久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3344|回復: 19
打印 上一主題 下一主題
收起左側

問一個單片機串口通訊數據丟位的問題

  [復制鏈接]
跳轉到指定樓層
樓主
問題說明:我設置的波特率是9600,然后這個程序就是筆記本發送數據給單片機,單片機馬上原封不動地發送回去,但是在發送回來的時候發現缺位了,比如說我發送了一串數字2019060720055905,但是傳回來的時候有時候就少了一位數字成了201906072055905,我想問下這是程序寫的有什么問題嗎,需要延時還是怎樣?
  1. /*************************************************單純串口通訊程序******************************************************/

  2. 先上程序
  3. #include <reg52.h>

  4. typedef unsigned char uchar;
  5. typedef unsigned int uint;

  6. void SendStr(uchar *s);
  7. void InitUART()

  8. void main()
  9. {
  10.         InitUART();
  11.         SendStr("UART test");
  12.         ES = 1
  13.         while(1)
  14.         {
  15.         }
  16. }

  17. void SendByte(uchar dat)
  18. {
  19.         SBUF = dat;
  20.         while(!TI)
  21.         TI=0;
  22. }

  23. void SendStr(uchar *s)
  24. {
  25.         while(*s != '\0')
  26.         {
  27.                 SendByte(*s);
  28.                 s++;
  29.         }               
  30. }

  31. void InitUART()
  32. {
  33.         SCON = 0x50
  34.         TMOD = 0x20;
  35.         TH1 = 0xFD;
  36.         TR1 = 1;
  37.         EA = 1;
  38. }

  39. void UART_SER() interrupt 4
  40. {
  41.         uchar temp;
  42.         if(RI)
  43.         {
  44.                 RI = 0;
  45.                 temp = SBUF;
  46.                 SBUF = temp;
  47.         }
  48.         if(TI)
  49.         {
  50.                 TI = 0;
  51.         }
  52. }
復制代碼

/******************************************串口中斷和定時器中斷**********************************************/

