找回密码
 立即注册
查看: 351|回复: 12

大老们帮忙看一下这个单片机串口屏程序是否正常 用的是陶晶驰的串口

[复制链接]
  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-06-27 17:47:07
已绑定手机

12

主题

65

回帖

342

积分

中级会员

积分
342
发表于 2025-5-9 17:40:24 | 显示全部楼层 |阅读模式
截图202505091738466559.jpg 现在的问题是点击屏幕 单片机没有输出   
  1. #include "config.h"
  2. #define U8 unsigned char
  3. U8 rec_Dat[60];
  4. U8 rec_num = 0;
  5. void Uart1_Isr(void) interrupt 4
  6. {
  7.         if (TI)                                //检测串口1发送中断
  8.         {
  9.                 TI = 0;                        //清除串口1发送中断请求位
  10.         }
  11.         if (RI)                                //检测串口1接收中断
  12.         {
  13.                 RI = 0;                        //清除串口1接收中断请求位
  14.         }
  15. }
  16. void Uart1_Init(void)        //9600bps@24.000MHz
  17. {
  18.     P_SW1 = (P_SW1 & ~0xc0) | 0x40;       
  19.         SCON = 0x50;                //8位数据,可变波特率
  20.         AUXR &= 0xBF;                //定时器时钟12T模式
  21.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  22.         TMOD &= 0x0F;                //设置定时器模式
  23.         TL1 = 0xCC;                        //设置定时初始值
  24.         TH1 = 0xFF;                        //设置定时初始值
  25.         ET1 = 0;                        //禁止定时器中断
  26.         TR1 = 1;                        //定时器1开始计时
  27.         ES = 1;                                //使能串口1中断
  28.         rec_Dat[rec_num++]=S2BUF;
  29.        
  30. }
  31. // 处理接收到的数据
  32. void usart1_RunTask(void)
  33. {
  34.     if (rec_num >= 6)
  35.     {
  36.         if ((rec_Dat[rec_num - 1] == '\n') && (rec_Dat[rec_num - 2] == '\r'))
  37.         {
  38.             if ((rec_Dat[rec_num - 3] == 'O') && (rec_Dat[rec_num - 4] == 'P') &&
  39.                 (rec_Dat[rec_num - 5] == 'E') && (rec_Dat[rec_num - 6] == 'N'))
  40.             {
  41.                 P20 = 0; // 设置P0的值
  42.             }
  43.         }
  44.         rec_num = 0; // 处理完数据后重置计数器
  45.     }
  46. }
复制代码


回复

使用道具 举报 送花

3

主题

524

回帖

-241

积分

等待验证会员

积分
-241
发表于 2025-5-9 17:43:00 | 显示全部楼层
针对您提供的代码及故障现象分析,程序存在以下几处关键问题需要修正:

一、串口中断服务函数缺陷
原中断服务函数存在数据丢失风险:
  1. c
  2. void Uart1Isr(void) interrupt 4
  3. {
  4.     if (TI) { TI = 0; }  //清除发送中断
  5.     if (RI) { RI = 0; }  //清除接收中断但未读取数据
  6. }
复制代码
问题分析:  
在检测到接收中断标志RI=1时,未从SBUF寄存器中读取数据,导致接收数据丢失。  
修正方案:  
  1. c
  2. void Uart1Isr(void) interrupt 4
  3. {
  4.     if (RI) {
  5.         RI = 0;
  6.         recDat[recnum++] = SBUF;  //保存接收数据
  7.         if (recnum >= 60) recnum = 0; //防止溢出
  8.     }
  9.     if (TI) { TI = 0; }
  10. }
复制代码

二、UART1初始化函数错误
1. 错误的数据寄存器访问
代码中误用S2BUF(UART2缓冲区):
  1. c
  2. recDat[recnum++]=S2BUF;  //错误:UART1应使用SBUF
复制代码
修正方案:  
删除该行代码。初始化函数仅需配置硬件,不应主动读取数据。

2. 波特率计算验证
根据代码注释//9600bps@24000MHz,实际晶振频率可能为24.000MHz。  
计算定时器1重载值:
  1. TH1 = 256 - (Fosc / 12 / 16 / Baudrate)
  2.      = 256 - (24,000,000 / 12 / 16 / 9600)
  3.      ≈ 256 - 13.02 ≈ 243 (0xF3)
复制代码
当前配置TH1=0xFF会导致实际波特率偏低(约6250bps),建议修正为:
  1. c
  2. TL1 = 0xF3;  //修正波特率参数
  3. TH1 = 0xF3;
