單片機IO口模仿UART串口通訊

爲了讓人人充沛瞭解 UART 串口通訊的道理,我們先把 P3.0 和 P3.1 當做 IO 口來停止模仿實踐串口通訊的進程,道理搞懂後,我們再運用存放器設置裝備擺設完成串口通訊進程。
關於 UART 串口波特率,常用的值是 300、600、1200、2400、4800、9600、14400、19200、28800、38400、57600、115200 等速度。IO 口模仿 UART 串行通訊程序是一個複雜的演示程序,我們運用串口調試助手下發一個數據,數據加 1 後,再主動前往。
串口調試助手,這裏我們直接運用 STC-ISP 軟件自帶的串口調試助手,先把串口調試助手的運用給人人說一下,如圖 11-6 所示。第一步要選擇串口助手菜單,第二步選擇十六進制顯示,第三步選擇十六進制發送,第四步選擇 COM 口,這個 COM 口要和本人電腦裝備治理器裏的誰人 COM 口分歧,波特率按我們程序設定好的選擇,我們程序中讓一個數據位繼續工夫是 1/9600 秒,那這個中央選擇波特率就是選 9600,校驗位選 N,數據位 8,中止位 1。

圖 11-6 串口調試助手錶示圖
圖 11-6   串口調試助手錶示圖


串口調試助手的本質就是應用電腦上的 UART 通訊接口,發送數據給我們的單片機,也可以把我們的單片機發送的數據接納到這個調試助手界面上。
由於首次接觸通訊方面的技巧,所以我把前面的 IO 模仿串口通訊程序停止一下說明,人人可以邊看我的說明邊看程序,把底層道理先徹底弄懂。
變量界說局部就不必說了,直接看 main 主函數。起首是對通訊的波特率的設定,在這裏我們設置裝備擺設的波特率是 9600,那麼串口調試助手也得是 9600。設置裝備擺設波特率的時分,我們用的是準時器 T0 的形式 2。形式 2 中,不再是 TH0 代表高 8 位,TL0 代表低 8 位了,而只要TL0 在停止計數,當 TL0 溢出後,不只僅會讓 TF0 變 1,並且還會將 TH0 中的內容從新主動裝到 TL0 中。如許有一個益處,就是我們可以把想要的準時器初值提早存在 TH0 中,當 TL0溢出後,TH0 主動把初值就從新送入 TL0 了,全主動的,不需求程序中再給 TL0 從新賦值了,設置裝備擺設方法很複雜,人人可以本人看下程序而且盤算一下初值。
波特率設置好今後,翻開中綴,然後等候接納串口調試助手下發的數據。接納數據的時分,起首要停止低電平檢測 while (PIN_RXD),若沒有低電平則闡明沒無數據,一旦檢測到低電平,就進入啓動接納函數 StartRXD()。接納函數最開端啓動半個波特率週期,初學能夠這裏不是很明確。人人回頭看一下我們的圖 11-2 裏邊的串口數據表示圖,假如在數據位電平變更的時分去讀取,由於時序上的誤差以及旌旗燈號波動性的成績很輕易讀錯數據,所以我們願望在旌旗燈號最波動的時分去讀數據。除了旌旗燈號變更的誰人沿的地位外,其它地位都很波動,那麼我們如今就商定在旌旗燈號兩頭地位去讀取電平形態,如許可以包管我們讀的必定是準確的。
一旦讀到了肇端旌旗燈號,我們就把以後形態設定成接納形態,而且翻開準時器中綴,第一次是半個週期進入中綴後,對肇端位停止二次判別一下,確認一下肇端位是低電平,而不是一個攪擾旌旗燈號。今後每經由 1/9600 秒進入一次中綴,而且把這個引腳的形態讀到 RxdBuf 裏邊。等候接納終了之後,我們再把這個 RxdBuf 加 1,再經過 TXD 引腳發送出去,異樣需求先發一位肇端位,然後發 8 個數據位,再發完畢位,發送終了後,程序運轉到 while (PIN_RXD),等候第二輪旌旗燈號接納的開端。

