21ic问答首页 - LKS07x使用串口通信接受中断问题
LKS07x使用串口通信接受中断问题
我在使用串口接受中断接受串口信号时,用示波器验证过,只要一个帧的字节之间间隔小于100ms,数据帧的字节就会丢失,比如接受4个字节的帧,只要字节之间发送间隔小于100ms,接受中断UART_IF_RcvOver就只会触发一次,而不是4次,而只要间隔大于100ms,就能成功。之后使用UART_IF_RX_OV接受缓冲区溢出中断标志位验证过,确实间隔小于100ms,缓冲区溢出。有什么能解决这个串口间隔时间这么长的方法吗?

问答
赞0
好奇一下,串口通信一般会有什么问题?
评论
2026-04-29
赞0
找到原因了,不是程序的问题,是电路问题
评论
2026-04-29
赞0
程序里只留下串口处理那块程序后,这么测试过也是一样的?
你修改一下试试:
就是中断里只通过UART_ReadData接收数据,其他代码不要放到中断里面。
评论
2026-04-29
赞0
程序主体是水泵控制,主要是foc算法,我不太好发,
中断处理程序可以发你看看
uint8_t rx_data=0;
void UART1_IRQHandler(void)
{
if(UART_GetIRQFlag(UART1,UART_IF_SendOver))
{
UART_ClearIRQFlag(UART1,UART_IF_SendOver);
if(uart_ctx.tx_head == uart_ctx.tx_tail) {
uart_ctx.tx_busy = 0;
}
uart_ctx.bus_state=BUS_STATE_IDLE;
}
if(UART_GetIRQFlag(UART1,UART_IF_SendBufEmpty))
{
UART_ClearIRQFlag(UART1,UART_IF_SendBufEmpty);
// uart_ctx.bus_state=BUS_STATE_SENDING;
if(uart_ctx.tx_head != uart_ctx.tx_tail) {
// 发送下一个字节
UART_SendData(UART1, uart_ctx.tx_buffer[uart_ctx.tx_head]);
uart_ctx.tx_head = (uart_ctx.tx_head + 1) % TX_BUFFER_SIZE;
}
else {
// 缓冲区空,停止发送中断
uart_ctx.tx_busy = 0;
uart_ctx.bus_state = BUS_STATE_IDLE;
}
}
// if(UART_GetIRQFlag(UART1,UART_IF_RX_OV))
// {
// UART_ClearIRQFlag(UART1,UART_IF_RX_OV);
// value=1;
//// UART_ReadData(UART1);
// }
while(UART_GetIRQFlag(UART1,UART_IF_RcvOver))
{
UART_ClearIRQFlag(UART1,UART_IF_RcvOver);
uart1_rx_count++;
rx_data = (uint8_t)UART_ReadData(UART1);
if(uart_ctx.bus_state==BUS_STATE_SENDING) {
continue;
}
switch (uart_ctx.rx_state) {
case STATE_IDLE:
if (rx_data == FRAME_HEADER) {
uart_ctx.rx_state = STATE_CMD;
uart_ctx.rx_frame_len = 0;
uart_ctx.checksum = rx_data;
uart_ctx.rx_frame[uart_ctx.rx_frame_len++] = rx_data;
uart_ctx.bus_state=BUS_STATE_RECEIVING;
get_byte=0x01;
}
break;
case STATE_CMD:
uart_ctx.rx_state = STATE_LEN;
uart_ctx.checksum += rx_data;
uart_ctx.rx_frame[uart_ctx.rx_frame_len++] = rx_data;
get_byte=0x02;
break;
case STATE_LEN:
uart_ctx.expected_len = rx_data;
uart_ctx.checksum += rx_data;
uart_ctx.rx_frame[uart_ctx.rx_frame_len++] = rx_data;
get_byte=0x03;
// value=rx_data;
// if (uart_ctx.expected_len == 0) {
// uart_ctx.rx_state = STATE_CHECKSUM;
// } else {
// uart_ctx.rx_state = STATE_DATA;
// }
// break;
if (rx_data==0xBB) {
uart_ctx.rx_state = STATE_CHECKSUM;
} else {
uart_ctx.rx_state = STATE_DATA;
}
break;
case STATE_DATA:
uart_ctx.checksum += rx_data;
uart_ctx.rx_frame[uart_ctx.rx_frame_len++] = rx_data;
if (uart_ctx.rx_frame_len >= (3 + uart_ctx.expected_len)) {
uart_ctx.rx_state = STATE_CHECKSUM;
}
break;
case STATE_CHECKSUM:
if (uart_ctx.checksum == rx_data) {
// 校验通过,处理完整帧
uart_ctx.rx_frame[uart_ctx.rx_frame_len++] = rx_data;
get_byte=0x04;
// 复制到命令缓冲区(避免在中断中处理复杂逻辑)
memcpy(uart_ctx.cmd_buffer, (const void *)uart_ctx.rx_frame, uart_ctx.rx_frame_len);
uart_ctx.cmd_len = uart_ctx.rx_frame_len;
uart_ctx.cmd_pending = 1;
}
uart_ctx.rx_state = STATE_IDLE;
uart_ctx.rx_frame_len = 0;
break;
}
// 接收完成后,如果状态机回到空闲,标记总线空闲
if (uart_ctx.rx_state == STATE_IDLE) {
uart_ctx.bus_state = BUS_STATE_IDLE;
}
}
}
评论
2026-04-29
赞0
程序里目前只有串口处理这块程序吗?可以把代码发来看看
评论
2026-04-29
赞0
9600
评论
2026-04-29
赞0
评论
2026-04-29
您需要登录后才可以回复 登录 | 注册