|
这是最新的官方发布版本的代码:
static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen)
{
uint16_t i;
for (i = 0; i < _usLen; i++)
{
/* 如果发送缓冲区已经满了,则等待缓冲区空 */
#if 0
/*
在调试GPRS例程时,下面的代码出现死机,while 死循环
原因: 发送第1个字节时 _pUart->usTxWrite = 1;_pUart->usTxRead = 0;
将导致while(1) 无法退出
*/
while (1)
{
uint16_t usRead;
DISABLE_INT();
usRead = _pUart->usTxRead;
ENABLE_INT();
if (++usRead >= _pUart->usTxBufSize)
{
usRead = 0;
}
if (usRead != _pUart->usTxWrite)
{
break;
}
}
#else
/* 当 _pUart->usTxBufSize == 1 时, 下面的函数会死掉(待完善) */
while (1)
{
__IO uint16_t usCount;
DISABLE_INT();
usCount = _pUart->usTxCount;
ENABLE_INT();
if (usCount < _pUart->usTxBufSize)
{
break;
}
}
#endif
/* 将新数据填入发送缓冲区 */
_pUart->pTxBuf[_pUart->usTxWrite] = _ucaBuf;
DISABLE_INT();
if (++_pUart->usTxWrite >= _pUart->usTxBufSize)
{
_pUart->usTxWrite = 0;
}
_pUart->usTxCount++;
ENABLE_INT();
}
USART_ITConfig(_pUart->uart, USART_IT_TXE, ENABLE);
}
注释提示: /* 当 _pUart->usTxBufSize == 1 时, 下面的函数会死掉(待完善) */,起始这里不止_pUart->usTxBufSize=1时会出现,只要第一次填入串口fifo中的数据长度等于或大于发送buf的
大小时,都会出现以上是循环的问题。
我们注意到串口发送中断使能位是在这段代码的最后才被使能的,也就是必须等到所有数据都填充完后才开始中断的自动发送,当第一次填入的数据大于或等于RxBufSize时,这个时候中断发送是无法开启的,导致数据阻塞在FIFO中,于是就出现死循环中无法跳出的尴尬。
个人觉得可以这样改:
if (usCount < _pUart->usTxBufSize)
{
break;
}
else if(usCount == _pUart->usTxBufSize)//数据已填满缓冲区
{
if(!(_pUart->uart->CR1&(1<<7)))
USART_ITConfig(_pUart->uart, USART_IT_TXE, ENABLE);
} |
评分
-
查看全部评分
|