21ic问答首页 - APM32F107串口中断接收丢包
APM32F107串口中断接收丢包
APM32F107在串口同时发送和接收的情况下串口接收丢字节,具体表现为偶发进入串口接收中断了,但是USART_FLAG_RXBNE标志位没有触发,导致读不到这个字节进而丢字节,通过计数发现进入中断的次数与实际应该收到的字节数一致。1、发送是阻塞式发送的,没有用发送中断,排除进入的是发送中断的可能。
2、出现这种情况时打断点看了,其他的溢出及错误标志位并没有置位,也打印检查了,没有置位。
3、排查代码了没有在其他地方主动调用USART_RxDatad读取。
4、串口中断优先级已调至最高。
5、只接收不发送不会丢字节,挂一晚上都不丢,只要一发送接收就会丢。
发送代码:
void Uart1_Send(char buf)
{
uint16_t data_9th = buf;
dog_feed_count_clean(); // 循环清除喂狗变量,超过DOG_PROTECT_TIME_100MS不清除则认为主循环异常,并停止喂狗。
if (g_rParameters.sPort[0].ucParity == UART_CHK_MARK)
{
data_9th |= (1 << (uart1_data_bit - 1));
}
else if (g_rParameters.sPort[0].ucParity == UART_CHK_SPACE)
{
data_9th &= ~(1 << (uart1_data_bit - 1));
}
WAIT_TX_EMPTY; // wait data register empty//等待发送完
USART_TxData(USART1, data_9th);
}
接收中断:
void USART1_IRQHandler(void)
{
uint8_t data;
uint8_t longth = g_sParameters.sPort[0].ucDataSize;
if (USART_ReadStatusFlag(USART1, USART_FLAG_OVRE) == SET)
{
// 由软件清0,先读取USART_STS寄存器,再读USART_DATA寄存器完成清0。
USART_RxData(USART1);
}
if (USART_ReadStatusFlag(USART1, USART_FLAG_RXBNE) == SET)
{
data = (uint8_t)USART_RxData(USART1); // fetch recv data from buffer
if (g_sParameters.sPort[0].ucParity != UART_CHK_NONE)
{
data = data & (~(1 << longth)); // 去掉校验位
}
if (AtCmd_enter_mode(0, data) == 1)
{
packet_count = 0;
}
else
{
packet_count = 0;
uart1_rx_ringbuf_push(&uart1_rx_ringbuf, data);
// uart_rec_len ++;
}
usart_recv_total_len++;
}
timer_pack_reset_func();
}
2、出现这种情况时打断点看了,其他的溢出及错误标志位并没有置位,也打印检查了,没有置位。
3、排查代码了没有在其他地方主动调用USART_RxDatad读取。
4、串口中断优先级已调至最高。
5、只接收不发送不会丢字节,挂一晚上都不丢,只要一发送接收就会丢。
发送代码:
void Uart1_Send(char buf)
{
uint16_t data_9th = buf;
dog_feed_count_clean(); // 循环清除喂狗变量,超过DOG_PROTECT_TIME_100MS不清除则认为主循环异常,并停止喂狗。
if (g_rParameters.sPort[0].ucParity == UART_CHK_MARK)
{
data_9th |= (1 << (uart1_data_bit - 1));
}
else if (g_rParameters.sPort[0].ucParity == UART_CHK_SPACE)
{
data_9th &= ~(1 << (uart1_data_bit - 1));
}
WAIT_TX_EMPTY; // wait data register empty//等待发送完
USART_TxData(USART1, data_9th);
}
接收中断:
void USART1_IRQHandler(void)
{
uint8_t data;
uint8_t longth = g_sParameters.sPort[0].ucDataSize;
if (USART_ReadStatusFlag(USART1, USART_FLAG_OVRE) == SET)
{
// 由软件清0,先读取USART_STS寄存器,再读USART_DATA寄存器完成清0。
USART_RxData(USART1);
}
if (USART_ReadStatusFlag(USART1, USART_FLAG_RXBNE) == SET)
{
data = (uint8_t)USART_RxData(USART1); // fetch recv data from buffer
if (g_sParameters.sPort[0].ucParity != UART_CHK_NONE)
{
data = data & (~(1 << longth)); // 去掉校验位
}
if (AtCmd_enter_mode(0, data) == 1)
{
packet_count = 0;
}
else
{
packet_count = 0;
uart1_rx_ringbuf_push(&uart1_rx_ringbuf, data);
// uart_rec_len ++;
}
usart_recv_total_len++;
}
timer_pack_reset_func();
}
赞0
建议先排查两个方面:
评论
2025-04-24
赞0
评论
2025-04-24
赞0
评论
2025-04-24
赞0
你是极海的技术支持么?
评论
2025-04-24
赞0
F107的主频近百兆呢!处理一个kbps级别的通讯。
即使错误进入了串口接收中断了,只要没有读出 ,下次仍然会进入串口中断
评论
2025-04-24
您需要登录后才可以回复 登录 | 注册