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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1721|回復(fù): 16
打印 上一主題 下一主題
收起左側(cè)

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

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1078938 發(fā)表于 2023-6-4 20:16 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
不理解邏輯。
單片機(jī)是通過010101這種的高低電平模擬二級制記錄數(shù)據(jù)的,這里是接收數(shù)據(jù)部分,PIN_RXD引腳的高低電平這里是如何控制的?

#include <reg52.h>

sbit PIN_RXD = P3^0;
sbit PIN_TXD = P3^1;

bit RxdEnd = 0;  //接收數(shù)據(jù)完成標(biāo)記位
bit RxdOrTxd = 0;   //發(fā)送 和接收狀態(tài)標(biāo)記位
unsigned char RxdBuf = 0;//接收數(shù)據(jù)緩沖區(qū)
unsigned char TxdBuf = 0;//發(fā)送數(shù)據(jù)緩沖區(qū)

void ConfigUART(unsigned int baud);
void StartRXD();
void StartTXD(unsigned char dat);

void main()
{
     EA = 1;
           ConfigUART(9600);
        
           while(1)
                 {
                   while(PIN_RXD);
                         StartRXD();
                         while(!RxdEnd);
                         StartTXD(RxdBuf+1);
                         while(!TxdEnd);
                 }
}

void ConfigUART(unsigned int baud)
{

   TMOD &= 0XF0;
         TMOD |= 0X02; //模式2 ,自動重裝模式
         TH0 = 256 - 11059200 / 12 / baud ;
         
}

void StartRXD()
{
   TL0 = 256 - ((256 - TH0)>>1);
         ET0 = 1;
         TR0 = 1;
         RxdEnd = 0;
         RxdOrTxd = 0;
}

void StartTXD(unsigned  char dat)
{

   TxdBuf = dat;
         TL0 = TH0; //發(fā)送整個數(shù)據(jù)
         ET0 = 1;
         TR0 = 1;
         PIN_TXD = 0;
         TxdEnd = 0;
         RxdOrTxd = 1;
}

void InterruptTimer0() interrupt 1
{
   static unsigned char cnt = 0;
        
         if(RxdOrTxd)
         {
            cnt ++ ;
                  if(cnt <= 8)
                        {
                           PIN _TXD = TxdBuf & 0x01;
                                 TxdBuf >>= 1;
                                 
                        }
                        else if(cnt == 9)
                        {
                          PIN _ TXD = 1;// STOP BIT
                        }
                        else
                        {
                           cnt = 0;
                                 TR0 = 0;
                                 TxdEnd = 1;
                        }
         }
         else //接收狀態(tài)
         {
            if(cnt == 0)
                        {
                           if(!PIN_RXD) // 確認(rèn)是起始位
                                 {
                                    RxdBuf = 0; //接收RxdBuf清空
                                          cnt++;
                                 }
                                 else // 不是低電平,是干擾信號
                                 {
                                    TR0 = 0; //關(guān)中斷
                                 }
                        }
                        else if(cnt <= 8)
                        {
                            RxdBuf >>= 1; //接收數(shù)據(jù)是一位一位的接收
                                  if(PIN_RXD)
                                        {
                                          RxdBuf |= 0x80;
                                        }
                                        cnt ++;
                        }
      else
                        {
                            cnt = 0;
                                  TR0 = 0;
                                  if(PIN_RXD)
                                        {
                                          RxdEnd = 1;            
                                        }
                        }                                
         }

}

對于如下的:              RxdBuf >>= 1;
                                  if(PIN_RXD)
                                        {
                                          RxdBuf |= 0x80;
                                        }
                                        cnt ++;
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:1078938 發(fā)表于 2023-6-4 20:36 | 只看該作者
沙發(fā),詳情見下面回復(fù)
回復(fù)

使用道具 舉報

板凳
ID:1078938 發(fā)表于 2023-6-4 20:48 | 只看該作者
我理解如下:
PIN_RXD是接收數(shù)據(jù)的引腳,1就是高,0就是低。
以接收 1010 0101為例子舉例。
1 . 數(shù)據(jù)確定是從起始位開始后,RxdBuf  = 0;
2.1  RxdBuf = 0 ,
       PIN_RXD這時候接收為高電平,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ā)送停止位
回復(fù)

使用道具 舉報

地板
ID:1078938 發(fā)表于 2023-6-4 21:18 | 只看該作者
為何串口發(fā)送1 ,接收81??

