找回密码
 立即注册
查看: 64|回复: 4

[求助] 8H 串口2只能发送数据接收不了,请问下是啥原因啊谢谢

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-08-03 10:11:17
已绑定手机

1

主题

2

回帖

19

积分

新手上路

积分
19
发表于 4 天前 | 显示全部楼层 |阅读模式
我通过点亮P12来判断从机是否接收到数据
通过串口接收的数据来判断是否数据是从哪个判断中触发的
但是串口2不工作,不知道怎么处理了,新手小白,感谢各位
  1. #include <STC8H.H>
  2. // 全局变量:定义一个环形缓冲区
  3. #define BUFFER_SIZE 20  // 缓冲区大小,根据需要调整
  4. unsigned char rx_buffer[BUFFER_SIZE];  // 接收缓冲区数组
  5. unsigned char rx_in = 0;  // 写入指针
  6. unsigned char rx_out = 0; // 读取指针
  7. unsigned char rx_count = 0;  // 当前缓冲区中数据的数量
  8. unsigned char rx_buffer2[BUFFER_SIZE];  // 接收缓冲区数组
  9. unsigned char rx_in2 = 0;  // 写入指针
  10. unsigned char rx_out2 = 0; // 读取指针
  11. unsigned char rx_count2 = 0;  // 当前缓冲区中数据的数量
  12. void Uart1_Init(void)
  13. {
  14.         SCON = 0x50;                //8位数据,可变波特率
  15.         AUXR |= 0x40;                //定时器时钟1T模式
  16.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  17.         TMOD &= 0x0F;                //设置定时器模式
  18.         TL1 = 0xE0;                        //设置定时初始值
  19.         TH1 = 0xFE;                        //设置定时初始值
  20.         ET1 = 0;                        //禁止定时器中断
  21.         TR1 = 1;                        //定时器1开始计时
  22.         EA=1;                                        //总中断控制
  23.         ES = 1;                                //使能串口1中断
  24. }
  25. void Uart2_Init(void)
  26. {
  27.         S2CON = 0x50;                //8位数据,可变波特率
  28.         AUXR |= 0x04;                //定时器时钟1T模式
  29.         //9600频率
  30.         T2L = 0xE0;                        //设置定时初始值
  31.         T2H = 0xFE;                        //设置定时初始值
  32.         AUXR |= 0x10;                //定时器2开始计时
  33.         IE2 |= 0x01;                //使能串口2中断
  34. }
  35. void Delay10ms(void)        //@11.0592MHz
  36. {
  37.         unsigned char data i, j;
  38.         i = 108;
  39.         j = 145;
  40.         do
  41.         {
  42.                 while (--j);
  43.         } while (--i);
  44. }
  45. void Delay1000ms(void)        //@11.0592MHz
  46. {
  47.         unsigned char data i, j, k;
  48.         i = 57;
  49.         j = 27;
  50.         k = 112;
  51.         do
  52.         {
  53.                 do
  54.                 {
  55.                         while (--k);
  56.                 } while (--j);
  57.         } while (--i);
  58. }
  59. void UART1_Isr() interrupt 4
  60. {
  61.     unsigned char received_byte;
  62.                 if(RI)
  63.                 {
  64.                         RI = 0;
  65.                         received_byte  = SBUF;
  66.        if (rx_count < BUFFER_SIZE)
  67.         {
  68.             rx_buffer[rx_in] = received_byte;  // 写入数据
  69.             rx_in = (rx_in + 1) % BUFFER_SIZE;  // 更新写入指针
  70.             rx_count++;  // 增加计数
  71.         }
  72.                 }
  73.                
  74. }
  75. void UART2_Isr() interrupt 8
  76. {
  77.         unsigned char received_byte2;
  78.         if(S2CON & 0x01){
  79.                 S2CON &= ~0x01;
  80.                 received_byte2  = S2BUF;
  81.          if (rx_count2 < BUFFER_SIZE)
  82.                 {
  83.                                 rx_buffer2[rx_in2] = received_byte2;  // 写入数据
  84.                                 rx_in2 = (rx_in2 + 1) % BUFFER_SIZE;  // 更新写入指针
  85.                                 rx_count2++;  // 增加计数
  86.                 }
  87.         }
  88. }
  89. void main() {
  90.   Uart1_Init();
  91.         Uart2_Init();
  92.         
  93.         P1M0 = 0x00;
  94.   P1M1 = 0x00;
  95.         
  96.          while(1)  // 无限循环
  97.     {
  98.         if (rx_count > 0)  // 如果缓冲区中有数据
  99.         {
  100.               //TI = 0;  // 清除发送中断标志(如果需要)
  101.                                         SBUF = 4;
  102.                                         //SBUF = rx_buffer[rx_out];  // 从缓冲区取出数据发送
  103.                                         S2BUF = rx_buffer[rx_out];
  104.                                         rx_out = (rx_out + 1) % BUFFER_SIZE;  // 更新读取指针
  105.                                         rx_count--;  // 减少计数
  106.                                         //P12 =1;
  107.                                         //Delay10ms();
  108.         }else if(rx_count2 > 0){
  109.                                         SBUF = 5;
  110.                                         //SBUF = rx_buffer2[rx_out2];
  111.                                         rx_out2 = (rx_out2 + 1) % BUFFER_SIZE;
  112.                                         rx_count2--;
  113.                                         P12 =1;
  114.                                         Delay10ms();
  115.                                 }
  116.                                 else{
  117.                                                 P12 =0;
  118.                                 }
  119.     }
  120. }
复制代码


回复

使用道具 举报 送花

3

主题

2092

回帖

1032

积分

等待验证会员

积分
1032
发表于 4 天前 | 显示全部楼层
[回复]  
您好,感谢您的提问。关于您在使用STC8H系列单片机时遇到的“串口2只能发送数据,无法接收”的问题,以下是一些可能的原因及排查建议,供您参考。

一、硬件连接问题  
1. 检查串口2的引脚配置:确保P3.4(RXD2)和P3.5(TXD2)引脚已正确连接至外部设备,并且未被其他功能占用。某些型号的STC8H支持多路复用功能,需确认是否配置为UART模式。  
2. 电平匹配与通信协议:确认通信双方的电平标准一致(如TTL/RS232),并确保波特率、数据位、停止位、校验位等参数设置一致。  
3. 线路故障或干扰:检查串口线是否接触良好,是否存在短路或断路;若使用长距离传输,考虑添加终端电阻或使用隔离器。

二、软件配置问题  
1. 串口初始化不完整:您提供的代码中仅展示了Uart1Init函数,而串口2的初始化未见相关代码。请检查是否对串口2进行了正确的寄存器配置。例如:  
SCON2:用于配置串口2的工作模式和中断使能。  
PCON:设置波特率倍增位(SMOD2)。  
AUXR:确定串口2使用的定时器源(如T0或T1)。  
定时器初值计算是否正确,特别是当使用自定义波特率时。  

2. 中断使能未开启:若您使用中断方式接收数据,请确保EA(全局中断使能)、ES2(串口2中断使能)已置1。  
3. 环形缓冲区逻辑错误:检查rxbuffer2、rxin2、rxout2等变量是否在接收中断中被正确更新,避免因指针越界或覆盖导致数据丢失。  
4. 接收标志位未清除:部分型号的STC8H在接收到数据后需要手动清除RI2标志位,否则可能影响后续接收。

三、调试建议  
1. 使用示波器或逻辑分析仪:观察串口2的TXD2和RXD2引脚波形,确认发送端是否有信号输出,接收端是否接收到有效数据。  
2. 简化测试流程:尝试仅使用串口2进行简单收发测试,排除其他外设干扰。例如:  
使用printf或直接发送字符,验证串口2能否正常工作。  
在接收中断中添加LED闪烁或延时,判断中断是否被触发。  
3. 查阅数据手册:参考STC8H系列单片机的数据手册,确认串口2的寄存器配置方法及注意事项。