复制代码

三、全局中断未启用
代码中未开启全局中断使能位EA,导致中断无法触发。  
补充初始化代码:
  1. c
  2. void Uart1Init(void)
  3. {
  4.     //原有配置代码...
  5.     EA = 1;  //开启全局中断
  6. }
复制代码

四、数据协议处理逻辑优化
当前数据处理条件if (recnum >= 6)缺乏协议完整性校验:  
1. 陶晶驰串口屏通常采用帧结构(如:AA CMDLEN CMD ... CKSUM 0F 0F)  
2. 建议增加帧头、长度、校验和等检测逻辑  
改进示例:
  1. c
  2. void usart1RunTask(void)
  3. {
  4.     if (recnum >= 4) {  //假设最小帧长4字节
  5.         if (recDat[0] == 0xAA && recDat[recnum-2] == 0x0F && recDat[recnum-1] == 0x0F) {
  6.             //校验通过后处理数据
  7.             recnum = 0;  //复位接收指针
  8.         }
  9.     }
  10. }
复制代码

五、硬件排查建议
1. 物理层验证  
确认TXD(单片机)与RXD(屏幕)交叉连接  
测量信号电平是否符合标准(3.3V/5V匹配)  
使用示波器捕获波形,验证实际波特率

2. 陶晶驰配置检查  
通过USART HMI工具确认控件事件是否绑定正确指令  
检查屏幕工程中设置的波特率与代码是否一致

六、完整修正代码
  1. c
  2. include "config.h"
  3. define UARTBUFLEN 60
  4. volatile U8 recDat[UARTBUFLEN];
  5. volatile U8 recnum = 0;
  6. void Uart1Isr(void) interrupt 4
  7. {
  8.     if (RI) {
  9.         RI = 0;
  10.         recDat[recnum++] = SBUF;
  11.         if (recnum >= UARTBUFLEN) recnum = 0; //循环缓冲
  12.     }
  13.     if (TI) TI = 0;
  14. }
  15. void Uart1Init(void) //9600bps@24.000MHz
  16. {
  17.     PSW1 = (PSW1 & ~0xC0) | 0x40; //切换UART1到P3.0/P3.1
  18.     SCON = 0x50;    //8位数据+可变波特率
  19.     AUXR &= ~0x40;  //定时器1时钟12T模式
  20.     TMOD &= 0x0F;   //定时器1模式设置
  21.     TL1 = 0xF3;     //波特率重载值
  22.     TH1 = 0xF3;
  23.     TR1 = 1;        //启动定时器1
  24.     ES = 1;         //使能串口中断
  25.     EA = 1;         //开启全局中断
  26. }
  27. void ProcessTouchEvent(void)
  28. {
  29.     if (recnum >= 4) { //示例协议:AA CMD 0F 0F
  30.         if (recDat[0]==0xAA && recDat[recnum-2]==0x0F && recDat[recnum-1]==0x0F) {
  31.             //TODO: 触发对应操作
  32.             SBUF = 0x01; //示例:通过串口发送响应
  33.             while(!TI);  //等待发送完成
  34.             TI = 0;
  35.             recnum = 0; //清空缓冲区
  36.         }
  37.     }
  38. }
复制代码

七、调试建议
1. 最小系统验证  
   通过短接单片机的TXD与RXD引脚,测试自发自收是否正常。

2. 指令监控  
   使用USB转TTL工具连接屏幕串口,通过PC端串口助手确认屏幕实际输出数据。

3. LED辅助调试  
   在中断服务函数中添加GPIO翻转代码,通过示波器观察中断触发频率。

以上修正可系统性解决通信异常问题。若仍存在故障,建议重点排查硬件链路阻抗匹配问题。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-06-27 17:47:07
已绑定手机

12

主题

65

回帖

342

积分

中级会员

积分
342
发表于 2025-5-9 18:33:27 | 显示全部楼层
还是不行 不知道哪里出了问题哦

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-06-27 17:47:07
已绑定手机

12

主题

65

回帖

342

积分

中级会员

积分
342
发表于 2025-5-9 19:23:24 | 显示全部楼层
小*** 发表于 2025-5-9 18:33
还是不行 不知道哪里出了问题哦

我接的是1.6  1.7
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:577
  • 最近打卡:2025-06-29 10:04:32
已绑定手机

50

主题

1821

回帖

3192

积分

论坛元老

