|
发表于 2019-6-16 17:34:38
|
显示全部楼层
eric2013,您好!
这样用还不是完全非阻塞,至少要等待一个timeout的时间,才跳出while循环;我们经过改造,在接收中断增加一个定时几个字符时间,然后封装一个comGetBuf的函数,调用这个函数,可以做到完全非阻塞。
uint16_t comGetBuf(COM_PORT_E _ucPort, uint8_t *_ucaBuf, uint16_t _usLen)
{
TMR_E tmr_t;
uint16_t i;
uint8_t ucData;
if(_ucPort == COM1)
{
tmr_t = U1_TMR;
}
else if(_ucPort == COM2)
{
tmr_t = U2_TMR;
}
else if(_ucPort == COM3)
{
tmr_t = U3_TMR;
}
if(bsp_timer_check(tmr_t))
{
for(i=0; i<_usLen; i++)
{
if(comGetChar(_ucPort, &ucData))
{
_ucaBuf = ucData;
}
else
{
//清空数据
comClearRxFifo(_ucPort);
return i;
}
}
}
return 0;
}
static void UartIRQ(UART_T *_pUart)
{
TMR_E tmr_t;
/* 处理接收中断 */
if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)
{
/* 从串口接收数据寄存器读取数据存放到接收FIFO */
uint8_t ch;
ch = USART_ReceiveData(_pUart->uart);
_pUart->pRxBuf[_pUart->usRxWrite] = ch;
if (++_pUart->usRxWrite >= _pUart->usRxBufSize)
{
_pUart->usRxWrite = 0;
}
if (_pUart->usRxCount < _pUart->usRxBufSize)
{
_pUart->usRxCount++;
}
/* 回调函数,通知应用程序收到新数据,一般是发送1个消息或者设置一个标记 */
//if (_pUart->usRxWrite == _pUart->usRxRead)
//if (_pUart->usRxCount == 1)
{
if (_pUart->ReciveNew)
{
_pUart->ReciveNew(ch);
}
}
if(_pUart->uart == USART1)
{
tmr_t = U1_TMR;
}
else if(_pUart->uart == USART2)
{
tmr_t = U2_TMR;
}
else if(_pUart->uart == USART3)
{
tmr_t = U3_TMR;
}
bsp_timer_star_once(tmr_t, 30);
}
/* 处理发送缓冲区空中断 */
if (USART_GetITStatus(_pUart->uart, USART_IT_TXE) != RESET)
{
//if (_pUart->usTxRead == _pUart->usTxWrite)
if (_pUart->usTxCount == 0)
{
/* 发送缓冲区的数据已取完时, 禁止发送缓冲区空中断 (注意:此时最后1个数据还未真正发送完毕)*/
USART_ITConfig(_pUart->uart, USART_IT_TXE, DISABLE);
/* 使能数据发送完毕中断 */
USART_ITConfig(_pUart->uart, USART_IT_TC, ENABLE);
}
else
{
/* 从发送FIFO取1个字节写入串口发送数据寄存器 */
USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
if (++_pUart->usTxRead >= _pUart->usTxBufSize)
{
_pUart->usTxRead = 0;
}
_pUart->usTxCount--;
}
}
/* 数据bit位全部发送完毕的中断 */
else if (USART_GetITStatus(_pUart->uart, USART_IT_TC) != RESET)
{
//if (_pUart->usTxRead == _pUart->usTxWrite)
if (_pUart->usTxCount == 0)
{
/* 如果发送FIFO的数据全部发送完毕,禁止数据发送完毕中断 */
USART_ITConfig(_pUart->uart, USART_IT_TC, DISABLE);
/* 回调函数, 一般用来处理RS485通信,将RS485芯片设置为接收模式,避免抢占总线 */
if (_pUart->SendOver)
{
_pUart->SendOver();
}
}
else
{
/* 正常情况下,不会进入此分支 */
/* 如果发送FIFO的数据还未完毕,则从发送FIFO取1个数据写入发送数据寄存器 */
USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
if (++_pUart->usTxRead >= _pUart->usTxBufSize)
{
_pUart->usTxRead = 0;
}
_pUart->usTxCount--;
}
}
} |
|