#include <REGX52.H>
void UART_Init(void) //串口初始化函数
//4800bps@12.000MHz
{
PCON |= 0x80; //使能波特率倍速位SMOD
SCON = 0x50; //8位数据,可变波特率,使能接收
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xF3; //设置定时初始值
TH1 = 0xF3; //设置定时重载值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
EA=1; //串口中断
ES=1;
}
void UART_SendByte(unsigned char Byte) //串口发送一个字节数据
{
SBUF=Byte;
while(TI==0); //发送控制器发送后变1,需软件重新赋值0
TI=0;
}
unsigned char data1,data2,count=0,sum;
void main()
{
UART_Init();
while(1)
{
}
}
void UART_Routine() interrupt 4
{
if(RI==1) //返回电脑输入第一个数据函数,十六进制
{
RI=0;
if(count==0)
{
data1=SBUF;
count=1;
}
else if(count==1)
{
data2=SBUF;
count=2;
}
}
if(count==2)
{
sum=data1+data2;
if(sum<=9) //hex模式相当于发送ASCII值,hex模式接收该ASCII对应的十六进制数,当sum<10时,sum不变例如ASCII=9对应0x09
UART_SendByte(sum);
else
{
sum=sum+6; //hex模式相当于发送ASCII值,hex模式接收该ASCII对应的十六进制数,当sum>10时,sum+6例如ASCII=16对应0x10
UART_SendByte(sum);
}
count=0;
}
}
51单片机利用串口hex模式发送两个位数,hex模式返回他们的和,但是第一次发送数据都会出错,后面就再发送正确,能否帮我找一下问题出在哪
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
2条回答 默认 最新
- ChatGPTᴼᴾᴱᴺᴬᴵ 2023-09-08 22:18关注
该回答引用ChatGPT-3.5,仅为您提供参考,不保证完全正确
根据你提供的代码,可能存在一个问题是在程序启动时,count
的初始值为0,这会导致第一次接收数据时,进入了count==0
的条件分支,然后接收到的第一个数据被存储到data1
中,但在第一次发送之前并没有等待接收到第二个数据。这会导致在第一次发送数据之前,data2
变量中的数据是未初始化的。
为了解决这个问题,你可以将
count
的初始值设置为1,或者在程序一开始先接收一个数据,然后再进入主循环等待下一个数据的到来。以下是一种修改后的代码示例:#include <REGX52.H> void UART_Init(void) { PCON |= 0x80; SCON = 0x50; TMOD &= 0x0F; TMOD |= 0x20; TL1 = 0xF3; TH1 = 0xF3; ET1 = 0; TR1 = 1; EA = 1; ES = 1; } void UART_SendByte(unsigned char Byte) { SBUF = Byte; while (TI == 0); TI = 0; } unsigned char data1, data2, count = 1, sum; void main() { UART_Init(); while (1) { // 主循环可以放一些其他的代码逻辑 // 如果需要发送数据,将数据发送到串口 // UART_SendByte(dataToSend); } } void UART_Routine() interrupt 4 { if (RI == 1) { RI = 0; if (count == 1) { data1 = SBUF; count = 2; } else if (count == 2) { data2 = SBUF; count = 0; // 在接收到两个数据后,计算它们的和并发送 sum = data1 + data2; if (sum <= 9) UART_SendByte(sum); else { sum = sum + 6; UART_SendByte(sum); } } } }
这个修改后的代码将在接收到两个数据后再进行计算和发送,从而避免了第一次发送数据时的问题。
该回答引用NewBing,仅为您提供参考,不保证完全正确
未知错误
该回答引用文心一言,仅为您提供参考,不保证完全正确
你的代码里,串口初始化后,你没有设置串口的中断允许,也就是你没有设置ES=1。你需要在UART_Init()函数中添加ES=1;来允许串口中断。
此外,你在主函数main()中,没有开启全局中断,你需要添加EA=1;来允许全局中断。
修改后的代码如下:
#include <REGX52.H> void UART_Init(void) //串口初始化函数 //4800bps@12.000MHz { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率,使能接收 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x20; //设置定时器模式 TL1 = 0xF3; //设置定时初始值 TH1 = 0xF3; //设置定时重载值 ET1 = 0; //禁止定时器中断 TR1 = 1; //定时器1开始计时 EA=1; //允许全局中断 ES=1; //允许串口中断 } void UART_SendByte(unsigned char Byte) //串口发送一个字节数据 { SBUF=Byte; while(TI==0); //发送控制器发送后变1,需软件重新赋值0 TI=0; } unsigned char data1,data2,count=0,sum; void main() { UART_Init(); EA=1; //允许全局中断 //添加这一行 while(1) { } } void UART_Routine() interrupt 4 { if(RI==1) //返回电脑输入第一个数据函数,十六进制 { RI=0; if(count==0) { data1=SBUF; count=1; } else if(count==1) { data2=SBUF; count=2; } } if(count==2) { sum=data1+data2; if(sum<=9) //hex模式相当于发送ASCII值,hex模式接收该ASCII对应的十六进制数,当sum<10时,sum不变例如ASCII=9对应0x09 UART_SendByte(sum); else { sum=sum+6; //hex模式相当于发送ASCII值,hex模式接收该ASCII对应的十六进制数,当sum>10时,sum+6例如ASCII=16对应0x10 UART_SendByte(sum); } count=0; } }
该回答引用讯飞星火,仅为您提供参考,不保证完全正确
问题可能出在串口接收中断函数UART_Routine()中。当第一次接收到数据时,count的值可能为0或1,此时会将接收到的数据存储到data1或data2中。但是,当第二次接收到数据时,count的值为2,此时会将data1和data2相加并将结果存储到sum中。然而,在计算sum的值时,没有考虑到sum可能小于等于9的情况,这可能导致sum的值不正确。
为了解决这个问题,可以在计算sum的值时,根据sum的值是否小于等于9来选择不同的处理方式。以下是修改后的代码:
#include <REGX52.H> void UART_Init(void) //串口初始化函数 //4800bps@12.000MHz { PCON |= 0x80; //使能波特率倍速位SMOD SCON = 0x50; //8位数据,可变波特率,使能接收 TMOD &= 0x0F; //设置定时器模式 TMOD |= 0x20; //设置定时器模式 TL1 = 0xF3; //设置定时初始值 TH1 = 0xF3; //设置定时重载值 ET1 = 0; //禁止定时器中断 TR1 = 1; //定时器1开始计时 EA=1; //串口中断 ES=1; } void UART_SendByte(unsigned char Byte) //串口发送一个字节数据 { SBUF=Byte; while(TI==0); //发送控制器发送后变1,需软件重新赋值0 TI=0; } unsigned char data1,data2,count=0,sum; void main() { UART_Init(); while(1) { } } void UART_Routine() interrupt 4 { if(RI==1) //返回电脑输入第一个数据函数,十六进制 { RI=0; if(count==0) { data1=SBUF; count=1; } else if(count==1) { data2=SBUF; count=2; } } if(count==2) { sum=data1+data2; if(sum<=9) //hex模式相当于发送ASCII值,hex模式接收该ASCII对应的十六进制数,当sum<10时,sum不变例如ASCII=9对应0x09 UART_SendByte(sum); else { sum=sum+6; //hex模式相当于发送ASCII值,hex模式接收该ASCII对应的十六进制数,当sum>10时,sum+6例如ASCII=16对应0x10 UART_SendByte(sum); } count=0; } }
这样修改后,当sum的值小于等于9时,会直接发送sum的值;当sum的值大于9时,会将sum的值加上6后再发送。这样可以确保sum的值正确。
解决 1无用
悬赏问题
- ¥15 微信会员卡接入微信支付商户号收款
- ¥15 如何获取烟草零售终端数据
- ¥15 数学建模招标中位数问题
- ¥15 phython路径名过长报错 不知道什么问题
- ¥15 深度学习中模型转换该怎么实现
- ¥15 HLs设计手写数字识别程序编译通不过
- ¥15 Stata外部命令安装问题求帮助!
- ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
- ¥15 TYPCE母转母,插入认方向
- ¥15 如何用python向钉钉机器人发送可以放大的图片?