针对您提供的代码及故障现象分析,程序存在以下几处关键问题需要修正:
一、串口中断服务函数缺陷
原中断服务函数存在数据丢失风险:- c
- void Uart1Isr(void) interrupt 4
- {
- if (TI) { TI = 0; } //清除发送中断
- if (RI) { RI = 0; } //清除接收中断但未读取数据
- }
复制代码
问题分析:
在检测到接收中断标志RI=1时,未从SBUF寄存器中读取数据,导致接收数据丢失。
修正方案: - c
- void Uart1Isr(void) interrupt 4
- {
- if (RI) {
- RI = 0;
- recDat[recnum++] = SBUF; //保存接收数据
- if (recnum >= 60) recnum = 0; //防止溢出
- }
- if (TI) { TI = 0; }
- }
复制代码
二、UART1初始化函数错误
1. 错误的数据寄存器访问
代码中误用S2BUF(UART2缓冲区):- c
- recDat[recnum++]=S2BUF; //错误:UART1应使用SBUF
复制代码
修正方案:
删除该行代码。初始化函数仅需配置硬件,不应主动读取数据。
2. 波特率计算验证
根据代码注释//9600bps@24000MHz,实际晶振频率可能为24.000MHz。
计算定时器1重载值:- TH1 = 256 - (Fosc / 12 / 16 / Baudrate)
- = 256 - (24,000,000 / 12 / 16 / 9600)
- ≈ 256 - 13.02 ≈ 243 (0xF3)
复制代码
当前配置TH1=0xFF会导致实际波特率偏低(约6250bps),建议修正为:- c
- TL1 = 0xF3; //修正波特率参数
- TH1 = 0xF3;
复制代码
三、全局中断未启用
代码中未开启全局中断使能位EA,导致中断无法触发。
补充初始化代码:- c
- void Uart1Init(void)
- {
- //原有配置代码...
- EA = 1; //开启全局中断
- }
复制代码
四、数据协议处理逻辑优化
当前数据处理条件if (recnum >= 6)缺乏协议完整性校验:
1. 陶晶驰串口屏通常采用帧结构(如:AA CMDLEN CMD ... CKSUM 0F 0F)
2. 建议增加帧头、长度、校验和等检测逻辑
改进示例:- c
- void usart1RunTask(void)
- {
- if (recnum >= 4) { //假设最小帧长4字节
- if (recDat[0] == 0xAA && recDat[recnum-2] == 0x0F && recDat[recnum-1] == 0x0F) {
- //校验通过后处理数据
- recnum = 0; //复位接收指针
- }
- }
- }
复制代码
五、硬件排查建议
1. 物理层验证
确认TXD(单片机)与RXD(屏幕)交叉连接
测量信号电平是否符合标准(3.3V/5V匹配)
使用示波器捕获波形,验证实际波特率
2. 陶晶驰配置检查
通过USART HMI工具确认控件事件是否绑定正确指令
检查屏幕工程中设置的波特率与代码是否一致
六、完整修正代码- c
- include "config.h"
- define UARTBUFLEN 60
- volatile U8 recDat[UARTBUFLEN];
- volatile U8 recnum = 0;
- void Uart1Isr(void) interrupt 4
- {
- if (RI) {
- RI = 0;
- recDat[recnum++] = SBUF;
- if (recnum >= UARTBUFLEN) recnum = 0; //循环缓冲
- }
- if (TI) TI = 0;
- }
- void Uart1Init(void) //9600bps@24.000MHz
- {
- PSW1 = (PSW1 & ~0xC0) | 0x40; //切换UART1到P3.0/P3.1
- SCON = 0x50; //8位数据+可变波特率
- AUXR &= ~0x40; //定时器1时钟12T模式
- TMOD &= 0x0F; //定时器1模式设置
- TL1 = 0xF3; //波特率重载值
- TH1 = 0xF3;
- TR1 = 1; //启动定时器1
- ES = 1; //使能串口中断
- EA = 1; //开启全局中断
- }
- void ProcessTouchEvent(void)
- {
- if (recnum >= 4) { //示例协议:AA CMD 0F 0F
- if (recDat[0]==0xAA && recDat[recnum-2]==0x0F && recDat[recnum-1]==0x0F) {
- //TODO: 触发对应操作
- SBUF = 0x01; //示例:通过串口发送响应
- while(!TI); //等待发送完成
- TI = 0;
- recnum = 0; //清空缓冲区
- }
- }
- }
复制代码
七、调试建议
1. 最小系统验证
通过短接单片机的TXD与RXD引脚,测试自发自收是否正常。
2. 指令监控
使用USB转TTL工具连接屏幕串口,通过PC端串口助手确认屏幕实际输出数据。
3. LED辅助调试
在中断服务函数中添加GPIO翻转代码,通过示波器观察中断触发频率。
以上修正可系统性解决通信异常问题。若仍存在故障,建议重点排查硬件链路阻抗匹配问题。
[本文内容由国芯人工智能辅助生成,仅供参考] |