tlxfif 发表于 2025-8-3 10:22:35

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

我通过点亮P12来判断从机是否接收到数据
通过串口接收的数据来判断是否数据是从哪个判断中触发的
但是串口2不工作,不知道怎么处理了,新手小白,感谢各位
#include <STC8H.H>


// 全局变量:定义一个环形缓冲区
#define BUFFER_SIZE 20// 缓冲区大小,根据需要调整
unsigned char rx_buffer;// 接收缓冲区数组
unsigned char rx_in = 0;// 写入指针
unsigned char rx_out = 0; // 读取指针
unsigned char rx_count = 0;// 当前缓冲区中数据的数量

unsigned char rx_buffer2;// 接收缓冲区数组
unsigned char rx_in2 = 0;// 写入指针
unsigned char rx_out2 = 0; // 读取指针
unsigned char rx_count2 = 0;// 当前缓冲区中数据的数量


void Uart1_Init(void)
{
      SCON = 0x50;                //8位数据,可变波特率
      AUXR |= 0x40;                //定时器时钟1T模式
      AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
      TMOD &= 0x0F;                //设置定时器模式
      TL1 = 0xE0;                        //设置定时初始值
      TH1 = 0xFE;                        //设置定时初始值
      ET1 = 0;                        //禁止定时器中断
      TR1 = 1;                        //定时器1开始计时
      EA=1;                                        //总中断控制
      ES = 1;                              //使能串口1中断

}

void Uart2_Init(void)
{
      S2CON = 0x50;                //8位数据,可变波特率
      AUXR |= 0x04;                //定时器时钟1T模式
      //9600频率
      T2L = 0xE0;                        //设置定时初始值
      T2H = 0xFE;                        //设置定时初始值
      AUXR |= 0x10;                //定时器2开始计时
      IE2 |= 0x01;                //使能串口2中断
}


void Delay10ms(void)      //@11.0592MHz
{
      unsigned char data i, j;

      i = 108;
      j = 145;
      do
      {
                while (--j);
      } while (--i);
}

void Delay1000ms(void)      //@11.0592MHz
{
      unsigned char data i, j, k;

      i = 57;
      j = 27;
      k = 112;
      do
      {
                do
                {
                        while (--k);
                } while (--j);
      } while (--i);
}


void UART1_Isr() interrupt 4
{
    unsigned char received_byte;

                if(RI)
                {
                        RI = 0;
                        received_byte= SBUF;
       if (rx_count < BUFFER_SIZE)
      {
            rx_buffer = received_byte;// 写入数据
            rx_in = (rx_in + 1) % BUFFER_SIZE;// 更新写入指针
            rx_count++;// 增加计数
      }
                }
               
}




void UART2_Isr() interrupt 8
{
      unsigned char received_byte2;
      if(S2CON & 0x01){
                S2CON &= ~0x01;
                received_byte2= S2BUF;
         if (rx_count2 < BUFFER_SIZE)
                {
                              rx_buffer2 = received_byte2;// 写入数据
                              rx_in2 = (rx_in2 + 1) % BUFFER_SIZE;// 更新写入指针
                              rx_count2++;// 增加计数
                }
      }
}


void main() {
Uart1_Init();
      Uart2_Init();
      
      P1M0 = 0x00;
P1M1 = 0x00;
      
         while(1)// 无限循环
    {
      if (rx_count > 0)// 如果缓冲区中有数据
      {
            //TI = 0;// 清除发送中断标志(如果需要)
                                        SBUF = 4;
                                        //SBUF = rx_buffer;// 从缓冲区取出数据发送
                                        S2BUF = rx_buffer;
                                        rx_out = (rx_out + 1) % BUFFER_SIZE;// 更新读取指针
                                        rx_count--;// 减少计数
                                        //P12 =1;
                                        //Delay10ms();
      }else if(rx_count2 > 0){
                                        SBUF = 5;
                                        //SBUF = rx_buffer2;
                                        rx_out2 = (rx_out2 + 1) % BUFFER_SIZE;
                                        rx_count2--;
                                        P12 =1;
                                        Delay10ms();
                              }
                              else{
                                                P12 =0;
                              }
    }
}


国芯人工智能 发表于 2025-8-3 10:23:00

[回复]
您好,感谢您的提问。关于您在使用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的寄存器配置方法及注意事项。

四、示例代码片段(仅供参考)
c
void Uart2Init(void) {
    SCON2 = 0x50;      // 8位数据,可变波特率
    AUXR |= 0x20;      // 选择定时器0作为串口2的波特率发生器
    PCON &= 0x7F;      // SMOD2=0,普通波特率
    TL2 = 0xE0;          // 设置定时器初始值(根据实际波特率调整)
    TH2 = 0xFE;
    ET2 = 1;             // 使能串口2中断
    EA = 1;            // 全局中断使能
    TR2 = 1;             // 启动定时器2
}

void UART2ISR(void) interrupt 16 {
    if (RI2) {         // 接收中断
      rxbuffer2 = SBUF2;
      if (rxin2 >= BUFFERSIZE) rxin2 = 0;
      RI2 = 0;         // 清除接收标志位
    }
}

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

