找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索

51單片機(jī)UART通信-不理解接收程序 求分析

查看數(shù): 1843 | 評(píng)論數(shù): 16 | 收藏 0
關(guān)燈 | 提示:支持鍵盤(pán)翻頁(yè)<-左 右->
    組圖打開(kāi)中,請(qǐng)稍候......
發(fā)布時(shí)間: 2023-6-4 20:16

正文摘要:

不理解邏輯。 單片機(jī)是通過(guò)010101這種的高低電平模擬二級(jí)制記錄數(shù)據(jù)的,這里是接收數(shù)據(jù)部分,PIN_RXD引腳的高低電平這里是如何控制的? #include <reg52.h> sbit PIN_RXD = P3^0; sbit PIN_TXD = P3^1; ...

回復(fù)

ID:1078938 發(fā)表于 2023-6-6 09:43
wulin 發(fā)表于 2023-6-5 06:05
軟件模擬串口示例
  1.   if (RING)
  2.         {
  3.                 if (--RCNT == 0)
  4.                 {
  5.                         RCNT = 3;                   //重置發(fā)送波特率計(jì)數(shù)器
  6.                         if (--RBIT == 0)
  7.                         {
  8.                                 RBUF = RDAT;            //將數(shù)據(jù)保存到RBUF
  9.                                 RING = 0;               //停止接收
  10.                                 REND = 1;               //設(shè)置接收完成標(biāo)志
  11.                         }
  12.                         else
  13.                         {
  14.                                 RDAT >>= 1;
  15.                                 if (RXB) RDAT |= 0x80;  //將RX數(shù)據(jù)轉(zhuǎn)換為RX緩沖區(qū)
  16.                         }
  17.                 }
  18.         }
  19.         else if (!RXB)
  20.         {
  21.                 RING = 1;                       //設(shè)置開(kāi)始接收標(biāo)志
  22.                 RCNT = 4;                       //初始接收波特率計(jì)數(shù)器
  23.                 RBIT = 9;                       //initial receive bit number (8 data bits + 1 stop bit)
  24.         }                                                                                          //初始接收比特?cái)?shù)(8個(gè)數(shù)據(jù)位+ 1個(gè)停止位)
復(fù)制代碼

我的理解:         波特率就是傳輸二進(jìn)制的速率,這里選用的是1200,每秒傳送1200個(gè)比特位,1 / 1200 = 833 us,833us傳輸一個(gè)比特位。每次溢出后進(jìn)入中斷,代表已經(jīng)時(shí)間已經(jīng)達(dá)到一個(gè)碼元位,如果向下面理解那么傳輸?shù)谋忍夭粦?yīng)該是對(duì)的????

接收代碼的理解:
    1.當(dāng)遇到低電平RXB的時(shí)候,代表UART通信開(kāi)始接收,先把RING = 1 , 比特計(jì)數(shù)器RCNT = 4 , 比特?cái)?shù)RBIT = 9。
    2.下次再進(jìn)入中斷,RCNT自動(dòng)減1,經(jīng)過(guò)4次中斷進(jìn)入后,直到RCNT = 0,然后賦值RCNT = 3,比特?cái)?shù)RBT減少一位,這時(shí)候認(rèn)為數(shù)據(jù)是有效的,把RXB電平的數(shù)據(jù)記錄到RDAT中。
    3. 每個(gè)比特位都需要RCNT減3次后才把RXB的數(shù)據(jù)賦值給RDAT。同時(shí),把RBIT數(shù)據(jù)也減1,直到等于0就代表接收完畢,然后恢復(fù)RING = 0。








ID:624769 發(fā)表于 2023-6-5 11:26
哈蘭德 發(fā)表于 2023-6-5 01:30
接收部分,是從每個(gè)比特位的中間部分接收的,不太理解如何從1.3-1.5接收

參考9樓給你的代碼,這是典型的3分波特率,每個(gè)位的間隔為3次中斷,收到起始信號(hào)時(shí)為4個(gè)時(shí)間中斷,就是從1.333的位置開(kāi)始接受。
ID:123289 發(fā)表于 2023-6-5 10:43
【PIN_RXD引腳的高低電平這里是如何控制的?】
由發(fā)送方進(jìn)行控制。
控制的邏輯依據(jù)串行協(xié)議。
接收方由單片機(jī)內(nèi)部嵌入的UART硬件完成,當(dāng)然也會(huì)按照同樣的協(xié)議進(jìn)行解碼。
ID:1064915 發(fā)表于 2023-6-5 10:35
wulin 發(fā)表于 2023-6-5 06:05
軟件模擬串口示例

