找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4496|回复: 2
打印 上一主题 下一主题
收起左侧

51单片机串口通信 接收不到返回值

[复制链接]
跳转到指定楼层
楼主
新人第一次提问,如有不足请各位多多包涵~
单片机型号:STC85C516  晶振:12MHz  波特率:2400

问题描述:在做UART串口通信时 我想实现用电脑给单片机发送一个数字 然后单片机返回这个数字+1的值  但是通过串口助手发现单片机没有返回任何东西   想请问一下为什么会这样?是程序的问题吗?还是有哪里设置不对?谢谢各位!!

串口设置如图:


单片机程序代码如下:
  1. #include<reg52.h>

  2. sbit PIN_RXD=P3^0;
  3. sbit PIN_TXD=P3^1;

  4. typedef unsigned char u8;
  5. typedef unsigned int u16;

  6. bit RxdOrTxd=0;//用于判断现在是接受还是发送数据
  7. bit RxdEnd=0;//接收完毕标志
  8. bit TxdEnd=0;//发送完毕标志

  9. u8 RxdBuff=0;//接收数据缓冲区
  10. u8 TxdBuff=0;//发送数据缓冲区
  11. u16 baud;

  12. void ConfigBaud(u16);//设置波特率函数
  13. void StartRxd();
  14. void StartTxd(u8 dat);

  15. void main()
  16. {   
  17.         ConfigBaud(2400);
  18.         EA=1;

  19.         while(1)
  20.         {
  21.         //接收数据时 没有数据过来的时候一直是高电平
  22.         while(PIN_RXD);//退出循环时 说明已经有数据过来了,已经收到了起始位了
  23.         StartRxd();
  24.         while(!RxdEnd);//一直保持在接受信号的状态直到给出接收结束的信号
  25.         StartTxd(RxdBuff+1);//准备发送信号
  26.         while(!TxdEnd);//一直保持在发送信号的状态直到结束
  27.         
  28.         }

  29. }


  30. void ConfigBaud(u16 baud)
  31. {
  32.         TMOD=(TMOD&0x0F)|0x20; //定时器1设置为模式2
  33.         TH1=256-1000000/(baud*32);
  34. }

  35. void StartRxd()
  36. {
  37.         TL0=256-((256-TH0)>>1);//256-TH0是发送一位需要的时间 向右移动一位表示除了2
  38.         //所以计时器第一次溢出的时间是发送一位所需的一半 目的是为了检验接受到的0是干扰还是真正的起始位
  39.         ET1=1;
  40.         TR1=1;//现在才开中断
  41.         
  42.         RxdEnd=0;//清零接受结束标志位
  43.         RxdOrTxd=0;//设置状态为发送
  44. }


  45. void StartTxd(u8 dat)
  46. {
  47.         TxdBuff=dat;
  48.         TL1=TH1;
  49.         ET1=1;
  50.         TR1=1;

  51.         PIN_TXD=0;//发送起始位
  52.         TxdEnd=0;//结束标志位清零
  53.         RxdOrTxd=1;//现在状态是发送
  54. }

  55. void InterruptTimer1() interrupt 3
  56. {
  57.         static u8 cnt=0;


  58.         if(!RxdOrTxd)//如果状态是接受数据
  59.         {
  60.                 if(cnt==0)//说明当前在处理的是起始位
  61.                 {
  62.                         if(!PIN_RXD)//如果真的是起始位而不是干扰
  63.                         {
  64.                                  cnt++;
  65.                                 RxdBuff=0;//清空缓冲区准备接受数据
  66.                         }
  67.                         else
  68.                         {TR1=0;}
  69.                
  70.                 }
  71.                 else if(cnt>=8)//数据接收完毕
  72.                 {
  73.                         RxdEnd=1;
  74.                         cnt=0;
  75.                         TR1=0;
  76.                 }
  77.                 else //接受数据
  78.                 {
  79.                         RxdBuff>>=1;//因为先进来的是低位 往右移动
  80.                         if(RxdBuff)//如果此时接收到的位是1
  81.                         {RxdBuff|=0x80;}//那就把最高位置1其他不动
  82.                         //如果此时接受到的是0 那直接移动就好了 自动补0
  83.                 }
  84.                                 
  85.         }
  86.         else//发送数据
  87.         {        
  88.                 cnt++;
  89.                 PIN_TXD=TxdBuff&0x01;
  90.                 TxdBuff>>=1;

  91.                 if(cnt>=8)
  92.                 {
  93.                         cnt=0;
  94.                         PIN_TXD=1;//结束位要发1
  95.                         TxdEnd=1;
  96.                         TR1=0;//关定时器
  97.                 }               
  98.         }
  99.         
  100. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2019-8-18 07:16 | 只看该作者
1.没有STC85C516这个型号,只有STC89C516RD+这个型号。
2.使用12MHz晶振波特率会有误差,建议使用11.0592MHz晶振。
3.串口通讯模块已经是做在MCU内部的硬件,通过正常配置相应寄存器就能正常工作,不需要像模拟串口那样写程序。
4.串口中断号是interrupt 4, 不是interrupt 3
给你一个测试程序参考
  1. #include <reg52.H>

  2. unsigned char a;//接收缓冲变量

  3. void main()                                                       
  4. {
  5.         TMOD=0x20;        //定时器1方式2(8位自动重载)
  6.         TH1=0xf3;         //波特率2400,12MHz晶振误差0.16%
  7.         TL1=0xf3;
  8. //        TH1=0xf4;         //波特率2400,11.0592MHz晶振误差0.00%
  9. //        TL1=0xf4;
  10.         TR1=1;                //开定时器1
  11.         REN=1;                //允许串行接收
  12.         SM0=0;                //设置串口方式1(8位UART波特率可变)
  13.         SM1=1;                //设置串口方式1(8位UART波特率可变)
  14.         EA=1;                        //开总中断
  15.         ES=1;                        //开串口中断
  16.         while(1);
  17. }

  18. void UARTInterrupt(void) interrupt 4
  19. {//当接收完成发生中断请求RI由硬件置1
  20.         RI=0;                        //接收中断请求标志位必须软件清0
  21.         a=SBUF;                //保存SBUF接收到的数据
  22.         SBUF=a;                //发送收到的数据
  23.         while(!TI);        //等待发送中断请求标志位为1
  24.         TI=0;                        //发送中断请求标志位必须软件清0
  25. }
复制代码
回复

使用道具 举报

板凳
ID:601140 发表于 2019-8-18 11:22 | 只看该作者
wulin 发表于 2019-8-18 07:16
1.没有STC85C516这个型号,只有STC89C516RD+这个型号。
2.使用12MHz晶振波特率会有误差,建议使用11.0592M ...

那个单片机型号确实是我打错了不好意思...非常感谢您的详细解答!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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