我在做单片机接收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[11]; // 接收到的数据
-
-
- // 串口1接受数据
- void Uart1Recv_isr() interrupt 4 {
- if(RI) {
- RI = 0;
- // 从SBUF读取数据
- recvBuf[cnt] = 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]; i++) {
- Uart1Send(msg[i]);
- }
- }
- }
- }
复制代码
|