找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4397|回復(fù): 6
收起左側(cè)

單片機(jī)串口通訊程序波特率只能是4800,其他的波特率就會(huì)出錯(cuò)

[復(fù)制鏈接]
ID:149043 發(fā)表于 2017-10-13 17:05 來自觸屏版 | 顯示全部樓層 |閱讀模式
小弟入門單片機(jī)不久,在寫一個(gè)小程序,目標(biāo)是從單片機(jī)從串口發(fā)送數(shù)據(jù)給單片機(jī),單片機(jī)接受數(shù)據(jù)放進(jìn)數(shù)組,新數(shù)據(jù)來到后和之前數(shù)組中的數(shù)據(jù)進(jìn)行比較,如果相同不進(jìn)入數(shù)組,不相同就進(jìn)入數(shù)組,最后輸出數(shù)組中元素的個(gè)數(shù),顯示到數(shù)碼管上。


這個(gè)是程序,單片機(jī)也可以從正常接收到數(shù)據(jù),但是無法輸出正確的個(gè)數(shù)…,而且………這款單片機(jī)為什么只能用4800的波特率發(fā)送數(shù)據(jù)啊,只要用其他的波特率都會(huì)出錯(cuò)???求大佬們幫忙找到程序中的錯(cuò)誤,給我一些篩選比較方面的提示。。。

  1. #include "reg52.h"                         //此文件中定義了單片機(jī)的一些特殊功能寄存器
  2. #include "intrins.h"
  3. #include "stdio.h"

  4. typedef unsigned int uint;          //對(duì)數(shù)據(jù)類型進(jìn)行聲明定義
  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];//個(gè)位               
  23. }

  24. void InitUART()                             //串口1設(shè)置          上位機(jī)通訊
  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字節(jié)發(fā)送****************/
  36. void UART_SendOneByte(unsigned char c)
  37. {
  38.     SBUF = c;
  39.     while(!TI);           //若TI=0,在此等待
  40.     TI = 0;         
  41. }
  42. /****************串行口1字符發(fā)送****************/
  43. void SendStr1(unsigned char *s)
  44. {
  45. while(*s!='\0') //通過檢測是否字符串末尾
  46.   {
  47.   UART_SendOneByte(*s);
  48.   s++;
  49.   }
  50. }
  51. /*******************************************************************************
  52. * 函 數(shù) 名         : delay
  53. * 函數(shù)功能                   : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)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. * 函 數(shù) 名         : DigDisplay
  71. * 函數(shù)功能                   : 數(shù)碼管動(dòng)態(tài)掃描函數(shù),循環(huán)掃描8個(gè)數(shù)碼管顯示
  72. *******************************************************************************/
  73. void DigDisplay()
  74. {
  75.         uchar i;
  76.         for(i=0;i<4;i++)
  77.         {
  78.                 switch(i)         //位選,選擇點(diǎn)亮的數(shù)碼管,
  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];//發(fā)送段碼
  90.                 delay(100); //間隔一段時(shí)間掃描      
  91.                 P0=0x00;//消隱
  92.         }
  93. }

  94. /*******************************************************************************
  95. * 函 數(shù) 名       : main
  96. * 函數(shù)功能                 : 主函數(shù)
  97. * 輸    入       : 無
  98. * 輸    出             : 無
  99. *******************************************************************************/
  100. void main()
  101. {      
  102.     InitUART();
  103.         while(1);
  104.         /*while(1)
  105.         {      
  106.                 if(!Key_U)                                        //判斷按鍵是否按下
  107.                 {
  108.                         Delayms(5);                                //延時(shí)消抖
  109.                         if(!Key_U)                                //判斷按鍵是否按下
  110.                         {                                       
  111.                                 while(!Key_U);                 //等待按鍵松開   
  112.                                 SendStr1("\nU\r");        //發(fā)送<LF>U<CR>           多標(biāo)簽讀取指令                              
  113.                         }      
  114.                 }
  115.                 xianshi();
  116.                 DigDisplay();  //數(shù)碼管顯示函數(shù)      
  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. }
復(fù)制代碼



我用的就是這款開發(fā)版,波特率只能是4800,只要是其他的波特率就會(huì)出錯(cuò)。。。
-1003127784.jpg
回復(fù)

使用道具 舉報(bào)

ID:82765 發(fā)表于 2017-10-13 22:32 | 顯示全部樓層
提示: 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽
回復(fù)

使用道具 舉報(bào)

ID:123289 發(fā)表于 2017-10-14 19:25 | 顯示全部樓層
串口中斷未規(guī)劃得好。
中斷收到一個(gè)字節(jié)后就退出來。
回復(fù)

使用道具 舉報(bào)

ID:1064915 發(fā)表于 2023-6-19 10:14 | 顯示全部樓層
單片機(jī)用12M晶振,9600誤差太大,4800還可以
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2023-6-19 13:00 | 顯示全部樓層
joyb 發(fā)表于 2023-6-19 10:14
單片機(jī)用12M晶振,9600誤差太大,4800還可以

和12M 沒什么關(guān)系,我12M 用57600一樣沒事
問題的關(guān)鍵是他中斷里有了:
                SBUF = count;
                while(!TI);
這個(gè)東西,說實(shí)話,中斷里放了這個(gè) 他 4800 能用應(yīng)該已經(jīng)偷笑了。
回復(fù)

使用道具 舉報(bào)

ID:744809 發(fā)表于 2023-6-19 15:07 | 顯示全部樓層
188610329 發(fā)表于 2023-6-19 13:00
和12M 沒什么關(guān)系,我12M 用57600一樣沒事
問題的關(guān)鍵是他中斷里有了:
                SBUF = count; ...

STC89C51 12M用定時(shí)器0/定時(shí)器1最多只能用4800,11.0592M能用9600,更高的要22.1184M才行了。當(dāng)然用STC8H8K、STC15\STC12等系列較新的51單片機(jī),可以更快速率通信。STC89C51單片機(jī)用T2定時(shí)器,11.0592M的晶振可以用115200波特率。
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2023-6-20 13:15 | 顯示全部樓層
這個(gè)問題搜舊帖子就行。BBS比Q群好太多的優(yōu)點(diǎn)就在于此。
http://www.torrancerestoration.com/bbs/dpj-150703-1.html
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表