那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

掌握串口通信協議的收發過程

GReq_mcu168 ? 2017-12-22 10:02 ? 次閱讀

(3)、發送秩序。低位先發。(4)、波特率。收發雙方共同約定的一個數據位(0或1)在數據傳輸線上維持的時間。也可理解為每秒可以傳輸的位數。常用的波特率有300bit/s, 600bit/s, 2400bit/s, 4800bit/s, 9600bit/s。(5)、通信的起始信號。發送方在沒有發送數據時,應該將Tx置1 。 當需發送時,先將Tx置0,并且保持1位的時間。接受方不斷地偵測Rx,如果發現Rx常時間變高后,突然被拉低(置為0),則視為發送方將要發送數據,迅速啟動自己的定時器,從而保證了收發雙方定時器同步定時。

(6)、停止信號。發送方發送完最后一個有效位時,必須再將Tx保持1位的時間,即為停止位。

掌握串口通信協議的收發過程

好了,理論暫時到這里,現在我們要做一個實驗,將一個字節從51單片機發送到電腦串口調試助手上。這個實驗的目的是為了掌握串口通信協議的收發過程。

虛擬串口

實驗一、虛擬串口實驗

一般單片機都有專門的串口引腳,51里面分別是P3.0和P3.1,這些引腳擁有串口的硬件電路,因此使用它們并不需要設置信號的發送停止。為了掌握協議,我們使用其他的引腳來模擬串口,所以也叫虛擬串口。這里我們選用P1.0,然而注意到我們51單片機要發送數據給電腦,必須經過一個串口轉USB設備(即TTL電平轉換為RS232電平),而限于我們的開發板只有P3.0與P3.1連接到了串口轉USB設備,所以我們可以將P1.0短接到P3.1 。 下圖是這個串口轉USB的原理圖。

掌握串口通信協議的收發過程

好了直接上代碼吧。

[cpp]view plaincopy

  1. #include"reg51.h"

  2. /*

  3. 將P1.0虛擬成串口發送腳TX

  4. 以9600bit/s的比特率向外發送數據

  5. 因為波特率是9600bit/s

  6. 所以me發送一位的時間是t=1000000us/9600=104us

  7. */

  8. sbitTX=P3^1;//P1^0outputTTLsignal,needtotransferredtors232signal,canbeconnectedtoP3^1

  9. #defineu16unsignedint//宏定義

  10. #defineu8unsignedchar

  11. u8sbuf;

  12. bitti=0;

  13. voiddelay(u16x)

  14. {

  15. while(x--);

  16. }

  17. voidTimer0_Init()

  18. {

  19. TMOD|=0x01;

  20. TH0=65440/256;

  21. TH0=65440%256;

  22. TR0=0;

  23. }

  24. voidIsr_Init()

  25. {

  26. EA=1;

  27. ET0=1;

  28. }

  29. voidSend_Byte(u8dat)

  30. {

  31. sbuf=dat;//通過引入全局變量sbuf,可以保存形參dat

  32. TX=0;//A起始位

  33. TR0=1;

  34. while(ti==0);//等待發送完成

  35. ti=0;//清除發送完成標志

  36. }

  37. voidTF0_isr()interrupt1//每104us進入一次中斷

  38. {

  39. staticu8i;//記錄進入中斷的次數

  40. TH0=65440/256;

  41. TL0=65440%256;

  42. i++;

  43. if(i>=1&&i<=8)??

  44. {

  45. if((sbuf&(1<<(i-1)))==0)??//?(sbuf&(1<<(i-1)))表示取出i-1位??

  46. {

  47. TX=0;

  48. }

  49. else

  50. {

  51. TX=1;

  52. }

  53. }

  54. if(i==9)//停止位

  55. {

  56. TX=1;

  57. }

  58. if(i==10)

  59. {

  60. TR0=0;

  61. i=0;

  62. ti=1;//發送完成

  63. }

  64. }

  65. voidmain()

  66. {

  67. TX=1;//使TX處于空閑狀態

  68. Timer0_Init();

  69. Isr_Init();

  70. while(1)

  71. {

  72. Send_Byte(65);//0x41

  73. delay(60000);

  74. }

  75. }

