在講解本章的內(nèi)容之前請(qǐng)大家先反復(fù)閱讀《手把手教你學(xué)51單片機(jī)》文檔的第11章內(nèi)容,很多概念文檔都已詳細(xì)講解有。
1.波特率
串口通信就是單片機(jī)與電腦端,單片機(jī)與單片機(jī),單片機(jī)與模塊器件之間互發(fā)信息進(jìn)行通信,比如單片機(jī)發(fā)送一個(gè)“1”的字符給電腦端,電腦端的窗口就會(huì)接收到“1”。我們常用的波特率為9600,所謂9600指的是一秒鐘單片機(jī)可以發(fā)送9600個(gè)數(shù)據(jù)位,也就是1秒鐘的時(shí)間里單片機(jī)可以發(fā)送(9600/8)=1200字節(jié)。
如果我們想發(fā)送一個(gè)字符“A”給電腦端的窗口,那么字符“A”對(duì)應(yīng)的ASCII值就是65,二進(jìn)制表示為01000001。
2.通信引腳
單片機(jī)的P3.1是發(fā)送引腳,也就是說(shuō)要發(fā)送字符“A”,這個(gè)引腳的變化如下圖所示
單片機(jī)要發(fā)送一個(gè)字節(jié)給電腦端,首先發(fā)送引腳需要先拉高,然后拉低持續(xù)(1/9600)秒,電腦端檢測(cè)到這個(gè)低電平信號(hào)就會(huì)準(zhǔn)備接收數(shù)據(jù)字節(jié)。然后我們要發(fā)送的二進(jìn)制位是01000001,但是串口通信發(fā)送的字節(jié)是低位在前,高位在后,所以上圖的發(fā)送順序就是01000001反過(guò)來(lái)為10000010。一個(gè)字節(jié)發(fā)送完成之后還要發(fā)送一個(gè)停止位1,電腦端接收到這個(gè)停止位就認(rèn)為一個(gè)字節(jié)發(fā)送完成了。
我們用定時(shí)器來(lái)實(shí)現(xiàn)引腳的持續(xù)時(shí)間,怎么定時(shí)(1/9600)秒怎么設(shè)置,計(jì)算一下就可以了
(1/9600)=X*(12/11059200)
解得X=96。
因?yàn)槎〞r(shí)時(shí)間間隔比較短,所以我們使用定時(shí)器0的工作模式2就可以了。填充TH0的初始值就是256-96=160=0xA0。
因?yàn)镻3.1在“#include<reg52.h>”已有定義為TXD,我們直接用即可。通過(guò)按K4來(lái)啟動(dòng)發(fā)送字節(jié)數(shù)據(jù)。
3.代碼
#include <reg52.h> #include <function.h>//詳見第六章第8講 #include <timer.h> //詳見第八章第11講 void TIM0_Mode2_Init() { TMOD&=0xF0; //清0低四位 TMOD|=0x02; //設(shè)置定時(shí)器0為工作模式2 TH0 = 0xA0; //計(jì)算出波特率9600 TL0 = 0xA0; ET0 = 1; //閉合定時(shí)器0中斷的開關(guān) TR0 = 1; //啟動(dòng)定時(shí)器0 } void main() { u8 key; LED_Init(); //初始化LED硬件模塊 KEY_Init(); //初始化按鍵模塊 EA = 1; //閉合總中斷開關(guān) TIM0_Mode2_Init(); //定時(shí)(1/9600)秒 TR0 = 0; //先關(guān)閉定時(shí)器 while(1) { key=KEY_Scan(0,1000); if(key==4)TR0 = 1;//開啟定時(shí)器啟動(dòng)一次字節(jié)傳輸,按一次發(fā)送一次。 } } void TIM0_IRQHandler() interrupt 1 { static u8 cnt=0,i,TXDBUF=65; //字符“A”的ASCII值為65 cnt++; //cnt一直在1~10之間變化 if(cnt==1)TXD=0; //cnt變?yōu)?,發(fā)送起始位,這次的中斷函數(shù)就執(zhí)行完了,持續(xù)夠(1/9600)秒之后,再次進(jìn)入中斷函數(shù),然后就是進(jìn)入發(fā)送數(shù)據(jù)字節(jié)的8位的任務(wù) if (cnt>=2 && cnt<=9) //發(fā)送8位數(shù)據(jù)位,從低位開始引腳的變化為 1 0 0 0 0 0 1 0 { TXD = TXDBUF & 0x01; //“TXDBUF & 0x01”的表達(dá)式就是,要么等于1要么等于0,這樣P3.1的引腳要么保持高電平,要么保持低電平 TXDBUF >>= 1; } if (cnt == 10) { TXD = 1; //發(fā)送停止位 TR0 = 0; //關(guān)閉定時(shí)器,結(jié)束一次字節(jié)傳輸 cnt=0; i++; TXDBUF=65+i; //下次按按鍵發(fā)送的是 B C D E··· } }
大家可能對(duì)中斷函數(shù)里的內(nèi)容感到艱澀難度,這里簡(jiǎn)單說(shuō)明一下,我們按下K4啟動(dòng)了定時(shí)器,然后第一次進(jìn)入中斷函數(shù)時(shí),做的任務(wù)就是拉低P3.1,然后這次的中斷函數(shù)的任務(wù)就結(jié)束了,等過(guò)了(1/9600)秒之后,再次進(jìn)入中斷函數(shù),上一次拉低P3.1的時(shí)間已經(jīng)持續(xù)夠(1/9600)秒了,這第二次的中斷函數(shù)任務(wù)就是拉高P3.1,因?yàn)榘l(fā)送字符A這個(gè)字節(jié)的最低位為1,持續(xù)夠(1/9600)秒進(jìn)入第三次執(zhí)行中斷函數(shù),拉低P3.1,第四,第五,第六,第七都是拉低P3.1發(fā)送0,以此類推,到第10次中斷函數(shù)執(zhí)行就是拉高P3.1發(fā)送停止位,關(guān)閉定時(shí)器結(jié)束一次字節(jié)的傳輸,要想再次發(fā)送需要按K4啟動(dòng)定時(shí)器,“TXDBUF=65+i;
”表示下次發(fā)送的是66這個(gè)數(shù)據(jù),再下次就是發(fā)送67······
4.軟件設(shè)置
在軟件界面選擇串口助手,選用字符格式顯示,查看波特率是否為9600,最后點(diǎn)擊“打開串口”。
不斷地間隔按K4,就會(huì)看到電腦端顯示出單片機(jī)發(fā)送過(guò)來(lái)的字符數(shù)據(jù)
C語(yǔ)言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:
一點(diǎn)編程也不會(huì)寫的:零基礎(chǔ)C語(yǔ)言學(xué)練課程
解決困擾你多年的C語(yǔ)言疑難雜癥特性的C語(yǔ)言進(jìn)階課程
從零到寫出一個(gè)爬蟲的Python編程課程
只會(huì)語(yǔ)法寫不出代碼?手把手帶你寫100個(gè)編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程