四、示例代码片段(仅供参考)  
  1. c
  2. void Uart2Init(void) {
  3.     SCON2 = 0x50;        // 8位数据,可变波特率
  4.     AUXR |= 0x20;        // 选择定时器0作为串口2的波特率发生器
  5.     PCON &= 0x7F;        // SMOD2=0,普通波特率
  6.     TL2 = 0xE0;          // 设置定时器初始值(根据实际波特率调整)
  7.     TH2 = 0xFE;
  8.     ET2 = 1;             // 使能串口2中断
  9.     EA = 1;              // 全局中断使能
  10.     TR2 = 1;             // 启动定时器2
  11. }
  12. void UART2ISR(void) interrupt 16 {
  13.     if (RI2) {           // 接收中断
  14.         rxbuffer2[rxin2++] = SBUF2;
  15.         if (rxin2 >= BUFFERSIZE) rxin2 = 0;
  16.         RI2 = 0;         // 清除接收标志位
  17.     }
  18. }
复制代码

五、总结  
串口2无法接收数据通常由硬件连接、配置错误或中断处理不当引起。建议从基础步骤逐一排查,结合示波器等工具辅助调试。若您能提供更多代码细节或硬件连接信息,可进一步定位问题。希望以上内容对您有所帮助,祝您开发顺利!

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

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2025-08-03 10:11:17
已绑定手机

1

主题

2

回帖

19

积分

新手上路

积分
19
发表于 4 天前 | 显示全部楼层
国芯人*** 发表于 2025-8-3 10:23
[回复]  
您好,感谢您的提问。关于您在使用STC8H系列单片机时遇到的“串口2只能发送数据,无法接收”的问 ...

按人工智能回复解决不了问题....
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:259
  • 最近打卡:2025-08-06 00:10:02
已绑定手机

78

主题

2819

回帖

5821

积分

荣誉版主

无情的代码机器