[本文内容由国芯人工智能辅助生成,仅供参考]

tlxfif 发表于 2025-8-3 11:24:53

国芯人工智能 发表于 2025-8-3 10:23
[回复]
您好,感谢您的提问。关于您在使用STC8H系列单片机时遇到的“串口2只能发送数据,无法接收”的问 ...

按人工智能回复解决不了问题....

ercircle 发表于 2025-8-4 11:47:14

SBUF发送,一是要在中断里清TI标识位,二是下次一次发送要等上一次发送结束
main第一行开EAXFR
【新提醒】新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读!新手必读! - 老鸟反刍/吐槽,新手乐园,毕业设计 国芯人工智能技术交流网站 - AI32位8051交流社区
#include <STC8H.H>


// 全局变量:定义一个环形缓冲区
#define BUFFER_SIZE 20// 缓冲区大小,根据需要调整
unsigned char rx_buffer;// 接收缓冲区数组
unsigned char rx_in = 0;// 写入指针
unsigned char rx_out = 0; // 读取指针
unsigned char rx_count = 0;// 当前缓冲区中数据的数量

unsigned char rx_buffer2;// 接收缓冲区数组
unsigned char rx_in2 = 0;// 写入指针
unsigned char rx_out2 = 0; // 读取指针
unsigned char rx_count2 = 0;// 当前缓冲区中数据的数量


void Uart1_Init(void)
{
      SCON = 0x50;                //8位数据,可变波特率
      AUXR |= 0x40;                //定时器时钟1T模式
      AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
      TMOD &= 0x0F;                //设置定时器模式
      TL1 = 0xE0;                        //设置定时初始值
      TH1 = 0xFE;                        //设置定时初始值
      ET1 = 0;                        //禁止定时器中断
      TR1 = 1;                        //定时器1开始计时
      EA=1;                                        //总中断控制
      ES = 1;                              //使能串口1中断

}

void Uart2_Init(void)
{
      S2CON = 0x50;                //8位数据,可变波特率
      AUXR |= 0x04;                //定时器时钟1T模式
      //9600频率
      T2L = 0xE0;                        //设置定时初始值
      T2H = 0xFE;                        //设置定时初始值
      AUXR |= 0x10;                //定时器2开始计时
      IE2 |= 0x01;                //使能串口2中断
}


void Delay10ms(void)      //@11.0592MHz
{
      unsigned char data i, j;

      i = 108;
      j = 145;
      do
      {
                while (--j);
      } while (--i);
}

void Delay1000ms(void)      //@11.0592MHz
{
      unsigned char data i, j, k;

      i = 57;
      j = 27;
      k = 112;
      do
      {
                do
                {
                        while (--k);
                } while (--j);
      } while (--i);
}


void UART1_Isr() interrupt 4
{
    unsigned char received_byte;
        if(TI){
                TI = 0;
        }
                if(RI)
                {
                        RI = 0;
                        received_byte= SBUF;
       if (rx_count < BUFFER_SIZE)
      {
            rx_buffer = received_byte;// 写入数据
            rx_in = (rx_in + 1) % BUFFER_SIZE;// 更新写入指针
            rx_count++;// 增加计数
      }
                }
               
}




void UART2_Isr() interrupt 8
{
      unsigned char received_byte2;
      if(S2CON & 0x01){
                S2CON &= ~0x01;
                received_byte2= S2BUF;
         if (rx_count2 < BUFFER_SIZE)
                {
                              rx_buffer2 = received_byte2;// 写入数据
                              rx_in2 = (rx_in2 + 1) % BUFFER_SIZE;// 更新写入指针
                              rx_count2++;// 增加计数
                }
      }
                                        if (S2CON & 0x02)        //检测串口2发送中断
        {
                S2CON &= ~0x02;        //清除串口2发送中断请求位
        }
                               
}


void main() {
        P_SW2 |= 0x80;
Uart1_Init();
      Uart2_Init();
      
      P1M0 = 0x00;
P1M1 = 0x00;
      TI = 0;
         while(1)// 无限循环
    {
      if (rx_count > 0)// 如果缓冲区中有数据
      {
            //TI = 0;// 清除发送中断标志(如果需要)
                                        while(TI);SBUF = 4;
                                        //SBUF = rx_buffer;// 从缓冲区取出数据发送
                                        S2BUF = rx_buffer;
                                        rx_out = (rx_out + 1) % BUFFER_SIZE;// 更新读取指针
                                        rx_count--;// 减少计数
                                        //P12 =1;
                                        //Delay10ms();
      }else if(rx_count2 > 0){
                                        while(TI);SBUF = 5;
                                        //SBUF = rx_buffer2;
                                        rx_out2 = (rx_out2 +1) % BUFFER_SIZE;
                                        rx_count2--;
                                        P12 =1;
                                        Delay10ms();
                              }
                              else{
                                                P12 =0;
                              }
    }
}


页: [1]
查看完整版本: [求助] 8H 串口2只能发送数据接收不了,请问下是啥原因啊谢谢