疑似bug: ISP "设置RTC"按键,会截断接收缓冲器的输出
我在做单片机接收RTC对时数据的功能,我原本想做的功能是,如果单片机接收到RTC对时数据(11个字节),就用串口发送一条消息,表示单片机对时成功。程序写好后,调试过程中,我发现,我一点"设置RTC"按钮,原本该正常打印的字符串,被截断了。串口助手只输出,字符串的前半部分。
发生频率大概是:我点10次"设置RTC"按钮,有大约2次的输出被截断了。
下面是输出截图:
我点了3次"设置RTC"按钮, 前两次的输出被截断了,第3次是正常的。
还有几个发现:
- 我用逻辑分析仪,抓串口输出的数据,发现输出的字符串是完整的,但是,串口助手的显示被截断了。
- 如果我用串口助手的发送功能,模拟发送11个字节,输出是完全正常的。
- 我用双串口的串口2接收,(串口1发送RTC数据,串口2接收),输出是完全正常的。
疑似是,“设置RTC”按钮的响应函数里面有bug,导致了输出的截断。
下面是测试代码,我用的单片机型号,是STC32G12K128,可复现。
#include "stc32g.h"
typedef unsigned char uint8_t;
typedef long int32_t;
// 串口1初始化
void Uart1Init() {
int32_t T2value;
SM0 = 0;
SM1 = 1; // 串口1: 8位可变波特率
REN = 1; // 允许串口1接收数据
TI = 0; // 清除中断标志位
RI = 0; // 清除中断标志位
// 定时器2设置
T2x12 = 1; // 0表示定时器2处于12T模式 ; 1表示定时器2处于1T模式
// T2 = 65536 - SYSclk / 4 / 波特率
T2value = (int32_t)(65536 - 12000000L / 4 / 115200);// MAIN_Fosc = 12MHz
T2L = T2value & 0xFF;
T2H = T2value >> 8;
T2R = 1; // 定时器2开始计数
ES = 1; // 允许串口1中断
}
uint8_t cnt = 0; // 接收到的数据个数
uint8_t recvBuf; // 接收到的数据
// 串口1接受数据
void Uart1Recv_isr() interrupt 4 {
if(RI) {
RI = 0;
// 从SBUF读取数据
recvBuf = SBUF;
cnt++;
}
}
// 串口1发送数据
void Uart1Send(uint8_t dat) {
SBUF = dat;
while(!TI);
TI = 0;
}
void main() {
uint8_t i;
char * msg = "RTC message: RTC set time finished! Congradulation!\n"; // 规律是,字符串越长,bug越容易出现
P54RST = 1;
EAXFR = 1; // 允许访问XFR存储区
CKCON = 0; // 访问外设等待时间
WTST = 0;// 每次读取FLASH存储区的等待时间
EA = 1;
Uart1Init();
while(1) {
// 每接收到11个数据,就发送成功消息
if(cnt >= 11) {
cnt = 0;
// 发送成功消息
for(i = 0; msg; i++) {
Uart1Send(msg);
}
}
}
}
这种情况一定要从自己的程序里找原因,串口只负责收或发一个字节,别的功能都是程序的事。 主循环里发送指令再改改:
for(i = 0; msg; i++) {
Uart1Send(msg);
}
例如改成:
for(i = 0; i<52; i++) {
Uart1Send(msg);
} 用这个插入代码,否则会显示不完整
乘风飞扬 发表于 2026-7-21 14:12
主循环里发送指令再改改:
哎呀 刚发现,刚才往论坛上贴代码的时候,复制错了。。。。
for(i = 0; msg; i++) {
Uart1Send(msg);
}
我用上面这段代码测试的,我点了设置RTC按钮,输出仍然是截断的。可是,逻辑分析仪,已经捕获了完整的字符串,但是,串口助手被截断了。 这段代码存在数组越界的可能,越界的后果可能会严重。
建议先限制cnt,再存入数组。如这样:u8 d;d=SBUF;if(cnt<11){recvBuf=d;cnt++;}
// 串口1接受数据
void Uart1Recv_isr() interrupt 4 {
if(RI) {
RI = 0;
// 从SBUF读取数据
recvBuf = SBUF;
cnt++;
}
}
lcwswust 发表于 2026-7-21 15:48
这段代码存在数组越界的可能,越界的后果可能会严重。
建议先限制cnt,再存入数组。如这样:u8 d;d=SBUF;if ...串口发送的是完整的字符串,已经被逻辑分析仪验证过了,说明问题不在程序。问题是,串口助手显示的是截断的。 1277120515 发表于 2026-7-21 16:13
串口发送的是完整的字符串,已经被逻辑分析仪验证过了,说明问题不在程序。问题是,串口助手显示的是截断的 ...
如果确定发送没问题,那问题可能出在USB转串口或串口助手,换一种USB转串口线(如CH340)、换一种串口助手(如sscom5.13.1.exe)试试。 lcwswust 发表于 2026-7-21 16:22
如果确定发送没问题,那问题可能出在USB转串口或串口助手,换一种USB转串口线(如CH340)、换一种串口助 ...
都试了。我用ISP的串口助手,直接发送11个字节的数据,没问题。换成CH340,发送11个字节的数据,也没有问题。但是,就是用RTC对时模块,实际上,也是发送了11个字节的数据,就有问题了。 所以, 问题就是出在RTC对时模块的"设置RTC"按钮上。
页:
[1]