积分
5821
发表于 3 天前 | 显示全部楼层
SBUF发送,一是要在中断里清TI标识位,二是下次一次发送要等上一次发送结束
main第一行开EAXFR
【新提醒】新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读! - 老鸟反刍/吐槽,新手乐园,毕业设计 国芯人工智能技术交流网站 - AI32位8051交流社区
  1. #include <STC8H.H>
  2. // 全局变量:定义一个环形缓冲区
  3. #define BUFFER_SIZE 20  // 缓冲区大小,根据需要调整
  4. unsigned char rx_buffer[BUFFER_SIZE];  // 接收缓冲区数组
  5. unsigned char rx_in = 0;  // 写入指针
  6. unsigned char rx_out = 0; // 读取指针
  7. unsigned char rx_count = 0;  // 当前缓冲区中数据的数量
  8. unsigned char rx_buffer2[BUFFER_SIZE];  // 接收缓冲区数组
  9. unsigned char rx_in2 = 0;  // 写入指针
  10. unsigned char rx_out2 = 0; // 读取指针
  11. unsigned char rx_count2 = 0;  // 当前缓冲区中数据的数量
  12. void Uart1_Init(void)
  13. {
  14.         SCON = 0x50;                //8位数据,可变波特率
  15.         AUXR |= 0x40;                //定时器时钟1T模式
  16.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  17.         TMOD &= 0x0F;                //设置定时器模式
  18.         TL1 = 0xE0;                        //设置定时初始值
  19.         TH1 = 0xFE;                        //设置定时初始值
  20.         ET1 = 0;                        //禁止定时器中断
  21.         TR1 = 1;                        //定时器1开始计时
  22.         EA=1;                                        //总中断控制
  23.         ES = 1;                                //使能串口1中断
  24. }
  25. void Uart2_Init(void)
  26. {
  27.         S2CON = 0x50;                //8位数据,可变波特率
  28.         AUXR |= 0x04;                //定时器时钟1T模式
  29.         //9600频率
  30.         T2L = 0xE0;                        //设置定时初始值
  31.         T2H = 0xFE;                        //设置定时初始值
  32.         AUXR |= 0x10;                //定时器2开始计时
  33.         IE2 |= 0x01;                //使能串口2中断
  34. }
  35. void Delay10ms(void)        //@11.0592MHz
  36. {
  37.         unsigned char data i, j;
  38.         i = 108;
  39.         j = 145;
  40.         do
  41.         {
  42.                 while (--j);
  43.         } while (--i);
  44. }
  45. void Delay1000ms(void)        //@11.0592MHz
  46. {
  47.         unsigned char data i, j, k;
  48.         i = 57;
  49.         j = 27;
  50.         k = 112;
  51.         do
  52.         {
  53.                 do
  54.                 {
  55.                         while (--k);
  56.                 } while (--j);
  57.         } while (--i);
  58. }
  59. void UART1_Isr() interrupt 4
  60. {
  61.     unsigned char received_byte;
  62.         if(TI){
  63.                 TI = 0;
  64.         }
  65.                 if(RI)
  66.                 {
  67.                         RI = 0;
  68.                         received_byte  = SBUF;
  69.        if (rx_count < BUFFER_SIZE)
  70.         {
  71.             rx_buffer[rx_in] = received_byte;  // 写入数据
  72.             rx_in = (rx_in + 1) % BUFFER_SIZE;  // 更新写入指针
  73.             rx_count++;  // 增加计数
  74.         }
  75.                 }
  76.                
  77. }
  78. void UART2_Isr() interrupt 8
  79. {
  80.         unsigned char received_byte2;
  81.         if(S2CON & 0x01){
  82.                 S2CON &= ~0x01;
  83.                 received_byte2  = S2BUF;
  84.          if (rx_count2 < BUFFER_SIZE)
  85.                 {
  86.                                 rx_buffer2[rx_in2] = received_byte2;  // 写入数据
  87.                                 rx_in2 = (rx_in2 + 1) % BUFFER_SIZE;  // 更新写入指针
  88.                                 rx_count2++;  // 增加计数
  89.                 }
  90.         }
  91.                                         if (S2CON & 0x02)        //检测串口2发送中断
  92.         {
  93.                 S2CON &= ~0x02;        //清除串口2发送中断请求位
  94.         }
  95.                                
  96. }
  97. void main() {
  98.         P_SW2 |= 0x80;
  99.   Uart1_Init();
  100.         Uart2_Init();
  101.         
  102.         P1M0 = 0x00;
  103.   P1M1 = 0x00;
  104.         TI = 0;
  105.          while(1)  // 无限循环
  106.     {
  107.         if (rx_count > 0)  // 如果缓冲区中有数据
  108.         {
  109.               //TI = 0;  // 清除发送中断标志(如果需要)
  110.                                         while(TI);SBUF = 4;
  111.                                         //SBUF = rx_buffer[rx_out];  // 从缓冲区取出数据发送
  112.                                         S2BUF = rx_buffer[rx_out];
  113.                                         rx_out = (rx_out + 1) % BUFFER_SIZE;  // 更新读取指针
  114.                                         rx_count--;  // 减少计数
  115.                                         //P12 =1;
  116.                                         //Delay10ms();
  117.         }else if(rx_count2 > 0){
  118.                                         while(TI);SBUF = 5;
  119.                                         //SBUF = rx_buffer2[rx_out2];
  120.                                         rx_out2 = (rx_out2 +1) % BUFFER_SIZE;
  121.                                         rx_count2--;
  122.                                         P12 =1;
  123.                                         Delay10ms();
  124.                                 }
  125.                                 else{
  126.                                                 P12 =0;
  127.                                 }
  128.     }
  129. }
复制代码


点评

大佬就是大佬,直接跑通,感谢了哈 嘻嘻  发表于 3 天前
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-8-7 05:31 , Processed in 0.114847 second(s), 63 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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