TL1 = 0xE8; T0可以用嗎
ID:1078938 發(fā)表于 2023-6-5 10:32
大漠落日 發(fā)表于 2023-6-5 09:25
用硬件接收,看你的狀態(tài),還沒(méi)有完全搞明白串口通信與接收的采樣位關(guān)系。先用硬件串口吧,軟件要實(shí)現(xiàn)一時(shí)半 ...

就是接收部分的    TL0 = 256 - ((256 - TH0)>>1);  不理解怎么改
ID:1064915 發(fā)表于 2023-6-5 10:16
有邏輯分析儀,厲害
ID:195496 發(fā)表于 2023-6-5 09:25
用硬件接收,看你的狀態(tài),還沒(méi)有完全搞明白串口通信與接收的采樣位關(guān)系。先用硬件串口吧,軟件要實(shí)現(xiàn)一時(shí)半會(huì)你可能調(diào)試不出結(jié)果。
ID:213173 發(fā)表于 2023-6-5 06:05
哈蘭德 發(fā)表于 2023-6-4 20:48
我理解如下:
PIN_RXD是接收數(shù)據(jù)的引腳,1就是高,0就是低。
以接收 1010 0101為例子舉例。

軟件模擬串口示例
  1. #include "reg51.h"

  2. typedef unsigned char uchar;
  3. typedef unsigned int uint;

  4. sbit RXB = P3^0;         //定義UART TX/RX端口
  5. sbit TXB = P3^1;

  6. uchar TBUF,RBUF;
  7. uchar TDAT,RDAT;
  8. uchar TCNT,RCNT;
  9. uchar TBIT,RBIT;
  10. bit TING,RING;
  11. bit TEND,REND;
  12. uchar t, r;
  13. uchar buf[16];

  14. //初始UART模塊
  15. void UART_INIT()
  16. {
  17.         TING = 0;
  18.         RING = 0;
  19.         TEND = 1;
  20.         REND = 0;
  21.         TCNT = 0;
  22.         RCNT = 0;
  23.         TMOD = 0x02;   //8位自動(dòng)重載12T模式
  24.         TL1 = 0xE8;                //設(shè)定定時(shí)初值(波特率1200)
  25.         TH1 = 0xE8;                //設(shè)定定時(shí)器重裝值
  26. //        TMOD = 0x00;   // 16位自動(dòng)重載模式中的Time0
  27. //        AUXR = 0x80;   // 1T工作模式
  28. //        TL0 = BAUD;
  29. //        TH0 = BAUD>>8; // 初始Time0和設(shè)置重載值
  30.         TR0  = 1;      // tiemr0開(kāi)始運(yùn)行
  31.         ET0  = 1;      // 啟用Time0中斷
  32.         PT0  = 1;      // 提高定時(shí)中斷優(yōu)先級(jí)
  33.         EA   = 1;      // 打開(kāi)全局中斷開(kāi)關(guān)
  34. }
  35. //
  36. void main()
  37. {
  38.         UART_INIT();   //初始UART模塊
  39.         while (1)
  40.         {              //用戶功能
  41.                 if (REND)   //接收完成標(biāo)志為真
  42.                 {
  43.                         REND = 0;//接收完成標(biāo)志清0
  44.                         buf[r++ & 0x0f] = RBUF;//保存在緩存中
  45.                 }
  46.                 if (TEND)
  47.                 {
  48.                         if (t != r)
  49.                         {
  50.                                 TEND = 0;
  51.                                 TBUF = buf[t++ & 0x0f];//發(fā)送緩存中數(shù)據(jù)
  52.                                 TING = 1;
  53.                         }
  54.                 }
  55.         }
  56. }
  57. //UART定時(shí)器中斷例程
  58. void tm0() interrupt 1 using 1
  59. {
  60.         if (RING)
  61.         {
  62.                 if (--RCNT == 0)
  63.                 {
  64.                         RCNT = 3;                   //重置發(fā)送波特率計(jì)數(shù)器
  65.                         if (--RBIT == 0)
  66.                         {
  67.                                 RBUF = RDAT;            //將數(shù)據(jù)保存到RBUF
  68.                                 RING = 0;               //停止接收
  69.                                 REND = 1;               //設(shè)置接收完成標(biāo)志
  70.                         }
  71.                         else
  72.                         {
  73.                                 RDAT >>= 1;
  74.                                 if (RXB) RDAT |= 0x80;  //將RX數(shù)據(jù)轉(zhuǎn)換為RX緩沖區(qū)
  75.                         }
  76.                 }
  77.         }
  78.         else if (!RXB)
  79.         {
  80.                 RING = 1;                       //設(shè)置開(kāi)始接收標(biāo)志
  81.                 RCNT = 4;                       //初始接收波特率計(jì)數(shù)器
  82.                 RBIT = 9;                       //initial receive bit number (8 data bits + 1 stop bit)
  83.         }                                                                                          //初始接收比特?cái)?shù)(8個(gè)數(shù)據(jù)位+ 1個(gè)停止位)
  84.         if (--TCNT == 0)
  85.         {
  86.                 TCNT = 3;                       //重置發(fā)送波特率計(jì)數(shù)器
  87.                 if (TING)                       //判斷是否發(fā)送
  88.                 {
  89.                         if (TBIT == 0)
  90.                         {
  91.                                 TXB = 0;                //發(fā)送起始位
  92.                                 TDAT = TBUF;            //加載數(shù)據(jù) TBUF 到 TDAT
  93.                                 TBIT = 9;               //initial send bit number (8 data bits + 1 stop bit)
  94.                         }                                                                        //初始發(fā)送比特?cái)?shù)(8個(gè)數(shù)據(jù)位+ 1個(gè)停止位)
  95.                         else
  96.                         {
  97.                                 TDAT >>= 1;             //將數(shù)據(jù)轉(zhuǎn)換到CY
  98.                                 if (--TBIT == 0)
  99.                                 {
  100.                                         TXB = 1;
  101.                                         TING = 0;           //停止發(fā)送
  102.                                         TEND = 1;           //設(shè)置發(fā)送完成標(biāo)志
  103.                                 }
  104.                                 else
  105.                                 {
  106.                                         TXB = CY;           //將CY寫(xiě)入TX端口
  107.                                 }
  108.                         }
  109.                 }
  110.         }
  111. }