實驗引入了定時器0來控制發送線上的各個位的保持時間。首先main函數進入,TX置1則使發送線處于空閑,這時候發送方和接受方都處于空閑。接下來初始化定時器0,TR0置0表示還不要啟動定時器0。接著中斷系統初始化,此時中斷系統已經開啟。進入while循環,先進Send_Byte()函數,將65傳給形參dat,dat再將65賦值給sbuf,到這里準備工作就做好了。接著TX置0,這個是起始位,要保持這個起始位104us。于是就啟動定時器TR0置1,計時器開始計數。當第一次溢出的時候,也就是過了104us,進入中斷,同時接收方也偵測到了這個突然被拉低的信號,于是迅速啟動自己的定時器。進入中斷子函數后,先是重裝定時器初值,然后i加1,也就是當i=1時,就應該發送數據的最低位了,總共有8位數據,所以使用條件語句if(i>=1 && i<=8)來判斷是否發送完數據位。然后再通過if(i==9) 來發送停止位,最后當i=10時,也就是發送完了,這時候要關閉定時器(那么程序也就),同時i置0,ti置1(才能跳出while(ti==0)循環),最后將ti置0,保證下次要發送字節時讓程序停留在while(ti==0)。

片上串口

以上說的是虛擬串口,上文中談到與串口相關的引腳P3.0與P3.1,事實上51單片機自帶片上串口,那這個串口又該怎么使用呢?

片上串口支持同步模式與異步模式。簡單來說同步模式就是指有時鐘線,而異步模式無時鐘線。這里的時鐘線是指在同步通信時,用一根線專門傳輸時鐘信號,這個信號用來與要發送的每一位保持同步,這樣就避免了例如異步通信中因為采用定時器而引入的時間誤差。

片上串口還支持8位模式和9位模式。如下圖所示

掌握串口通信協議的收發過程

其中D0-D7是一個字節的8個位。9位模式只是多了一個位TB8,這個TB8的作用是奇偶校驗或多機通信。奇偶校驗原理這不加分析。多機通信時比如主機只發送數據給網絡中的一臺地址為0x02的設備,這時候先讓TB8為1,前面的D0-D7則為地址即0x02,之后再讓TB8為0,前面的D0-D7則為數據了。

上面設置了片上串口的模式,另外還要設置串口的波特率。

片上串口的波特率等于定時器1工作在方式2時溢出率的32分頻。如果要定時器1工作在方式2,那么TMOD=0x20。另外要保證為32分頻,我們還必須設置計數器初值。設晶振為11.0592Mhz,則定時器的計數脈沖為F=f/12,則定時器每計一個脈沖的時間為T=12/f。又令計數器的起點為x,則溢出一次要計的脈沖數為(256-x)。所以在計數起點為x時,溢出一次的時間為t=12/f*(256-x)。則對應的溢出率為1/t=f/(12*(256-x))。對應的波特率就為b=f/(384*(256-x))。

x=256-f/(384*b)

其中f為晶振頻率,b為希望的波特率,x為定時器的計數起點TH1的值。

例如當晶振為11.0592M,希望波特率為9600bit/s,則TH1=253。題外話,我們同樣可以演算出在其他常用波特率情況下,TH1始終為一個整數。這里也就解釋了為什么51里面選用了11.0592M的晶振而不是12M,這樣就保證了串口的時序更加準確,雖然犧牲了定時器的準確度。

實驗二,片外串口發送一個字節。

好了現在開始我們的實驗之旅。直接看代碼吧。

[cpp]view plaincopy

  1. #include"reg51.h"

  2. #defineu16unsignedint

  3. #defineu8unsignedchar

  4. voiddelay(u16x)

  5. {

  6. while(x--);

  7. }

  8. voidUart_Init()//串口初始化

  9. {

  10. SCON=0x50;//8位異步模式

  11. TMOD|=0x20;//定時器1工作方式2

  12. TH1=253;//9600bit/s

  13. TR1=1;

  14. }

  15. voidSend_Byte(u8dat)

  16. {

  17. SBUF=dat;//啟動發送,只需要把發送內容給SBUF這個寄存器

  18. while(TI==0);//等待發送完成,因為TI為1時表示在發送停止位

  19. TI=0;

  20. }

  21. voidmain()

  22. {

  23. Uart_Init();

  24. while(1)

  25. {

  26. Send_Byte('m');

  27. delay(60000);

  28. }

  29. }