积分
3192
发表于 2025-5-9 20:39:18 | 显示全部楼层
你可以先用串口助手和屏联调一下试试
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:221
  • 最近打卡:2025-06-29 14:47:56
已绑定手机

72

主题

2016

回帖

4544

积分

荣誉版主

无情的代码机器

积分
4544
发表于 2025-5-9 20:51:55 | 显示全部楼层
代码不完整,且中断里没什么读写操作。建议用例程先测试
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-06-27 17:47:07
已绑定手机

12

主题

65

回帖

342

积分

中级会员

积分
342
发表于 2025-5-9 22:15:51 | 显示全部楼层
截图202505092215076668.jpg 感觉不对劲啊 多了好多符号
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-06-27 17:47:07
已绑定手机

12

主题

65

回帖

342

积分

中级会员

积分
342
发表于 2025-5-10 20:21:20 | 显示全部楼层
erci*** 发表于 2025-5-9 20:51
代码不完整,且中断里没什么读写操作。建议用例程先测试
  1. #define BAUDRATE        (9600)
  2. #define T2_RELOAD       (65536 - (SYSCLK / BAUDRATE + 2) / 4)
  3.     UART1_SwitchP1617();                //设置串口数据端口: RxD (P1.6), TxD (P1.7)
  4.     UART1_Timer2BRT();                  //选择定时器2作为串口1波特率发生器
  5.     TIMER2_TimerMode();                 //设置定时器2为定时模式
  6.     TIMER2_1TMode();                    //设置定时器2为1T模式
  7.     TIMER2_SetPrescale(0);              //设置定时器2的8位预分频
  8.     TIMER2_SetReload16(T2_RELOAD);      //设置定时器2的16位重载值
  9.     TIMER2_Run();                       //定时器2开始运行
  10.     UART1_EnableRx();                   //使能串口1接收数据
  11.     UART1_Mode1();                      //设置串口1为模式1 (8位数据可变波特率)
  12.     UART1_SetIntPriority(0);        //设置中断为最低优先级
  13.          rec_num = 0;
  14.     UART1_EnableInt();                  //使能串口1中断
  15.     //<<AICUBE_USER_UART1_INITIAL_BEGIN>>
  16.     // 在此添加用户初始化代码
  17.     //<<AICUBE_USER_UART1_INITIAL_END>>
  18. }
  19. void usart1_RunTask(void)
  20. {
  21.         if(rec_num >= 6)
  22.         {
  23.         if((rec_Dat[rec_num - 1] == 0x01) && (rec_Dat[rec_num - 2] == 0x02))
  24.                 {
  25.                         if((rec_Dat[rec_num - 3] == 0x03) && (rec_Dat[rec_num - 4] == 0x04) && (rec_Dat[rec_num - 5] == 0x05) && (rec_Dat[rec_num - 6] == 0x06))
  26.             {
  27.                 P20 = 0; // 设置P0的值
  28.             }
  29.         }
  30.         rec_num = 0; // 处理完数据后重置计数器
  31.         }
  32. }
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-06-27 17:47:07
已绑定手机

12

主题

65

回帖

342

积分

中级会员

积分
342
发表于 2025-5-10 20:22:18 | 显示全部楼层

这样子能接受到串口数据吗
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-06-27 17:47:07
已绑定手机

12

主题

65

回帖

342

积分

中级会员

积分
342
发表于 2025-5-10 20:24:15 | 显示全部楼层
  1. void UART1_ISR(void) interrupt UART1_VECTOR
  2. {
  3.     //<<AICUBE_USER_UART1_ISR_CODE1_BEGIN>>
  4.     // 在此添加中断函数用户代码
  5.     if (UART1_CheckTxFlag())            //判断串口发送中断
  6.     {
  7.         UART1_ClearTxFlag();            //清除串口发送中断标志
  8.     }
  9.     if (UART1_CheckRxFlag())            //判断串口接收中断
  10.     {
  11.         UART1_ClearRxFlag();                 //清除串口接收中断标志
  12.     }
  13.                 rec_Dat[rec_num++] = SBUF;
  14.     //<<AICUBE_USER_UART1_ISR_CODE1_END>>
  15. }
复制代码

点评

收数据要放在Rx判断里 if (UART1_CheckRxFlag()) //判断串口接收中断 { } 可以看看冲哥的讲解 https://www.stcaimcu.com/forum.php?mod=viewthread&tid=11902  详情 回复 发表于 2025-5-10 20:26
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-29 18:26 , Processed in 0.146356 second(s), 99 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表