我這里需要串口給單片機傳時間數據,也需要定時器定時給數碼管掃描顯示數據,但是串口傳給單片機的數據好像也不對,數碼管顯示的時間也不對,所以我覺得是不是兩個中斷會相互干擾,因為串口中斷優先級比定時器0中斷低,所以我特別設置了IP = 0x10,但是也沒什么用,所以想來問下這其中到底有什么問題。下面是串口程序和定時器0程序。
  1. /**************串口程序***************/

  2. #include "UART.h"

  3. bit SetFlag;
  4. uchar time_buf2[16];

  5. void UART_Init()
  6. {
  7.         SCON = 0X50;// SCON:模式1, 8-bit UART,
  8.         TMOD |= 0x20;//TMOD: timer 1, mode 2, 8-bit
  9.         TH1  = 0xFD; // TH1:波特率 9600 2
  10.         TR1 = 1;
  11.         EA = 1;
  12.         ES = 1;
  13.         
  14. }


  15. void UART() interrupt 4
  16. {
  17.         uchar temp;
  18.         static uchar i;
  19.         if(RI)
  20.         {
  21.                 RI = 0;
  22.                 temp = SBUF;
  23.                 time_buf2[i] = temp;
  24.                 i++;
  25.                 if(i == 16)
  26.                 {
  27.                         i = 0;
  28.                         SetFlag = 1;
  29.                 }
  30.                 SBUF = temp;
  31.         }
  32.         if(TI)
  33.         {
  34.                 TI = 0;
  35.         }
  36. }

  37. /*************定時器0程序***************/

  38. #include "Display.h"
  39. #include "Delay.h"

  40. uchar code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  41. uchar code WeiMa[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  42. uchar TempData[8];

  43. void Display(uchar firstbit, uchar num)
  44. {
  45.         static uchar i = 0;
  46.         
  47.         DataPort=0;   //Çå¿Õ¶ÎËø′æÖDμÄêy¾Y£¬·àÖ1óD½»ìæÖØó°
  48.         Seg_Latch = 1;
  49.         Seg_Latch = 0;
  50.         
  51.         DataPort = WeiMa[i+firstbit];
  52.         Bit_Latch = 1;
  53.         Bit_Latch = 0;
  54.                
  55.         DataPort = TempData[i];
  56.         Seg_Latch = 1;
  57.         Seg_Latch = 0;
  58.         
  59.         i++;
  60.         if(i == num)
  61.         {
  62.                 i = 0;
  63.         }
  64. }

  65. void Init_Timer0()
  66. {
  67.         TMOD |= 0x01;
  68.         TH0 = (65535-2000)/256;
  69.         TL0 = (65535-2000)%256;
  70.         EA = 1;
  71.         ET0 = 1;
  72.         TR0 = 1;
  73. }

  74. void Timer0() interrupt 1
  75. {
  76.         static uchar  num;
  77.         TH0 = (65535-500)/256;
  78.         TL0 = (65535-500)%256;
  79.         Display(0,8);
  80.         num++;
  81.         
  82.         if(num == 50)
  83.         {
  84.                 num = 0;
  85.                 ReadTimeFlag = 1;
  86.         }
  87.         
  88. }
復制代碼

下面就是串口通訊的錯誤結果


        


question.png (12.26 KB, 下載次數: 62)

question.png
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

來自 2#
ID:207421 發表于 2019-6-8 12:37 | 只看該作者
哪里抄的代碼,代碼中很多錯誤
串口通信注意的是:
1. 晶振的誤差會導致數據發生錯誤
2. 發送速度的快慢, 一個巴掌扇過去,那個人還沒來得及回復你,你又一個巴掌,他做啞巴得了,你白問了.
3. 沒有對數據進行校驗的函數
4. 接收或發送數據時,  沒有進行ES或EA處理,不就存在BUG了么
回復

使用道具 舉報

來自 3#
ID:557163 發表于 2019-6-8 22:57 | 只看該作者
這么改
1. 漏了個分號
void SendByte(uchar dat)
{
        SBUF = dat;
        while(!TI);  // 這里加上分號
        TI=0;
}

2.  中斷服務程序的收發看似沒問題,當單片機的波特率比電腦略低時,有一定的概率上一個字節發送還沒完下一個字節就收到了,簡單粗暴的改法是
把   SBUF=temp;
改為  SendByte(temp);
回復

使用道具 舉報

地板
ID:523537 發表于 2019-6-7 20:36 | 只看該作者
下面就是串口通訊的錯誤結果
回復

使用道具 舉報

5#
ID:523537 發表于 2019-6-8 06:14 | 只看該作者
懇請各位大佬指點
回復

使用道具 舉報

6#
ID:94031 發表于 2019-6-8 08:35 | 只看該作者
發送雙方都要給對方留出處理信息的時間。
回復

使用道具 舉報

7#
ID:557425 發表于 2019-6-8 11:42 | 只看該作者

發送雙方都要給對方留出處理信息的時間。



回復

使用道具 舉報

8#
ID:259083 發表于 2019-6-8 17:09 | 只看該作者
可能是兩個單片機的波特率誤差導致的,你可以換幾組波特率試試,如果還是不行,最好加CRC 校驗等校驗模式進行校驗,也可以考慮采用糾錯碼來糾正誤碼!
回復

使用道具 舉報

9#
ID:93224 發表于 2019-6-8 17:30 | 只看該作者
數碼管用定時器0,串口的用定時器1
回復

使用道具 舉報

10#
ID:523537 發表于 2019-6-8 19:14 | 只看該作者
lwh999995 發表于 2019-6-8 12:37
哪里抄的代碼,代碼中很多錯誤
串口通信注意的是:
1. 晶振的誤差會導致數據發生錯誤

這個代碼是我參照例子寫的。首先我用的是11.0592MHz的晶振,波特率9600,我想問下需要延時要在哪里加_nop_()函數呢?另外我這個因為是電腦和單片機通訊,為了簡單一點所以沒有校驗,最后接受和發送數據的時候要關閉總中斷來避免多個中斷干擾數據傳輸嗎?
回復

使用道具 舉報

11#
ID:523537 發表于 2019-6-8 19:15 | 只看該作者
xuyaqi 發表于 2019-6-8 08:35
發送雙方都要給對方留出處理信息的時間。

那需要在哪里加延時函數呢?
回復

使用道具 舉報

12#
ID:523537 發表于 2019-6-8 19:16 | 只看該作者
lele5211314 發表于 2019-6-8 17:30
數碼管用定時器0,串口的用定時器1

我數碼管確實用的是定時器0,串口用的是定時器1啊
回復

使用道具 舉報

13#
ID:519141 發表于 2019-6-8 19:34 | 只看該作者
數據傳輸開始和完成都需要有確認語句,方可進行下一步的操作
回復

使用道具 舉報

14#
ID:523537 發表于 2019-6-9 14:06 | 只看該作者
he_37 發表于 2019-6-8 22:57
這么改
1. 漏了個分號
void SendByte(uchar dat)

分號是我復制粘貼上來的時候不小心刪掉了,不過我想了下你的改法應該是對的,后面我嘗試了下也確實是對的,沒有出現過一次丟包,不過我又有了一個新問題,我先把代碼復制上來吧。void UART_SER() interrupt 4{
        uchar temp;
        if(RI)
        {
                RI = 0;
                temp = SBUF;
                SBUF = temp;
                /*下面兩個語句就是SendByte(uchar dat)的功能*/
                while(!TI);
                TI = 0;
        }
}


我是這么想的,電腦發送了一個8位數據過來,單片機接收端的SBUF接收了,然后我把數據轉給了發送端的SBUF,然后就是while(!TI);等待單片機發送完,但是我的串口中斷還是開的,那么當單片機數據發送完TI置1,那么就會觸發中斷,然后又從中斷函數開頭uchar temp;開始,那么而且我也把TI=0;語句刪了,那么按道理就是應該無限循環啊,為啥還會完整把整個數據接收完呢?我現在也搞不懂了。
回復

使用道具 舉報

15#
ID:523537 發表于 2019-6-9 14:12 | 只看該作者
he_37 發表于 2019-6-8 22:57
這么改
1. 漏了個分號
void SendByte(uchar dat)

更有意思的是我整個串口中斷程序沒有把TI置0也可以進行串口通訊,只是也有丟位。
void UART_SER() interrupt 4
{
        uchar temp;
        if(RI)
        {
                RI = 0;
                temp = SBUF;
                SBUF = temp;
                /*下面兩個語句就是SendByte(uchar dat)的功能*/
                while(!TI);
        }
}

回復

使用道具 舉報

16#
ID:552783 發表于 2019-6-9 21:13 | 只看該作者
我覺得可以加個校驗
回復

使用道具 舉報

17#
ID:222006 發表于 2019-6-10 01:01 | 只看該作者
波特率和檢驗的問題,小老弟串口不要用人家的源碼呀,bug多得嚇死人喲,還占資源
回復

使用道具 舉報

18#
ID:523537 發表于 2019-6-10 09:55 | 只看該作者
闊愛的釗釗 發表于 2019-6-10 01:01
波特率和檢驗的問題,小老弟串口不要用人家的源碼呀,bug多得嚇死人喲,還占資源

自己也是剛學,很多東西都不太懂,只好在源碼上做簡單修改
回復

使用道具 舉報

19#
ID:243060 發表于 2019-6-10 11:39 | 只看該作者
串口通訊的時間是最主要的,要保證兩個通訊的頻率是一樣的,其次對于發射和接受的延時等待時間也要一致
回復

使用道具 舉報

20#
ID:523537 發表于 2019-6-11 00:03 | 只看該作者
yumer 發表于 2019-6-10 11:39
串口通訊的時間是最主要的,要保證兩個通訊的頻率是一樣的,其次對于發射和接受的延時等待時間也要一致

嗯嗯,確實是這樣,多謝指教了!
回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品国产成人国产三级 | 国产精品黄色 | 亚洲欧美国产精品一区二区 | 超碰一区二区 | 国产精品欧美一区二区三区 | 国产日韩欧美综合 | 国产精品久久 | 天堂色综合 | 五月天激情综合网 | 瑞克和莫蒂第五季在线观看 | 欧美a级成人淫片免费看 | 成人免费大片黄在线播放 | 国产精品1区2区3区 男女啪啪高潮无遮挡免费动态 | 91国产精品在线 | 日本精品视频 | 欧美日韩中文字幕 | 亚洲精品自拍视频 | 91精品久久久久 | 亚洲综合字幕 | 亚洲aⅴ | 伊伊综合网 | 久草欧美 | 精品久久99 | 天天干天天色 | 国产精品成人一区二区三区夜夜夜 | 欧美日韩中文在线 | 久久九精品 | 久久这里只有 | 成人欧美一区二区三区在线播放 | 亚洲国产一区二区视频 | 香蕉婷婷 | 久久久www| 日韩久久久久久久久久久 | 国产精品伦一区二区三级视频 | 日韩三级一区 | 日本二区在线观看 | 国产精品一区二区三区免费观看 | 亚洲一区国产精品 | 久久久久久久久精 | 久亚州在线播放 | 亚洲人va欧美va人人爽 |