我设置的是发送8个数字的串口 为什么第一次串口接收到的就是正确的 第二次以及之后串口接收到的数据末尾就会有乱码(见最后一张图)
下图为串口.c

下图为串口.h

之后几张图为包含串口的主要程序






这张图为出现的问题
我设置的是发送8个数字的串口 为什么第一次串口接收到的就是正确的 第二次以及之后串口接收到的数据末尾就会有乱码(见最后一张图)
下图为串口.c








这张图为出现的问题
下午好🌅🌅🌅
本答案参考通义千问
根据你描述的问题,“第一次串口接收到的数据是正确的,但第二次及之后的接收数据末尾出现乱码”,这通常与以下几种原因有关:
缓冲区未清空或未正确管理
uart_rx_buffer),在每次接收后没有清空缓冲区,可能会导致后续接收时残留旧数据,造成乱码。接收中断触发条件不准确
RI)被误触发,导致接收数据不完整或重复。发送与接收操作冲突
波特率设置错误
串口初始化配置问题
SCON、PCON、TCON 等寄存器设置不当,也可能导致数据接收异常。在每次接收完成后,将接收缓冲区清空,防止旧数据干扰新数据。
// 示例代码:在接收完成后的处理函数中
void Uart_Rx_Handler(void) {
if (RI == 1) {
RI = 0; // 清除接收标志位
uart_rx_buffer[uart_rx_index] = SBUF; // 接收一个字节
uart_rx_index++;
if (uart_rx_index >= UART_BUFFER_SIZE) {
uart_rx_index = 0; // 防止越界
}
}
}
注意: 如果你使用的是固定长度的接收(比如8个数字),应提前设定好接收长度,并在达到长度后重置索引。
确保只在接收完成时才触发一次中断,避免因误触发导致数据错乱。
// 在接收中断服务程序中,添加判断逻辑
if (RI == 1) {
RI = 0;
// 处理接收逻辑
}
如果你在发送数据后立即接收,可能会有缓存数据未被清除,导致接收乱码。
// 发送数据前清空接收缓冲区
uart_rx_index = 0;
for (int i = 0; i < UART_BUFFER_SIZE; i++) {
uart_rx_buffer[i] = 0;
}
确保单片机和上位机的波特率一致,否则会出现数据丢失或乱码。
// 例如:115200 波特率
TMOD = 0x20; // 定时器1模式2
TH1 = 0xFD; // 设置为115200波特率
TL1 = 0xFD;
TR1 = 1; // 启动定时器1
确保 SCON 和 PCON 配置正确,特别是 SM0 和 SM1 的设置。
SCON = 0x50; // 8位异步串行模式,允许接收
PCON = 0x00; // 默认设置
uart.c 中有如下结构)unsigned char uart_rx_buffer[8];
unsigned char uart_rx_index = 0;
void UART_Init(void) {
SCON = 0x50; // 8位异步模式
TMOD = 0x20;
TH1 = 0xFD;
TL1 = 0xFD;
TR1 = 1;
EA = 1;
ES = 1;
}
void UART_ISR(void) interrupt 4 {
if (RI == 1) {
RI = 0;
uart_rx_buffer[uart_rx_index++] = SBUF;
}
}
#define UART_BUFFER_SIZE 8
unsigned char uart_rx_buffer[UART_BUFFER_SIZE];
unsigned char uart_rx_index = 0;
void UART_Init(void) {
SCON = 0x50; // 8位异步模式
TMOD = 0x20;
TH1 = 0xFD; // 115200 baud rate
TL1 = 0xFD;
TR1 = 1;
EA = 1;
ES = 1;
}
void UART_ISR(void) interrupt 4 {
if (RI == 1) {
RI = 0;
uart_rx_buffer[uart_rx_index++] = SBUF;
if (uart_rx_index >= UART_BUFFER_SIZE) {
uart_rx_index = 0; // 重置索引
// 可以在这里触发接收完成标志
}
}
}
重点总结:
请根据上述建议逐一排查,如果能提供具体的代码片段(如 uart.c 和 uart.h),我可以进一步帮你定位问题。