溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

單片機(jī)IO口模仿UART串口通訊

發(fā)布時(shí)間:2020-06-01 21:53:15 來源:網(wǎng)絡(luò) 閱讀:1150 作者:yuw2018 欄目:網(wǎng)絡(luò)安全

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

單片機(jī)IO口模仿UART串口通訊
圖 11-6   串口調(diào)試助手表示圖


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

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


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI