找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2842|回复: 19
收起左侧

[已解决]51单片机串口程序问题(在最后说明此次遇到的问题以及解决办法)

[复制链接]
ID:876099 发表于 2021-10-10 21:32 | 显示全部楼层 |阅读模式
目前需要用到51单片机串口控制单片机,但是我程序接受发送都没有问题,不知道哪里有问题,希望大佬帮助解决一下非常感谢,下面是程序,
  1. #include <REGX51.H>
  2. unsigned char i,j;
  3. unsigned char temp;
  4. sbit led1=P2^0;
  5. sbit led2=P2^1;
  6. sbit led3=P2^2;
  7. sbit led4=P2^3;
  8. void xie(char k);
  9. void dis();
  10. void UsartInit()
  11. {
  12.         SCON=0X50;                        //设置为工作方式1
  13.         TMOD=0X20;                        //设置计数器工作方式2
  14.         TH1=0XF9;                        
  15.         TL1=0XF9;
  16.         PCON=0x80;
  17.         ES=1;                                                //打开接收中断
  18.         EA=1;                                                //打开总中断
  19.         TR1=1;                                        //打开计数器
  20. }

  21. void main()
  22. {
  23.    UsartInit();
  24.    xie('a');
  25.    led1=0;
  26.    while(1)
  27.    {
  28.                      
  29.    }
  30. }

  31. void Usart() interrupt 4
  32. {
  33.   if(RI)
  34.   {
  35.   RI=0;
  36.   temp=SBUF;
  37.   SBUF=temp;
  38.   P0=temp;
  39.   dis();
  40.   }
  41.   if(TI)
  42.   {
  43.     TI=0;
  44.   }
  45. }
  46. void xie(char k)
  47. {
  48. SBUF=k;
  49. while(TI==0);
  50. TI=0;
  51. }
  52. void dis()
  53. {
  54.           switch(temp)
  55.         {
  56.           case 0x01:led1=~led1;break;
  57.           case 0x02:led2=~led2;break;
  58.           case 0x03:led3=~led3;break;
  59.           case 0x04:led4=~led4;break;
  60.           default:break;
  61.         }
  62. }
复制代码

波特率是9600


再一次感谢帮助解答我疑问的各位,本人因为不熟悉51单片机串口,所以在写串口程序的时候直接将SBUF的数据送给一个变量然后拿这个变量去判断,最后发现其实单片机是一位一位发送的,最后使用   变量&0x0f  解决问题,感谢大家的帮助
回复

使用道具 举报

ID:624769 发表于 2021-10-10 23:41 | 显示全部楼层
改两个地方, 有反映了再讨论其他

          switch(temp & 0x03)                     <==
        {
          case 0x01:led1=~led1;break;
          case 0x02:led2=~led2;break;
          case 0x03:led3=~led3;break;
          case 0x00:led4=~led4;break;             <===
          default:break;
        }
回复

使用道具 举报

ID:213173 发表于 2021-10-11 06:36 | 显示全部楼层
12M晶振加倍用9600波特率高了,误差太大。改4800或2400即可。
回复

使用道具 举报

ID:844772 发表于 2021-10-11 08:52 | 显示全部楼层
  while(1)后面少了分号,能编译过吗?
回复

使用道具 举报

ID:876099 发表于 2021-10-11 16:09 | 显示全部楼层
glinfei 发表于 2021-10-11 08:52
while(1)后面少了分号,能编译过吗?

下面有大括号,跟后面带分号一样的
回复

使用道具 举报

ID:876099 发表于 2021-10-11 16:10 | 显示全部楼层
wulin 发表于 2021-10-11 06:36
12M晶振加倍用9600波特率高了,误差太大。改4800或2400即可。

这个收发数据,数据回显没有问题,因为需要跟蓝牙通信,蓝牙最低9600所以单片机用的9600
回复

使用道具 举报

ID:624769 发表于 2021-10-11 16:29 | 显示全部楼层
? 还没搞定么?按我说的那样改依然没有反应么?
回复

使用道具 举报

ID:876099 发表于 2021-10-11 16:46 | 显示全部楼层
188610329 发表于 2021-10-10 23:41
改两个地方, 有反映了再讨论其他

          switch(temp & 0x03)

你好,根据你修改的有反应,目前只有0x01和0x02有反应,可以反转,0x03和0x00只能点亮不能反转
回复

使用道具 举报

ID:624769 发表于 2021-10-11 16:58 | 显示全部楼层
1045964948 发表于 2021-10-11 16:46
你好,根据你修改的有反应,目前只有0x01和0x02有反应,可以反转,0x03和0x00只能点亮不能反转

既然如此,我大胆的猜测一下,

你给单片机发送的数据,不是按16进制格式发的吧? 是文本格式吧? 不清楚你电脑用什么软件发的,你仔细看看软件,应该有地方勾选类似“HEX”,如果你是16进制格式发送,应该都能翻转。
回复

使用道具 举报

ID:876099 发表于 2021-10-11 17:10 | 显示全部楼层
188610329 发表于 2021-10-11 16:58
既然如此,我大胆的猜测一下,

你给单片机发送的数据,不是按16进制格式发的吧? 是文本格式吧? 不清 ...

我使用的16进制发送的,根据您修改的程序只能反转01和02,其他两个点亮后就不能熄灭了
回复

使用道具 举报

ID:876099 发表于 2021-10-11 17:29 | 显示全部楼层
188610329 发表于 2021-10-11 16:58
既然如此,我大胆的猜测一下,

你给单片机发送的数据,不是按16进制格式发的吧? 是文本格式吧? 不清 ...

还有可以解释一下为什么temp&0x03就可以反转了这个没搞懂,51没学精
回复

使用道具 举报

ID:213173 发表于 2021-10-11 17:44 | 显示全部楼层
1045964948 发表于 2021-10-11 16:10
这个收发数据,数据回显没有问题,因为需要跟蓝牙通信,蓝牙最低9600所以单片机用的9600

如果必须使用波特率9600那就必须更换晶振11.0592MHz。否则误差太大不可能正常传输信息。
回复

使用道具 举报

ID:624769 发表于 2021-10-11 17:51 | 显示全部楼层
1045964948 发表于 2021-10-11 17:29
还有可以解释一下为什么temp&0x03就可以反转了这个没搞懂,51没学精

你一共 4个选项, 根据修改后的CASE  0~3 只有4个结果, 不管你发的数据,是什么,只要你的程序正确运行了,temp & 0x03  之后,一定能符合 4选一,所以用这个先保证程序没问题,接下来只要考虑是不是传输问题就可以了。
回复

使用道具 举报

ID:624769 发表于 2021-10-11 18:09 | 显示全部楼层
1045964948 发表于 2021-10-11 17:10
我使用的16进制发送的,根据您修改的程序只能反转01和02,其他两个点亮后就不能熄灭了

按你说的,发的16进制格式, 回传也没有问题,那么,你接收到的应该也是16进制显示,不然,0x00~0x1F,在文本状态是什么也显示不了的,那么我问一下:

你程序中:
   xie('a');  
你这个,接受到什么了?
回复

使用道具 举报

ID:876099 发表于 2021-10-11 23:39 | 显示全部楼层
wulin 发表于 2021-10-11 17:44
如果必须使用波特率9600那就必须更换晶振11.0592MHz。否则误差太大不可能正常传输信息。

这个传输的数据很稳定的,就是我发送一个A就会返回一个A,目前问题应该是怎么提取出数据的问题
回复

使用道具 举报

ID:876099 发表于 2021-10-11 23:40 | 显示全部楼层
188610329 发表于 2021-10-11 18:09
按你说的,发的16进制格式, 回传也没有问题,那么,你接收到的应该也是16进制显示,不然,0x00~0x1F,在 ...

就接收到了一个a,每次按下复位键就可以接收到一个a
回复

使用道具 举报

ID:624769 发表于 2021-10-11 23:58 | 显示全部楼层
1045964948 发表于 2021-10-11 23:40
就接收到了一个a,每次按下复位键就可以接收到一个a

那么, 说明你上位机串口助手,接收的是文本,

所以,如果,你发16进制 0x01, 0x02, 这些数据给单片机,又是怎么确认成功了回传呢? 16进制数回传的话,你上位机的串口住手压根看不到任何东西。 所以再和你确认一下,你确定你发送的是16进制的 0x01 0x02 去单片机么??
回复

使用道具 举报

ID:876099 发表于 2021-10-12 00:25 | 显示全部楼层
wulin 发表于 2021-10-11 17:44
如果必须使用波特率9600那就必须更换晶振11.0592MHz。否则误差太大不可能正常传输信息。

我重新试了一下12mhz,虽然能传输正确的指令,但是后面会带有乱码,非常感谢你的帮助
回复

使用道具 举报

ID:876099 发表于 2021-10-12 00:26 | 显示全部楼层
188610329 发表于 2021-10-11 23:58
那么, 说明你上位机串口助手,接收的是文本,

所以,如果,你发16进制 0x01, 0x02, 这些数据给单片 ...

因为我接收a使用的文本,然后发送再选中的16进制发送显示
回复

使用道具 举报

ID:876099 发表于 2021-10-12 00:28 | 显示全部楼层
目前用的89c52,之前晶振使用的是12mhz现在使用11.0592mhz就很稳了,感谢大家帮助,明天测试和蓝牙通信,如果没问题的话我回反馈在下面,非常感谢大家能在百忙之中帮我解答疑问
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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