前言
人類生存于世,少不了溝通。溝通使人類互相認(rèn)知,傳遞信息,提升生活品質(zhì)。但然單片機(jī)也需要,不然單單一個(gè)機(jī)器,無(wú)法構(gòu)成一個(gè)系統(tǒng),發(fā)揮更大的力量。只有單片機(jī)與外圍設(shè)備傳遞信息,互相反饋才會(huì)有一個(gè)完美的系統(tǒng)。串行口通信就被發(fā)明出來(lái),下面來(lái)了解串行口通信(uart)。
幾個(gè)概念
為了能更好理解串行口通信,在介紹它之前,先來(lái)看看幾個(gè)概念,補(bǔ)充知識(shí),方便深入明白u(yù)art工作原理。
通信方式
通信方式
通信方式有兩種,分別是并行通信和串行通信。
并行通信:并行是指多比特?cái)?shù)據(jù)同時(shí)通過(guò)并行線進(jìn)行傳送,這樣數(shù)據(jù)傳送速度大大提高,但并行傳送的線路長(zhǎng)度受到限制,因?yàn)殚L(zhǎng)度增加,干擾就會(huì)增加,數(shù)據(jù)也就容易出錯(cuò)。
串行通信:串行通信是指 使用一條數(shù)據(jù)線,將數(shù)據(jù)一位一位地依次傳輸,每一位數(shù)據(jù)占據(jù)一個(gè)固定的時(shí)間長(zhǎng)度。其只需要少數(shù)幾條線就可以在系統(tǒng)間交換信息,特別適用于計(jì)算機(jī)與計(jì)算機(jī)、計(jì)算機(jī)與外設(shè)之間的遠(yuǎn)距離通信。
拿汽車通道來(lái)說(shuō),并行通信就是多車道,多輛車一起行駛,而串行通信就是單車道,只能一輛一輛車通過(guò)。
串行通信制式
串行通信制式
串行通信制式有單工通信,半雙工通信,雙工通信三種。
單工通信:?jiǎn)喂ねㄐ判诺朗菃蜗蛐诺?,發(fā)送端和接收端的身份是固定的,發(fā)送端只能發(fā)送信息,不能接收信息;接收端只能接收信息,不能發(fā)送信息,數(shù)據(jù)信號(hào)僅從一端傳送到另一端,即信息流是單方向的。
半雙工通信:半雙工數(shù)據(jù)傳輸指數(shù)據(jù)可以在一個(gè)信號(hào)載體的兩個(gè)方向上傳輸,但是不能同時(shí)傳輸。例如,在一個(gè)局域網(wǎng)上使用具有半雙工傳輸?shù)募夹g(shù),一個(gè)工作站可以在線上發(fā)送數(shù)據(jù),然后立即在線上接收數(shù)據(jù),這些數(shù)據(jù)來(lái)自數(shù)據(jù)剛剛傳輸?shù)姆较?。像全雙工傳輸一樣,半雙工包含一個(gè)雙向線路(線路可以在兩個(gè)方向上傳遞數(shù)據(jù))。
雙工通信:雙工通信是指在同一時(shí)刻信息可以進(jìn)行雙向傳輸,和打電話一樣,說(shuō)的同時(shí)也能聽(tīng),邊說(shuō)邊聽(tīng)。這種發(fā)射機(jī)和接收機(jī)分別在兩個(gè)不同的頻率上(兩個(gè)頻率差有一定要求)能同時(shí)進(jìn)行工作的雙工機(jī)也稱為異頻雙工機(jī)。
三種通信制式很容易理解,對(duì)照上圖看,單工通信不就是單方面通信,只能發(fā)出指令或接收指令。半雙工通信就是能接收又能發(fā)送,但是不能同時(shí)進(jìn)行。雙工就最厲害,可以同時(shí)發(fā)送和接收指令。
串行通信分類
串行通信有兩種,一位異步串行通信,二為同步串行通信。
異步串行通信:異步串行通信是指通信雙方以一個(gè)字符(包括特定附加位)作為數(shù)據(jù)傳輸單位且發(fā)送方傳送字符的間隔時(shí)間不一定,具有不規(guī)則數(shù)據(jù)段傳送特性的串行數(shù)據(jù)傳輸。
同步串行通信:所謂同步通信是指在約定的通信速率下,發(fā)送端和接收端的時(shí)鐘信號(hào)頻率和相位始終保持一致(同步),這就保證了通信雙方在發(fā)送和接收數(shù)據(jù)時(shí)具有完全一致的定時(shí)關(guān)系。
兩種串行通信不同就只有時(shí)間,在發(fā)送字符時(shí),異步可以是不同時(shí)間間隔發(fā)送,但同步只能以固定的時(shí)間間隔發(fā)送。
波特率
波特率:波特率表示每秒鐘傳送的二進(jìn)制位數(shù),是衡量數(shù)據(jù)傳送速率的指標(biāo),它用單位時(shí)間內(nèi)載波調(diào)制狀態(tài)改變的次數(shù)來(lái)表示。
相互通信的甲乙雙方必須具有相同的波特率,不然無(wú)法成功完成串行通信。
概述
52單片機(jī)具有一個(gè)全雙工串行通信口。一個(gè)全雙工UART(通用異步接收發(fā)送器)的串行I/O口,用于實(shí)現(xiàn)單片機(jī)之間或單片機(jī)與微機(jī)之間的串行通信;片內(nèi)振蕩器和時(shí)鐘產(chǎn)生電路,石英晶體和微調(diào)電容需要外接。最佳振蕩頻率為6M—12M。管腳RXD( P3.0),TXD(P3.1)與串口通信有關(guān)。波特率可以設(shè)置。
內(nèi)部結(jié)構(gòu)
串行口內(nèi)部結(jié)構(gòu)邏輯圖
串行口通信與三個(gè)寄存器有關(guān),分別是:
?1.?PCON寄存器
?2.?SCON寄存器
?3.?SBUF特殊功能寄存器
寄存器
PCON電源管理寄存器
電源管理寄存器
SMOD:該位與串口通信有關(guān)。
SMOD=0; 串口方式1,2,3時(shí),波特率正常。
SMOD=1; 串口方式1,2,3時(shí),波特率加倍。
LVDF:低電壓檢測(cè)標(biāo)志位,同時(shí)也是低電壓檢測(cè)中斷請(qǐng)求標(biāo)志位
GF1,GF0:兩個(gè)通用工作標(biāo)志位,用戶可以自由使用。
PD:掉電模式設(shè)定位。
PD=0 單片機(jī)處于正常工作狀態(tài)。
PD=1 單片機(jī)進(jìn)入掉電(Power Down)模式 ,可由外部中斷或硬件復(fù)位模式喚醒,進(jìn)入掉電模式后,外部晶振停振,CPU、定時(shí)器、串行口全部停止工作,只有外部中斷工作。在該模式下,只有硬件復(fù)位和上電能夠喚醒單片機(jī)。
IDL:空閑模式設(shè)定位。
IDL=0 單片機(jī)處于正常工作狀態(tài)。
IDL=1 單片機(jī)進(jìn)入空閑(Idle)模式,除CPU不工作外,其余仍繼續(xù)工作,在空閑模式下可由任一個(gè)中斷或硬件復(fù)位喚醒。
這個(gè)寄存器只有SMOD位與串行口通信有關(guān)。系統(tǒng)復(fù)位默認(rèn)為SMOD=0。當(dāng)為用52單片機(jī)的定時(shí)器2產(chǎn)生波特率時(shí),波特率不受SMOD影響。用定時(shí)器1產(chǎn)生波特率時(shí),不去設(shè)置,就默認(rèn)為0,波特率正常,設(shè)置為1時(shí),波特率加倍。
SCON串行口控制寄存器
串行口控制寄存器
SM0,SM1:共同決定串行口工作模式。
SM2:多機(jī)通信控制位。在方式0中,SM2一定要等于0。在方式1中,當(dāng)SM2為1時(shí)則只有接收到有效停止位時(shí),RI才置1。在方式2或3中,當(dāng)SM2為1且接收到的第9位數(shù)據(jù)RB8為0時(shí),RI才置1。
REN:接收允許控制位。由 軟件置位以允許接收,又由 軟件清零來(lái)禁止接收。
TB8:要發(fā)送數(shù)據(jù)的第9位。在方式2或3中,要發(fā)送的第9位數(shù)據(jù),根據(jù)需要由軟件置1或清零軟件置1或清零。例如,可約定作為奇偶校驗(yàn)位,或在多機(jī)通信中作為區(qū)別地址幀或數(shù)據(jù)幀的標(biāo)志位。(很少用)
RB8:接收到的數(shù)據(jù)的第9位。在方式0中不使用RB8。在方式1中,若SM2為0,RB8為接收到的停止位。在方式2或3中,RB8為到的第9位數(shù)據(jù)。(很少用)
TI:發(fā)送中斷標(biāo)志。在方式0中,第8位發(fā)送結(jié)束時(shí),由 硬件置位。在其它方式的發(fā)送停止位前,由 硬件置位。TI置位既表示一幀信息發(fā)送結(jié)束,同時(shí)也向CPU申請(qǐng)中斷??筛鶕?jù)需要,用軟件查詢的方法獲得數(shù)據(jù)已發(fā)送完畢的信息,或用中斷的方式來(lái)發(fā)送下一個(gè)數(shù)據(jù)。TI必須用 軟件清零。
RI:接收中斷標(biāo)志位。在方式0中,當(dāng)接收完第8位數(shù)據(jù)后,由 硬件置位。在其它方式中,在接收到停止位的中間時(shí)刻由硬件置位(例外情況見(jiàn)對(duì)SM2的說(shuō)明)。RI表示一幀數(shù)據(jù)接收完畢,可用查詢的方法獲知或者用中斷的方法獲知。RI也必須用 軟件清零。串行口工作模式
由于52單片機(jī)內(nèi)部有一個(gè)硬件模塊,讓它自動(dòng)接收數(shù)據(jù),接收完了,通知我們一下就可以了,就不需要再手動(dòng)配置TB8,RB8。只要配置好SCON,內(nèi)部就自動(dòng)幫弄好了。
SBUF特殊功能寄存器
特殊功能寄存器
SBUF是指串行口中的兩個(gè)緩沖寄存器,一個(gè)是發(fā)送寄存器,一個(gè)是接收寄存器,在物理結(jié)構(gòu)上是完全獨(dú)立的,但地址是重疊的。它們都是字節(jié)尋址的寄存器,字節(jié)地址均為99H。只要在編寫(xiě)程序時(shí),用不同指令即可操作兩個(gè)寄存器。
比如,SBUF=A;這個(gè)是指將A的數(shù)據(jù)移入發(fā)送寄存器,然后發(fā)送寄存器再把數(shù)據(jù)發(fā)送出去。A=SBUF;則是指將接受寄存器中的數(shù)據(jù)賦值給A。
串行口方式1
方式1邏輯圖
串行口為10位通用異步接口。發(fā)送或接收一幀數(shù)據(jù)信息為10位,包括1位起始位“0”、8位數(shù)據(jù)位、1位停止位“1”。發(fā)送數(shù)據(jù):數(shù)據(jù)從TXD端口輸出,當(dāng)數(shù)據(jù)寫(xiě)入發(fā)送緩沖器SBUF時(shí),就啟動(dòng)發(fā)送器發(fā)送。發(fā)送完一幀數(shù)據(jù)后,置中斷標(biāo)志TI=1,申請(qǐng)中斷,通知CPU可以發(fā)送下一個(gè)數(shù)據(jù)了。接收數(shù)據(jù):首先使REN=1(允許接收數(shù)據(jù)),串行口從RXD接收數(shù)據(jù),當(dāng)采樣到1至0跳變時(shí),確認(rèn)是起始位“0”,就開(kāi)始接收一幀數(shù)據(jù),當(dāng)接收完一幀數(shù)據(jù)時(shí),置中斷標(biāo)志RI=1,申請(qǐng)中斷,通知CPU從SBUF取走接收到的數(shù)據(jù) 。
計(jì)算波特率
方式1波特率計(jì)算
溢出速率即溢出頻率,只要算出定時(shí)器每溢出一次所需要的時(shí)間T,那溢出率就是1/T。計(jì)算在沒(méi)有波特率加倍(SMOD=0)的情況下,波特率為9600bps時(shí)怎樣賦值計(jì)數(shù)器。這里說(shuō)明一下,由于波特率是需要很精確的,不然通信會(huì)出錯(cuò)。如果采用定時(shí)器工作模式1,采用人工重載,會(huì)有較大誤差,因?yàn)檫M(jìn)入中斷函數(shù)也需要時(shí)間,累積時(shí)間就會(huì)出錯(cuò)。所以這里運(yùn)用工作模式2,8位自動(dòng)重裝。計(jì)數(shù)器自動(dòng)重裝不需人工干預(yù),減少誤差。
對(duì)照上面公式,波特率不加倍,SMOD=0,工作模式2,那n=8,波特率=9600,就可以算出x=253,十六進(jìn)制為fd。
編寫(xiě)步驟
設(shè)置串行口方式
設(shè)置定時(shí)器工作模式
計(jì)數(shù)器寄存器賦值
中斷寄存器控制
啟動(dòng)定時(shí)器中斷
發(fā)送函數(shù)
接收函數(shù)
范例1
#include
unsigned?char?date;????//定義變量數(shù)據(jù)中斷
bit?flag;??//定義變量標(biāo)志
void?send?();?//聲明發(fā)送函數(shù)
void?receive?();?//聲明接收函數(shù)
void?initialize?();????//聲明初始化函數(shù)
main()
{????????
????initialize();??//調(diào)用初始化函數(shù)
????while(1)
????{
????????send();????//調(diào)用發(fā)送函數(shù)
????????receive();?//調(diào)用接收函數(shù)
????}
}
void?initialize()??//初始化函數(shù)
{
????SCON=0X50;?????//0011?0000?串行口工作模式1
????TMOD?=?0X20;????//定時(shí)器1工作模式2,8為自動(dòng)重裝
????TH1?=?0xFD;?????//設(shè)定定時(shí)初值????????波特率為9600
????TL1?=?0xFD;?????//設(shè)定定時(shí)器重裝值
????TR1?=?1;????????//啟動(dòng)定時(shí)器1
????IE=0;
}
void?send()?????????//發(fā)送函數(shù)
{
????if(flag==1)????//證明已經(jīng)接收數(shù)據(jù)
????{???
????????SBUF=date;????//將接收的數(shù)據(jù)發(fā)送出去
????????while(!TI);???//等待發(fā)送中斷
????????TI=0;?????????//軟件置0
????????flag=0;???????//清零
????}
}
void?receive()???????//接收函數(shù)
{
????while(!RI);???//等待接收中斷
????date=SBUF;????//將收到的數(shù)據(jù)存進(jìn)接收緩沖寄存器
????RI=0;????????//軟件置0
????flag=1;??????//將標(biāo)志位置1
}
范例1是將接受的數(shù)據(jù)原封不動(dòng)發(fā)送出去。采用查詢法,故不需要打開(kāi)串口中斷,不用中斷函數(shù)。只需不斷查詢TI,RI的值,就知道數(shù)據(jù)接收發(fā)送情況。
范例2
#include
unsigned?char?date;
bit?flag;
main?()
{
????SCON=0X50;??????//初始化
????TMOD=0X20;
????TH1=0XFD;???????????????????????????????????
????TL1=0XFD;
????IE=0X90;
????TR1=1;
????while(1);
}
void?interrupt_uart()?interrupt?4?????//中斷函數(shù)
{
????if(RI==1)????????//判斷有無(wú)數(shù)據(jù)接收
????{
????????date=SBUF;?????//將寄存器的值賦給變量
????????RI=0;??????????//置0
????????flag=1;????????//標(biāo)志位置1
????}
????if(flag==1)?????????????//已接收數(shù)據(jù)
????{
????????SBUF=date;????????//將數(shù)據(jù)發(fā)出
????????while(!TI);
????????TI=0;
????????flag=0;
????}
}
與范例1如出一撤,就不詳細(xì)注釋。
總結(jié)
在串口通信中,方式1是最常用的,要認(rèn)真理解方式1。串行數(shù)據(jù)一位一位的已經(jīng)不用處理了,52單片機(jī)已經(jīng)有一個(gè)模塊處理完了。只要知道接收一個(gè)數(shù)據(jù),產(chǎn)生一次接收中斷,要軟件置0.,發(fā)送一個(gè)數(shù)據(jù)會(huì)產(chǎn)生一次發(fā)送中斷,也要軟件置0。自行置0,處理好數(shù)據(jù)就OK。下一篇將介紹其他三種方式,歡迎關(guān)注。
前言
人類生存于世,少不了溝通。溝通使人類互相認(rèn)知,傳遞信息,提升生活品質(zhì)。但然單片機(jī)也需要,不然單單一個(gè)機(jī)器,無(wú)法構(gòu)成一個(gè)系統(tǒng),發(fā)揮更大的力量。只有單片機(jī)與外圍設(shè)備傳遞信息,互相反饋才會(huì)有一個(gè)完美的系統(tǒng)。串行口通信就被發(fā)明出來(lái),下面來(lái)了解串行口通信(uart)。
幾個(gè)概念
為了能更好理解串行口通信,在介紹它之前,先來(lái)看看幾個(gè)概念,補(bǔ)充知識(shí),方便深入明白u(yù)art工作原理。
通信方式
通信方式
通信方式有兩種,分別是并行通信和串行通信。
并行通信:并行是指多比特?cái)?shù)據(jù)同時(shí)通過(guò)并行線進(jìn)行傳送,這樣數(shù)據(jù)傳送速度大大提高,但并行傳送的線路長(zhǎng)度受到限制,因?yàn)殚L(zhǎng)度增加,干擾就會(huì)增加,數(shù)據(jù)也就容易出錯(cuò)。
串行通信:串行通信是指 使用一條數(shù)據(jù)線,將數(shù)據(jù)一位一位地依次傳輸,每一位數(shù)據(jù)占據(jù)一個(gè)固定的時(shí)間長(zhǎng)度。其只需要少數(shù)幾條線就可以在系統(tǒng)間交換信息,特別適用于計(jì)算機(jī)與計(jì)算機(jī)、計(jì)算機(jī)與外設(shè)之間的遠(yuǎn)距離通信。
拿汽車通道來(lái)說(shuō),并行通信就是多車道,多輛車一起行駛,而串行通信就是單車道,只能一輛一輛車通過(guò)。
串行通信制式
串行通信制式
串行通信制式有單工通信,半雙工通信,雙工通信三種。
單工通信:?jiǎn)喂ねㄐ判诺朗菃蜗蛐诺溃l(fā)送端和接收端的身份是固定的,發(fā)送端只能發(fā)送信息,不能接收信息;接收端只能接收信息,不能發(fā)送信息,數(shù)據(jù)信號(hào)僅從一端傳送到另一端,即信息流是單方向的。
半雙工通信:半雙工數(shù)據(jù)傳輸指數(shù)據(jù)可以在一個(gè)信號(hào)載體的兩個(gè)方向上傳輸,但是不能同時(shí)傳輸。例如,在一個(gè)局域網(wǎng)上使用具有半雙工傳輸?shù)募夹g(shù),一個(gè)工作站可以在線上發(fā)送數(shù)據(jù),然后立即在線上接收數(shù)據(jù),這些數(shù)據(jù)來(lái)自數(shù)據(jù)剛剛傳輸?shù)姆较?。像全雙工傳輸一樣,半雙工包含一個(gè)雙向線路(線路可以在兩個(gè)方向上傳遞數(shù)據(jù))。
雙工通信:雙工通信是指在同一時(shí)刻信息可以進(jìn)行雙向傳輸,和打電話一樣,說(shuō)的同時(shí)也能聽(tīng),邊說(shuō)邊聽(tīng)。這種發(fā)射機(jī)和接收機(jī)分別在兩個(gè)不同的頻率上(兩個(gè)頻率差有一定要求)能同時(shí)進(jìn)行工作的雙工機(jī)也稱為異頻雙工機(jī)。
三種通信制式很容易理解,對(duì)照上圖看,單工通信不就是單方面通信,只能發(fā)出指令或接收指令。半雙工通信就是能接收又能發(fā)送,但是不能同時(shí)進(jìn)行。雙工就最厲害,可以同時(shí)發(fā)送和接收指令。
串行通信分類
串行通信有兩種,一位異步串行通信,二為同步串行通信。
異步串行通信:異步串行通信是指通信雙方以一個(gè)字符(包括特定附加位)作為數(shù)據(jù)傳輸單位且發(fā)送方傳送字符的間隔時(shí)間不一定,具有不規(guī)則數(shù)據(jù)段傳送特性的串行數(shù)據(jù)傳輸。
同步串行通信:所謂同步通信是指在約定的通信速率下,發(fā)送端和接收端的時(shí)鐘信號(hào)頻率和相位始終保持一致(同步),這就保證了通信雙方在發(fā)送和接收數(shù)據(jù)時(shí)具有完全一致的定時(shí)關(guān)系。
兩種串行通信不同就只有時(shí)間,在發(fā)送字符時(shí),異步可以是不同時(shí)間間隔發(fā)送,但同步只能以固定的時(shí)間間隔發(fā)送。
波特率
波特率:波特率表示每秒鐘傳送的二進(jìn)制位數(shù),是衡量數(shù)據(jù)傳送速率的指標(biāo),它用單位時(shí)間內(nèi)載波調(diào)制狀態(tài)改變的次數(shù)來(lái)表示。
相互通信的甲乙雙方必須具有相同的波特率,不然無(wú)法成功完成串行通信。
概述
52單片機(jī)具有一個(gè)全雙工串行通信口。一個(gè)全雙工UART(通用異步接收發(fā)送器)的串行I/O口,用于實(shí)現(xiàn)單片機(jī)之間或單片機(jī)與微機(jī)之間的串行通信;片內(nèi)振蕩器和時(shí)鐘產(chǎn)生電路,石英晶體和微調(diào)電容需要外接。最佳振蕩頻率為6M—12M。管腳RXD( P3.0),TXD(P3.1)與串口通信有關(guān)。波特率可以設(shè)置。
內(nèi)部結(jié)構(gòu)
串行口內(nèi)部結(jié)構(gòu)邏輯圖
串行口通信與三個(gè)寄存器有關(guān),分別是:
?1.?PCON寄存器
?2.?SCON寄存器
?3.?SBUF特殊功能寄存器
寄存器
PCON電源管理寄存器
電源管理寄存器
SMOD:該位與串口通信有關(guān)。
SMOD=0; 串口方式1,2,3時(shí),波特率正常。
SMOD=1; 串口方式1,2,3時(shí),波特率加倍。
LVDF:低電壓檢測(cè)標(biāo)志位,同時(shí)也是低電壓檢測(cè)中斷請(qǐng)求標(biāo)志位
GF1,GF0:兩個(gè)通用工作標(biāo)志位,用戶可以自由使用。
PD:掉電模式設(shè)定位。
PD=0 單片機(jī)處于正常工作狀態(tài)。
PD=1 單片機(jī)進(jìn)入掉電(Power Down)模式 ,可由外部中斷或硬件復(fù)位模式喚醒,進(jìn)入掉電模式后,外部晶振停振,CPU、定時(shí)器、串行口全部停止工作,只有外部中斷工作。在該模式下,只有硬件復(fù)位和上電能夠喚醒單片機(jī)。
IDL:空閑模式設(shè)定位。
IDL=0 單片機(jī)處于正常工作狀態(tài)。
IDL=1 單片機(jī)進(jìn)入空閑(Idle)模式,除CPU不工作外,其余仍繼續(xù)工作,在空閑模式下可由任一個(gè)中斷或硬件復(fù)位喚醒。
這個(gè)寄存器只有SMOD位與串行口通信有關(guān)。系統(tǒng)復(fù)位默認(rèn)為SMOD=0。當(dāng)為用52單片機(jī)的定時(shí)器2產(chǎn)生波特率時(shí),波特率不受SMOD影響。用定時(shí)器1產(chǎn)生波特率時(shí),不去設(shè)置,就默認(rèn)為0,波特率正常,設(shè)置為1時(shí),波特率加倍。
SCON串行口控制寄存器
串行口控制寄存器
SM0,SM1:共同決定串行口工作模式。
SM2:多機(jī)通信控制位。在方式0中,SM2一定要等于0。在方式1中,當(dāng)SM2為1時(shí)則只有接收到有效停止位時(shí),RI才置1。在方式2或3中,當(dāng)SM2為1且接收到的第9位數(shù)據(jù)RB8為0時(shí),RI才置1。
REN:接收允許控制位。由 軟件置位以允許接收,又由 軟件清零來(lái)禁止接收。
TB8:要發(fā)送數(shù)據(jù)的第9位。在方式2或3中,要發(fā)送的第9位數(shù)據(jù),根據(jù)需要由軟件置1或清零軟件置1或清零。例如,可約定作為奇偶校驗(yàn)位,或在多機(jī)通信中作為區(qū)別地址幀或數(shù)據(jù)幀的標(biāo)志位。(很少用)
RB8:接收到的數(shù)據(jù)的第9位。在方式0中不使用RB8。在方式1中,若SM2為0,RB8為接收到的停止位。在方式2或3中,RB8為到的第9位數(shù)據(jù)。(很少用)
TI:發(fā)送中斷標(biāo)志。在方式0中,第8位發(fā)送結(jié)束時(shí),由 硬件置位。在其它方式的發(fā)送停止位前,由 硬件置位。TI置位既表示一幀信息發(fā)送結(jié)束,同時(shí)也向CPU申請(qǐng)中斷??筛鶕?jù)需要,用軟件查詢的方法獲得數(shù)據(jù)已發(fā)送完畢的信息,或用中斷的方式來(lái)發(fā)送下一個(gè)數(shù)據(jù)。TI必須用 軟件清零。
RI:接收中斷標(biāo)志位。在方式0中,當(dāng)接收完第8位數(shù)據(jù)后,由 硬件置位。在其它方式中,在接收到停止位的中間時(shí)刻由硬件置位(例外情況見(jiàn)對(duì)SM2的說(shuō)明)。RI表示一幀數(shù)據(jù)接收完畢,可用查詢的方法獲知或者用中斷的方法獲知。RI也必須用 軟件清零。串行口工作模式
由于52單片機(jī)內(nèi)部有一個(gè)硬件模塊,讓它自動(dòng)接收數(shù)據(jù),接收完了,通知我們一下就可以了,就不需要再手動(dòng)配置TB8,RB8。只要配置好SCON,內(nèi)部就自動(dòng)幫弄好了。
SBUF特殊功能寄存器
特殊功能寄存器
SBUF是指串行口中的兩個(gè)緩沖寄存器,一個(gè)是發(fā)送寄存器,一個(gè)是接收寄存器,在物理結(jié)構(gòu)上是完全獨(dú)立的,但地址是重疊的。它們都是字節(jié)尋址的寄存器,字節(jié)地址均為99H。只要在編寫(xiě)程序時(shí),用不同指令即可操作兩個(gè)寄存器。
比如,SBUF=A;這個(gè)是指將A的數(shù)據(jù)移入發(fā)送寄存器,然后發(fā)送寄存器再把數(shù)據(jù)發(fā)送出去。A=SBUF;則是指將接受寄存器中的數(shù)據(jù)賦值給A。
串行口方式1
方式1邏輯圖
串行口為10位通用異步接口。發(fā)送或接收一幀數(shù)據(jù)信息為10位,包括1位起始位“0”、8位數(shù)據(jù)位、1位停止位“1”。發(fā)送數(shù)據(jù):數(shù)據(jù)從TXD端口輸出,當(dāng)數(shù)據(jù)寫(xiě)入發(fā)送緩沖器SBUF時(shí),就啟動(dòng)發(fā)送器發(fā)送。發(fā)送完一幀數(shù)據(jù)后,置中斷標(biāo)志TI=1,申請(qǐng)中斷,通知CPU可以發(fā)送下一個(gè)數(shù)據(jù)了。接收數(shù)據(jù):首先使REN=1(允許接收數(shù)據(jù)),串行口從RXD接收數(shù)據(jù),當(dāng)采樣到1至0跳變時(shí),確認(rèn)是起始位“0”,就開(kāi)始接收一幀數(shù)據(jù),當(dāng)接收完一幀數(shù)據(jù)時(shí),置中斷標(biāo)志RI=1,申請(qǐng)中斷,通知CPU從SBUF取走接收到的數(shù)據(jù) 。
計(jì)算波特率
方式1波特率計(jì)算
溢出速率即溢出頻率,只要算出定時(shí)器每溢出一次所需要的時(shí)間T,那溢出率就是1/T。計(jì)算在沒(méi)有波特率加倍(SMOD=0)的情況下,波特率為9600bps時(shí)怎樣賦值計(jì)數(shù)器。這里說(shuō)明一下,由于波特率是需要很精確的,不然通信會(huì)出錯(cuò)。如果采用定時(shí)器工作模式1,采用人工重載,會(huì)有較大誤差,因?yàn)檫M(jìn)入中斷函數(shù)也需要時(shí)間,累積時(shí)間就會(huì)出錯(cuò)。所以這里運(yùn)用工作模式2,8位自動(dòng)重裝。計(jì)數(shù)器自動(dòng)重裝不需人工干預(yù),減少誤差。
對(duì)照上面公式,波特率不加倍,SMOD=0,工作模式2,那n=8,波特率=9600,就可以算出x=253,十六進(jìn)制為fd。
編寫(xiě)步驟
設(shè)置串行口方式
設(shè)置定時(shí)器工作模式
計(jì)數(shù)器寄存器賦值
中斷寄存器控制
啟動(dòng)定時(shí)器中斷
發(fā)送函數(shù)
接收函數(shù)
范例1
#include
unsigned?char?date;????//定義變量數(shù)據(jù)中斷
bit?flag;??//定義變量標(biāo)志
void?send?();?//聲明發(fā)送函數(shù)
void?receive?();?//聲明接收函數(shù)
void?initialize?();????//聲明初始化函數(shù)
main()
{????????
????initialize();??//調(diào)用初始化函數(shù)
????while(1)
????{
????????send();????//調(diào)用發(fā)送函數(shù)
????????receive();?//調(diào)用接收函數(shù)
????}
}
void?initialize()??//初始化函數(shù)
{
????SCON=0X50;?????//0011?0000?串行口工作模式1
????TMOD?=?0X20;????//定時(shí)器1工作模式2,8為自動(dòng)重裝
????TH1?=?0xFD;?????//設(shè)定定時(shí)初值????????波特率為9600
????TL1?=?0xFD;?????//設(shè)定定時(shí)器重裝值
????TR1?=?1;????????//啟動(dòng)定時(shí)器1
????IE=0;
}
void?send()?????????//發(fā)送函數(shù)
{
????if(flag==1)????//證明已經(jīng)接收數(shù)據(jù)
????{???
????????SBUF=date;????//將接收的數(shù)據(jù)發(fā)送出去
????????while(!TI);???//等待發(fā)送中斷
????????TI=0;?????????//軟件置0
????????flag=0;???????//清零
????}
}
void?receive()???????//接收函數(shù)
{
????while(!RI);???//等待接收中斷
????date=SBUF;????//將收到的數(shù)據(jù)存進(jìn)接收緩沖寄存器
????RI=0;????????//軟件置0
????flag=1;??????//將標(biāo)志位置1
}
范例1是將接受的數(shù)據(jù)原封不動(dòng)發(fā)送出去。采用查詢法,故不需要打開(kāi)串口中斷,不用中斷函數(shù)。只需不斷查詢TI,RI的值,就知道數(shù)據(jù)接收發(fā)送情況。
范例2
#include
unsigned?char?date;
bit?flag;
main?()
{
????SCON=0X50;??????//初始化
????TMOD=0X20;
????TH1=0XFD;???????????????????????????????????
????TL1=0XFD;
????IE=0X90;
????TR1=1;
????while(1);
}
void?interrupt_uart()?interrupt?4?????//中斷函數(shù)
{
????if(RI==1)????????//判斷有無(wú)數(shù)據(jù)接收
????{
????????date=SBUF;?????//將寄存器的值賦給變量
????????RI=0;??????????//置0
????????flag=1;????????//標(biāo)志位置1
????}
????if(flag==1)?????????????//已接收數(shù)據(jù)
????{
????????SBUF=date;????????//將數(shù)據(jù)發(fā)出
????????while(!TI);
????????TI=0;
????????flag=0;
????}
}
與范例1如出一撤,就不詳細(xì)注釋。
總結(jié)
在串口通信中,方式1是最常用的,要認(rèn)真理解方式1。串行數(shù)據(jù)一位一位的已經(jīng)不用處理了,52單片機(jī)已經(jīng)有一個(gè)模塊處理完了。只要知道接收一個(gè)數(shù)據(jù),產(chǎn)生一次接收中斷,要軟件置0.,發(fā)送一個(gè)數(shù)據(jù)會(huì)產(chǎn)生一次發(fā)送中斷,也要軟件置0。自行置0,處理好數(shù)據(jù)就OK。下一篇將介紹其他三種方式,歡迎關(guān)注。
評(píng)論