實驗二較之實驗一,代碼減少了很多,而且不用考慮繁瑣的位發送時序。只需要明白各個寄存器SCON,TMOD,TCON,SBUF的用法。TI是SCON中的第一位,為發送中斷請求標志位。在本方式中,在停止位開始發送時由內部硬件置位,響應中斷后TI必須又軟件清零。

實驗三、片上串口發送一個字符串

上面介紹了如何發送一個字節,那如何發送一個字符串甚至文本呢?這里我們首先介紹下字符串的概念。

字符串:從存儲器的某個地址開始,連續存放多個字符的ASCII碼,并且在最后一個字符的后面存放一個0,這段連續的內存空間就叫字符串,最后的0叫字符串的結束符。注意這里的0和加單引號的0不是一個概念,加單引號的0是指0的ASCII碼。

數組與字符串的關系:字符串是數組的一種特殊情況,數組在特定條件下可當做字符串用。C語言用雙引號描述一個字符串,如“abcd”。

下面我們通過一個實驗來展示如何發送字符串。我們實驗的目標是打印字符串“Hello World ! 第一!”到打印機。直接上代碼。

[cpp]view plaincopy

  1. #include"reg51.h"

  2. #defineu16unsignedint

  3. #defineu8unsignedchar

  4. voiddelay(u16x)

  5. {

  6. while(x--);

  7. }

  8. voidUart_Init()//串口初始化

  9. {

  10. SCON=0x50;//8位異步模式

  11. TMOD|=0x20;//定時器1工作方式2

  12. TH1=253;//9600bit/s

  13. TR1=1;

  14. }

  15. voidSend_Byte(u8dat)//串口發送一個字節

  16. {

  17. SBUF=dat;//啟動發送,只需要把發送內容給SBUF這個寄存器

  18. while(TI==0);//等待發送完成,因為TI為1時表示在發送停止位

  19. TI=0;

  20. }

  21. voidSend_String(u8*str)//發送一個字符串*str為字符串第一個字符的地址

  22. {

  23. abc://標號

  24. if(*str!=0)

  25. {

  26. Send_Byte(*str);

  27. str++;

  28. gotoabc;

  29. }

  30. }

  31. voidmain()

  32. {

  33. Uart_Init();

  34. while(1)

  35. {

  36. Send_String("HelloWorld!第一!");

  37. Send_Byte(10);

  38. delay(60000);

  39. delay(60000);

  40. }

  41. }


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6043

    文章

    44622

    瀏覽量

    638527
  • 串口通信
    +關注

    關注

    34

    文章

    1627

    瀏覽量

    55727