復(fù)制代碼
ID:1078938 發(fā)表于 2023-6-5 01:30
188610329 發(fā)表于 2023-6-5 00:13
你接收程序有問(wèn)題, 接收到起始位后,要 錯(cuò)位 半個(gè)時(shí)間位才能 正確收到數(shù)據(jù),即要在收到起始位后,經(jīng)過(guò)1.3~ ...

接收部分,是從每個(gè)比特位的中間部分接收的,不太理解如何從1.3-1.5接收
ID:624769 發(fā)表于 2023-6-5 00:13
你接收程序有問(wèn)題, 接收到起始位后,要 錯(cuò)位 半個(gè)時(shí)間位才能 正確收到數(shù)據(jù),即要在收到起始位后,經(jīng)過(guò)1.3~ 1.5個(gè)位 的時(shí)間后 才開(kāi)始接收 第一位數(shù)據(jù)。所以,廣泛會(huì)用 3分波特率 或4分波特率方式。
ID:1078938 發(fā)表于 2023-6-4 20:48
我理解如下:
PIN_RXD是接收數(shù)據(jù)的引腳,1就是高,0就是低。
以接收 1010 0101為例子舉例。
1 . 數(shù)據(jù)確定是從起始位開(kāi)始后,RxdBuf  = 0;
2.1  RxdBuf = 0 ,
       PIN_RXD這時(shí)候接收為高電平,RxdBuf |= 1000 0000 ===> RxdBuf = 1000 0000
2.2 PIN_RXD 接收低電平 ,RxdBuf = 0100 0000 (右移了一位)
2.3 PIN_Rxd接收高電平  , RxdBuff >>=  0010 0000  ==>1010 0000
2.4 PIN_Rxd低, RxdBuf  ==> 0101 0000
2.5 Pin_Rxd為低 , RxdBuf ==> 0010 1000
2.6 Pin_Rxd高, Rxdbuf ===>1001 0100
2.7 Pin_Rxd低,RxdBuf ===> 0100 1010
2.8 Pin_Rxd高, RxdBuf ==> 1010 0101

3.發(fā)送停止位
ID:1078938 發(fā)表于 2023-6-4 20:36
沙發(fā),詳情見(jiàn)下面回復(fù)

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

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

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