純文本複製
			#include <reg52.h> sbit PIN_RXD = P3^0; //接納引腳界說 sbit PIN_TXD = P3^1; //發送引腳界說 bit RxdOrTxd = 0; //指導以後形態爲接納照樣發送 bit RxdEnd = 0; //接納完畢標記 bit TxdEnd = 0; //發送完畢標記 unsigned char RxdBuf = 0; //接納緩衝器 unsigned char TxdBuf = 0; //發送緩衝器 void ConfigUART(unsigned int baud); void StartTXD(unsigned char dat); void StartRXD(); void main(){ EA = 1; //開總中綴 ConfigUART(9600); while (1){ //設置裝備擺設波特率爲 9600 while (PIN_RXD); //等候接納引腳呈現低電平,即肇端位 StartRXD(); //啓動接納 while (!RxdEnd); //等候接納完成 StartTXD(RxdBuf+1); //接納到的數據+1 後,發送歸去 while (!TxdEnd); //等候發送完成 } } /* 串口設置裝備擺設函數,baud-通訊波特率 */ void ConfigUART(unsigned int baud){ TMOD &= 0xF0; //清零 T0 的掌握位 TMOD |= 0x02; //設置裝備擺設 T0 爲形式 2 TH0 = 256 - (11059200/12)/baud; //盤算 T0 重載值 } /* 啓動串行接納 */ void StartRXD(){ TL0 = 256 - ((256-TH0)>>1); //接納啓動時的 T0 準時爲半個波特率週期 ET0 = 1; //使能 T0 中綴 TR0 = 1; //啓動 T0 RxdEnd = 0; //清零接納完畢標記 RxdOrTxd = 0; //設置以後形態爲接納 } /* 啓動串行發送,dat-待發送字節數據 */ void StartTXD(unsigned char dat){ TxdBuf = dat; //待發送數據保管到發送緩衝器 TL0 = TH0; //T0 計數初值爲重載值 ET0 = 1; //使能 T0 中綴 TR0 = 1; //啓動 T0 PIN_TXD = 0; //發送肇端位 TxdEnd = 0; //清零發送完畢標記 RxdOrTxd = 1; //設置以後形態爲發送 } /* T0 中綴效勞函數,處置串行發送和接納 */ void InterruptTimer0() interrupt 1{ static unsigned char cnt = 0; //位接納或發送計數 if (RxdOrTxd){ //串行發送處置 cnt++; if (cnt <= 8){ //低位在先順次發送 8bit 數據位 PIN_TXD = TxdBuf & 0x01; TxdBuf >>= 1; }else if (cnt == 9){ //發送中止位 PIN_TXD = 1; }else{ //發送完畢 cnt = 0; //復位 bit 計數器 TR0 = 0; //封閉 T0 TxdEnd = 1; //置發送完畢標記 } }else{ //串行接納處置 if (cnt == 0){ //處置肇端位 if (!PIN_RXD){ //肇端位爲 0 時,清零接納緩衝器,預備接納數據位 RxdBuf = 0; cnt++; } }else{ //肇端位不爲 0 時,中斷接納 TR0 = 0; //封閉 T0 }else if (cnt <= 8){ //處置 8 位數據位 RxdBuf >>= 1; //低位在先,所以將之前接納的位向右移 //接納腳爲 1 時,緩衝器最高地位 1, //而爲 0 時不處置即仍堅持移位後的 0 if (PIN_RXD){ RxdBuf |= 0x80; } cnt++; }else{ //中止位處置 cnt = 0; //復位 bit 計數器 TR0 = 0; //封閉 T0 if (PIN_RXD){ //中止位爲 1 時,方能以爲數據無效 RxdEnd = 1; //置接納完畢標記 } } } }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章