Snipaste_2023-06-04_21-17-35.jpg (166.51 KB, 下載次數(shù): 38)

Snipaste_2023-06-04_21-17-35.jpg
回復(fù)

使用道具 舉報

5#
ID:1078938 發(fā)表于 2023-6-4 22:16 | 只看該作者
用邏輯分析儀抓波形,數(shù)據(jù)傳輸是對的,不理解為何是81?

Snipaste_2023-06-04_22-16-04.jpg (75.74 KB, 下載次數(shù): 31)

Snipaste_2023-06-04_22-16-04.jpg
回復(fù)

使用道具 舉報

6#
ID:624769 發(fā)表于 2023-6-5 00:13 | 只看該作者
你接收程序有問題, 接收到起始位后,要 錯位 半個時間位才能 正確收到數(shù)據(jù),即要在收到起始位后,經(jīng)過1.3~ 1.5個位 的時間后 才開始接收 第一位數(shù)據(jù)。所以,廣泛會用 3分波特率 或4分波特率方式。
回復(fù)

使用道具 舉報

7#
ID:1078938 發(fā)表于 2023-6-5 00:16 | 只看該作者
但是如果使用51單片機(jī)的串口模塊,發(fā)送數(shù)據(jù)和接收數(shù)據(jù)是正確的。
#include <reg52.h>

void ConfigUART(unsigned int baud);

void main()
{
         EA = 1;
   ConfigUART(9600);
       
         while(1)
         {
          
         }
}

void ConfigUART(unsigned int baud)
{
   SCON = 0X50; //模式1  REN = 1 ,允許軟件接收
         TMOD &= 0X0F; //定時器1
         TMOD |= 0X20;//模式2
         TH1 = 256 - (11059200/12/32)/baud;
         TL1 = TH1;
         ET1 = 0; //T1只能做波特率發(fā)生器,關(guān)閉定時器1中斷
         TR1 = 1;
         ES = 1; //打開串口中斷
}

void InterruptUART() interrupt 4
{
   if(RI)
         {
           RI = 0;
                 SBUF = SBUF + 1;
         }
         if(TI)
         {
           TI = 0;
         }
}

Snipaste_2023-06-05_00-16-12.jpg (172.64 KB, 下載次數(shù): 30)

Snipaste_2023-06-05_00-16-12.jpg
回復(fù)

使用道具 舉報

8#
ID:1078938 發(fā)表于 2023-6-5 01:30 | 只看該作者
188610329 發(fā)表于 2023-6-5 00:13
你接收程序有問題, 接收到起始位后,要 錯位 半個時間位才能 正確收到數(shù)據(jù),即要在收到起始位后,經(jīng)過1.3~ ...

接收部分,是從每個比特位的中間部分接收的,不太理解如何從1.3-1.5接收
回復(fù)

使用道具 舉報

9#
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位自動重載12T模式
  24.         TL1 = 0xE8;                //設(shè)定定時初值(波特率1200)
  25.         TH1 = 0xE8;                //設(shè)定定時器重裝值
  26. //        TMOD = 0x00;   // 16位自動重載模式中的Time0
  27. //        AUXR = 0x80;   // 1T工作模式
  28. //        TL0 = BAUD;
  29. //        TH0 = BAUD>>8; // 初始Time0和設(shè)置重載值
  30.         TR0  = 1;      // tiemr0開始運行
  31.         ET0  = 1;      // 啟用Time0中斷
  32.         PT0  = 1;      // 提高定時中斷優(yōu)先級
  33.         EA   = 1;      // 打開全局中斷開關(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定時器中斷例程
  58. void tm0() interrupt 1 using 1
  59. {
  60.         if (RING)
  61.         {
  62.                 if (--RCNT == 0)
  63.                 {
  64.                         RCNT = 3;                   //重置發(fā)送波特率計數(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è)置開始接收標(biāo)志
  81.                 RCNT = 4;                       //初始接收波特率計數(shù)器
  82.                 RBIT = 9;                       //initial receive bit number (8 data bits + 1 stop bit)
  83.         }                                                                                          //初始接收比特數(shù)(8個數(shù)據(jù)位+ 1個停止位)
  84.         if (--TCNT == 0)
  85.         {
  86.                 TCNT = 3;                       //重置發(fā)送波特率計數(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ā)送比特數(shù)(8個數(shù)據(jù)位+ 1個停止位)
  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寫入TX端口
  107.                                 }
  108.                         }
  109.                 }
  110.         }
  111. }
