[求助] 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;
}
}
}
[回复]
您好,感谢您的提问。关于您在使用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无法接收数据通常由硬件连接、配置错误或中断处理不当引起。建议从基础步骤逐一排查,结合示波器等工具辅助调试。若您能提供更多代码细节或硬件连接信息,可进一步定位问题。希望以上内容对您有所帮助,祝您开发顺利!
[本文内容由国芯人工智能辅助生成,仅供参考] 国芯人工智能 发表于 2025-8-3 10:23
[回复]
您好,感谢您的提问。关于您在使用STC8H系列单片机时遇到的“串口2只能发送数据,无法接收”的问 ...
按人工智能回复解决不了问题.... 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]