原文標題:單片機C語言之串口通信協議

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    通用異步收發傳輸器UART串口通信協議有哪些特性呢

    什么是通用異步收發傳輸器UART呢?通用異步收發傳輸器UART串口通信協議有哪些特性呢?
    發表于 11-01 07:03

    單線串口通信協議

    單線串口通信協議如下:需要發送的數據幀:
    發表于 12-07 08:16

    掌握通信協議的研究方法

    從根本出發,從簡單開始,逐步加碼,從而讓你徹底掌握通信協議的研究方法。就是串口uart,因為uart只有物理層,尤其是TTL電平的uart,就是個很簡單很直觀的物理層協議。你可以通過學
    發表于 01-13 06:09

    什么是串口通信串口通信協議了解

    行傳輸低。2、串口通信協議在計算機科學里,大部分復雜的問題都可以通過分層來簡化。如芯片被分為內核層和片上外設;STM32標準庫則是在寄存器與用戶代碼之間的軟件層。對于通訊協議,我們也以分層的方式來理解,最基本的是把它分為物理層和
    發表于 02-15 06:54

    SPI通信協議通信過程是怎樣的?

    SPI通信協議通信過程是怎樣的?
    發表于 02-17 06:52

    串口通信協議的相關資料分享

    的建立三、建立STM32與PC之間的通信基礎1、串口助手的使用2、效果呈現一、串口通信協議1、UART簡介嵌入式開發中,UART串口
    發表于 02-22 07:16

    串口通信協議詳解

    串口是計算機上一種非常通用設備通信協議。大多數計算機包含兩個基于RS232的串口串口同時也是儀器儀表設備通用的
    發表于 11-09 14:51 ?8725次閱讀

    基于狀態機的串口通信協議的設計與實現

    設計并實現了一種基于狀態機的串口通信協議,并將此協議應用到稱重儀表的上位機通信中。本文介紹了串口通信協議
    發表于 05-08 15:22 ?169次下載
    基于狀態機的<b class='flag-5'>串口</b><b class='flag-5'>通信協議</b>的設計與實現

    PC與單片機串口通信協議

    PC與單片機串口通信協議
    發表于 12-26 22:12 ?0次下載

    科爾摩根伺服驅動器串口通信協議

    科爾摩根伺服驅動器串口通信協議
    發表于 09-03 09:30 ?24次下載
    科爾摩根伺服驅動器<b class='flag-5'>串口</b><b class='flag-5'>通信協議</b>

    單片機C語言之串口通信協議

    本文首先介紹了串口的基本結構,其次介紹了串口通信方式,最后詳細介紹了單片機C語言之串口通信協議
    發表于 05-22 12:37 ?4971次閱讀
    單片機C語言之<b class='flag-5'>串口</b><b class='flag-5'>通信協議</b>

    西門子PLC串口協議與以太網通信協議對比

    西門子plc品牌眾多,通信協議的類型就更多了,具體可分為串口協議和以太網通信協議兩大類。 串口協議
    發表于 12-30 09:13 ?1639次閱讀
    西門子PLC<b class='flag-5'>串口</b><b class='flag-5'>協議</b>與以太網<b class='flag-5'>通信協議</b>對比

    UART串口通信協議是什么?

    UART (Universal Asynchronous Receiver/Transmitter) 是一種通信接口協議,用于實現串口通信。它是一種簡單的、可靠的、廣泛應用的
    的頭像 發表于 03-19 17:26 ?1546次閱讀

    串口通信協議解析 串口通信應用實例

    串口通信協議解析 串口通信協議是指規定了數據包的內容,內容包含了起始位、主體數據、校驗位及停止位,雙方需要約定一致的數據包格式才能正常收發
    的頭像 發表于 11-21 17:03 ?709次閱讀

    常見串口通信協議 如何設置串口參數

    串口通信是一種常見的通信方式,廣泛應用于計算機、嵌入式系統和各種電子設備之間。串口通信協議主要是指在串行
    的頭像 發表于 12-27 09:51 ?707次閱讀
    博网百家乐官网现金网| 大发888手机版下载安装| 百家乐博百家乐的玩法技巧和规则| 威尼斯人娱乐城骗子| 大发888下载 客户端| 瑞丰娱乐城| 爱博彩| 百家乐官网视频游戏会员| 澳门百家乐官网必赢技巧| 百家乐如何看面| 百家乐全部规| 大发888体育注册| 岢岚县| 百家乐官网侧牌器| 7人百家乐桌子| 大发888代理| 汪清县| 百家乐官网游戏打水| 现场百家乐平台源码| 百家乐那个平台信誉高| 水果机技巧规律| 百家乐官网投注开户| 大都会百家乐官网的玩法技巧和规则 | 新利网上娱乐| 百家乐官网巴厘岛上海在线| 百家乐庄家抽水| 百家乐正品地址| 太阳城官方网站| 百家乐官网的规则博彩正网 | 太阳城百家乐网址--| 德州扑克教学| 百家乐官网犯法| 百家乐龙虎台布| 百家乐官网如何破解| 云鼎百家乐官网代理| 太阳城菲律宾官网| 太阳城百家乐官网娱乐开户| 百家乐赢钱心得| 鸿运国际娱乐| 百家乐官网黏土筹码| 太阳城网上版|