復(fù)制代碼
回復(fù)

使用道具 舉報

10#
ID:195496 發(fā)表于 2023-6-5 09:25 | 只看該作者
用硬件接收,看你的狀態(tài),還沒有完全搞明白串口通信與接收的采樣位關(guān)系。先用硬件串口吧,軟件要實現(xiàn)一時半會你可能調(diào)試不出結(jié)果。
回復(fù)

使用道具 舉報

11#
ID:1064915 發(fā)表于 2023-6-5 10:16 | 只看該作者
有邏輯分析儀,厲害
回復(fù)

使用道具 舉報

12#
ID:1078938 發(fā)表于 2023-6-5 10:32 | 只看該作者
大漠落日 發(fā)表于 2023-6-5 09:25
用硬件接收,看你的狀態(tài),還沒有完全搞明白串口通信與接收的采樣位關(guān)系。先用硬件串口吧,軟件要實現(xiàn)一時半 ...

就是接收部分的    TL0 = 256 - ((256 - TH0)>>1);  不理解怎么改
回復(fù)

使用道具 舉報

13#
ID:1064915 發(fā)表于 2023-6-5 10:35 | 只看該作者
wulin 發(fā)表于 2023-6-5 06:05
軟件模擬串口示例

TL1 = 0xE8; T0可以用嗎
回復(fù)

使用道具 舉報

14#
ID:1078938 發(fā)表于 2023-6-5 10:39 | 只看該作者
wulin 發(fā)表于 2023-6-5 06:05
軟件模擬串口示例

確實可以,把波特率改為1200就可以。

Snipaste_2023-06-05_14-51-58.jpg (144.69 KB, 下載次數(shù): 50)

Snipaste_2023-06-05_14-51-58.jpg
回復(fù)

使用道具 舉報

15#
ID:123289 發(fā)表于 2023-6-5 10:43 | 只看該作者
【PIN_RXD引腳的高低電平這里是如何控制的?】
由發(fā)送方進(jìn)行控制。
控制的邏輯依據(jù)串行協(xié)議。
接收方由單片機(jī)內(nèi)部嵌入的UART硬件完成,當(dāng)然也會按照同樣的協(xié)議進(jìn)行解碼。
回復(fù)

使用道具 舉報

16#
ID:624769 發(fā)表于 2023-6-5 11:26 來自手機(jī) | 只看該作者
哈蘭德 發(fā)表于 2023-6-5 01:30
接收部分,是從每個比特位的中間部分接收的,不太理解如何從1.3-1.5接收

參考9樓給你的代碼,這是典型的3分波特率,每個位的間隔為3次中斷,收到起始信號時為4個時間中斷,就是從1.333的位置開始接受。
回復(fù)

使用道具 舉報

17#
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ā)送波特率計數(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è)置開始接收標(biāo)志
  22.                 RCNT = 4;                       //初始接收波特率計數(shù)器
  23.                 RBIT = 9;                       //initial receive bit number (8 data bits + 1 stop bit)
  24.         }                                                                                          //初始接收比特數(shù)(8個數(shù)據(jù)位+ 1個停止位)
復(fù)制代碼

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

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








回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久久综合精品 | 看av在线 | 亚洲欧美中文字幕在线观看 | 国产69精品久久99不卡免费版 | 在线观看亚 | 伊人春色成人 | 北条麻妃一区二区三区在线观看 | 国产在线中文 | 欧美三级三级三级爽爽爽 | 五月综合激情在线 | 一区二区av | 日本精品一区二区三区在线观看 | 污视频免费在线观看 | 国产视频中文字幕 | 亚洲免费视频播放 | 91在线视频精品 | 欧美日本一区二区 | 黄色毛片免费 | 香蕉一区| 99riav国产一区二区三区 | 美女黄网| 久久日韩粉嫩一区二区三区 | 高清亚洲 | 免费一区在线 | 日韩精品在线一区 | 在线中文字幕视频 | 日韩视频一区二区三区 | 99pao成人国产永久免费视频 | 九九伦理电影 | 在线日韩欧美 | 一区中文 | 99久久99热这里只有精品 | 亚洲在线看| 国产精品成人一区二区 | 国产精品一区二区三区99 | 国产成人99久久亚洲综合精品 | 欧美一级淫片免费视频黄 | 99re99| 亚洲免费在线视频 | 国产免费一区 | 午夜视频在线免费观看 |