找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3142|回复: 6
收起左侧

单片机串口通讯程序波特率只能是4800,其他的波特率就会出错

[复制链接]
ID:149043 发表于 2017-10-13 17:05 来自手机 | 显示全部楼层 |阅读模式
小弟入门单片机不久,在写一个小程序,目标是从单片机从串口发送数据给单片机,单片机接受数据放进数组,新数据来到后和之前数组中的数据进行比较,如果相同不进入数组,不相同就进入数组,最后输出数组中元素的个数,显示到数码管上。


这个是程序,单片机也可以从正常接收到数据,但是无法输出正确的个数…,而且………这款单片机为什么只能用4800的波特率发送数据啊,只要用其他的波特率都会出错啊?!??求大佬们帮忙找到程序中的错误,给我一些筛选比较方面的提示。。。

  1. #include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
  2. #include "intrins.h"
  3. #include "stdio.h"

  4. typedef unsigned int uint;          //对数据类型进行声明定义
  5. typedef unsigned char uchar;

  6. #define RX0_Lenth 200
  7. uint date,count;

  8. char TimeOut;
  9. char idata  shuzu[];

  10. sbit LSA=P2^2;
  11. sbit LSB=P2^3;
  12. sbit LSC=P2^4;
  13. sbit Key_U=P3^2;

  14. uint count=1;

  15. uchar code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9的值
  16. uchar disp[4];
  17. void xianshi()
  18. {
  19.         disp[0]=smgduan[count/1000];//千位
  20.         disp[1]=smgduan[count%1000/100];//百位
  21.         disp[2]=smgduan[count%1000%100/10];//十位
  22.         disp[3]=smgduan[count%1000%100%10];//个位               
  23. }

  24. void InitUART()                             //串口1设置          上位机通讯
  25. {
  26.     TMOD = 0x20;               
  27.     SCON = 0x50;
  28.         PCON = 0x80; //加倍后为19200
  29.     TH1 = 0xF3;//2400,加倍后为4800
  30.     TL1 = TH1;
  31.     EA = 1;
  32.     ES = 1;
  33.     TR1 = 1;
  34. }
  35. /****************串行口1字节发送****************/
  36. void UART_SendOneByte(unsigned char c)
  37. {
  38.     SBUF = c;
  39.     while(!TI);           //若TI=0,在此等待
  40.     TI = 0;         
  41. }
  42. /****************串行口1字符发送****************/
  43. void SendStr1(unsigned char *s)
  44. {
  45. while(*s!='\0') //通过检测是否字符串末尾
  46.   {
  47.   UART_SendOneByte(*s);
  48.   s++;
  49.   }
  50. }
  51. /*******************************************************************************
  52. * 函 数 名         : delay
  53. * 函数功能                   : 延时函数,i=1时,大约延时10us
  54. *******************************************************************************/
  55. void delay(uint i)
  56. {
  57.         while(i--);      
  58. }

  59. void Delayms(unsigned int t)                //@12.000MHz   
  60. {
  61.     unsigned char a,b;
  62.         while(t--)
  63.         {
  64.                    for(b=18;b>0;b--)
  65.                 for(a=152;a>0;a--);
  66.             _nop_();  //if Keil,require use intrins.h
  67.         }
  68. }

  69. /*******************************************************************************
  70. * 函 数 名         : DigDisplay
  71. * 函数功能                   : 数码管动态扫描函数,循环扫描8个数码管显示
  72. *******************************************************************************/
  73. void DigDisplay()
  74. {
  75.         uchar i;
  76.         for(i=0;i<4;i++)
  77.         {
  78.                 switch(i)         //位选,选择点亮的数码管,
  79.                 {
  80.                         case(0):
  81.                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  82.                         case(1):
  83.                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  84.                         case(2):
  85.                                 LSA=0;LSB=1;LSC=0; break;//显示第2位
  86.                         case(3):
  87.                                 LSA=1;LSB=1;LSC=0; break;//显示第3位      
  88.                 }
  89.                 P0=disp[3-i];//发送段码
  90.                 delay(100); //间隔一段时间扫描      
  91.                 P0=0x00;//消隐
  92.         }
  93. }

  94. /*******************************************************************************
  95. * 函 数 名       : main
  96. * 函数功能                 : 主函数
  97. * 输    入       : 无
  98. * 输    出             : 无
  99. *******************************************************************************/
  100. void main()
  101. {      
  102.     InitUART();
  103.         while(1);
  104.         /*while(1)
  105.         {      
  106.                 if(!Key_U)                                        //判断按键是否按下
  107.                 {
  108.                         Delayms(5);                                //延时消抖
  109.                         if(!Key_U)                                //判断按键是否按下
  110.                         {                                       
  111.                                 while(!Key_U);                 //等待按键松开   
  112.                                 SendStr1("\nU\r");        //发送<LF>U<CR>           多标签读取指令                              
  113.                         }      
  114.                 }
  115.                 xianshi();
  116.                 DigDisplay();  //数码管显示函数      
  117.         }*/               
  118. }

  119. void UART_1Interrupt() interrupt 4          //串口1接收程序
  120. {
  121.     uint i;
  122.         if(RI)
  123.         {      
  124.             for(i=0;i<count;i++)
  125.             {
  126.                         date = SBUF;
  127.                 if(date != shuzu[i+1] )
  128.                 {
  129.                             if(count >= RX0_Lenth)        count = 0;
  130.                            shuzu[count] = date;
  131.                            count++;
  132.                 }
  133.                     }
  134.                 RI=0;
  135.                 SBUF = count;
  136.                 while(!TI);
  137.                 TI=0;
  138.         //        TimeOut = 5;
  139.         }      
  140. }
复制代码



我用的就是这款开发版,波特率只能是4800,只要是其他的波特率就会出错。。。
-1003127784.jpg
回复

使用道具 举报

ID:82765 发表于 2017-10-13 22:32 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

ID:123289 发表于 2017-10-14 19:25 | 显示全部楼层
串口中断未规划得好。
中断收到一个字节后就退出来。
回复

使用道具 举报

ID:1064915 发表于 2023-6-19 10:14 | 显示全部楼层
单片机用12M晶振,9600误差太大,4800还可以
回复

使用道具 举报

ID:624769 发表于 2023-6-19 13:00 | 显示全部楼层
joyb 发表于 2023-6-19 10:14
单片机用12M晶振,9600误差太大,4800还可以

和12M 没什么关系,我12M 用57600一样没事
问题的关键是他中断里有了:
                SBUF = count;
                while(!TI);
这个东西,说实话,中断里放了这个 他 4800 能用应该已经偷笑了。
回复

使用道具 举报

ID:744809 发表于 2023-6-19 15:07 | 显示全部楼层
188610329 发表于 2023-6-19 13:00
和12M 没什么关系,我12M 用57600一样没事
问题的关键是他中断里有了:
                SBUF = count; ...

STC89C51 12M用定时器0/定时器1最多只能用4800,11.0592M能用9600,更高的要22.1184M才行了。当然用STC8H8K、STC15\STC12等系列较新的51单片机,可以更快速率通信。STC89C51单片机用T2定时器,11.0592M的晶振可以用115200波特率。
回复

使用道具 举报

ID:883242 发表于 2023-6-20 13:15 | 显示全部楼层
这个问题搜旧帖子就行。BBS比Q群好太多的优点就在于此。
http://www.51hei.com/bbs/dpj-150703-1.html
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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