AVR單片機(jī)(學(xué)習(xí)ing)-ATMEGA16的USART與PC機(jī)串行通信
7、數(shù)據(jù)發(fā)送—USART發(fā)送器
置位UCSRB 寄存器的發(fā)送允許位TXEN 將使能USART 的數(shù)據(jù)發(fā)送。使能后TxD 引腳
的通用I/O 功能即被USART 功能所取代,成為發(fā)送器的串行輸出引腳。發(fā)送數(shù)據(jù)之前要
設(shè)置好波特率、工作模式與幀結(jié)構(gòu)。如果使用同步發(fā)送模式,施加于XCK 引腳上的時(shí)鐘
信號(hào)即為數(shù)據(jù)發(fā)送的時(shí)鐘。
1)發(fā)送5 到8 位數(shù)據(jù)位的幀
將需要發(fā)送的數(shù)據(jù)加載到發(fā)送緩存器將啟動(dòng)數(shù)據(jù)發(fā)送。加載過(guò)程即為CPU 對(duì)UDR 寄存
器的寫操作。當(dāng)移位寄存器可以發(fā)送新一幀數(shù)據(jù)時(shí),緩沖的數(shù)據(jù)將轉(zhuǎn)移到移位寄存器。當(dāng)
移位寄存器處于空閑狀態(tài)( 沒(méi)有正在進(jìn)行的數(shù)據(jù)傳輸),或前一幀數(shù)據(jù)的最后一個(gè)停止位
傳送結(jié)束,它將加載新的數(shù)據(jù)。一旦移位寄存器加載了新的數(shù)據(jù),就會(huì)按照設(shè)定的波特率
完成數(shù)據(jù)的發(fā)送
以下程序給出一個(gè)對(duì)UDRE 標(biāo)志采用輪詢方式發(fā)送數(shù)據(jù)的例子。當(dāng)發(fā)送的數(shù)據(jù)少于8 位
時(shí),寫入U(xiǎn)DR 相應(yīng)位置的高幾位將被忽略。當(dāng)然,執(zhí)行本段代碼之前首先要初始化
USART。在匯編代碼中要發(fā)送的數(shù)據(jù)存放于R16。
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<
UDR = data;
}
2)發(fā)送9位數(shù)據(jù)的幀
TXB8,然后再將低8位數(shù)據(jù)寫入發(fā)送數(shù)據(jù)寄存器UDR。以下程序給出發(fā)送9位數(shù)據(jù)的數(shù)據(jù)
幀例子。在匯編代碼中要發(fā)送的數(shù)據(jù)存放在R17:R16 寄存器中。
void USART_Transmit( unsigned int data )
{
while ( !( UCSRA & (1<
UCSRB &= ~(1<
UCSRB |= (1<
UDR = data;
}
第9 位數(shù)據(jù)在多機(jī)通信中用于表示地址幀,在同步通信中可以用于協(xié)議處理。
3)傳送標(biāo)志位與中斷
USART 發(fā)送器有兩個(gè)標(biāo)志位:USART 數(shù)據(jù)寄存器空標(biāo)志UDRE 及傳輸結(jié)束標(biāo)志TXC,兩
個(gè)標(biāo)志位都可以產(chǎn)生中斷。
數(shù)據(jù)寄存器空UDRE 標(biāo)志位表示發(fā)送緩沖器是否可以接受一個(gè)新的數(shù)據(jù)。該位在發(fā)送緩
沖器空時(shí)被置"1” ;當(dāng)發(fā)送緩沖器包含需要發(fā)送的數(shù)據(jù)時(shí)清零。為與將來(lái)的器件兼容,寫
UCSRA 寄存器時(shí)該位要寫"0”。
當(dāng)UCSRB 寄存器中的數(shù)據(jù)寄存器空中斷使能位UDRIE 為"1” 時(shí),只要UDRE 被置位(
且全局中斷使能),就將產(chǎn)生USART 數(shù)據(jù)寄存器空中斷請(qǐng)求。對(duì)寄存器UDR 執(zhí)行寫操作
將清零UDRE。當(dāng)采用中斷方式的傳輸數(shù)據(jù)時(shí),在數(shù)據(jù)寄存器空中斷服務(wù)程序中必須寫一
個(gè)新的數(shù)據(jù)到UDR 以清零UDRE ;或者是禁止數(shù)據(jù)寄存器空中斷。否則一旦該中斷程序
結(jié)束,一個(gè)新的中斷將再次產(chǎn)生。
當(dāng)整個(gè)數(shù)據(jù)幀移出發(fā)送移位寄存器,同時(shí)發(fā)送緩沖器中又沒(méi)有新的數(shù)據(jù)時(shí),發(fā)送結(jié)束標(biāo)志
TXC 置位。TXC 在傳送結(jié)束中斷執(zhí)行時(shí)自動(dòng)清零,也可在該位寫"1” 來(lái)清零。TXC 標(biāo)志位
對(duì)于采用如RS-485 標(biāo)準(zhǔn)的半雙工通信接口十分有用。在這些應(yīng)用里,一旦傳送完畢,應(yīng)
用程序必須釋放通信總線并進(jìn)入接收狀態(tài)。
當(dāng)UCSRB 上的發(fā)送結(jié)束中斷使能位TXCIE 與全局中斷使能位均被置為"1” 時(shí),隨著TXC
標(biāo)志位的置位, USART 發(fā)送結(jié)束中斷將被執(zhí)行。一旦進(jìn)入中斷服務(wù)程序, TXC 標(biāo)志位
即被自動(dòng)清零,中斷處理程序不必執(zhí)行TXC 清零操作。
4)奇偶校驗(yàn)產(chǎn)生電路
奇偶校驗(yàn)產(chǎn)生電路為串行數(shù)據(jù)幀生成相應(yīng)的校驗(yàn)位。校驗(yàn)位使能(UPM1 = 1) 時(shí),發(fā)送控
制邏輯電路會(huì)在數(shù)據(jù)的最后一位與第一個(gè)停止位之間插入奇偶校驗(yàn)位。
5)禁止發(fā)送器
TXEN 清零后,只有等到所有的數(shù)據(jù)發(fā)送完成后發(fā)送器才能夠真正禁止,即發(fā)送移位寄存
器與發(fā)送緩沖寄存器中沒(méi)有要傳送的數(shù)據(jù)。發(fā)送器禁止后,TxD引腳恢復(fù)其通用I/O功能。
8、數(shù)據(jù)接收—USART接收器
置位UCSRB 寄存器的接收允許位(RXEN) 即可啟動(dòng)USART 接收器。接收器使能后RxD
的普通引腳功能被USART 功能所取代,成為接收器的串行輸入口。進(jìn)行數(shù)據(jù)接收之前首
先要設(shè)置好波特率、操作模式及幀格式。 如果使用同步操作, XCK 引腳上的時(shí)鐘被用為
傳輸時(shí)鐘。
1)以5 到8 個(gè)數(shù)據(jù)位的方式接收數(shù)據(jù)幀
一旦接收器檢測(cè)到一個(gè)有效的起始位,便開始接收數(shù)據(jù)。起始位后的每一位數(shù)據(jù)都將以所
設(shè)定的波特率或XCK 時(shí)鐘進(jìn)行接收,直到收到一幀數(shù)據(jù)的第一個(gè)停止位。接收到的數(shù)據(jù)
被送入接收移位寄存器。第二個(gè)停止位會(huì)被接收器忽略。 接收到第一個(gè)停止位后,接收移
位寄存器就包含了一個(gè)完整的數(shù)據(jù)幀。這時(shí)移位寄存器中的內(nèi)容將被轉(zhuǎn)移到接收緩沖器
中。通過(guò)讀取UDR 就可以獲得接收緩沖器的內(nèi)容的。
以下程序給出一個(gè)對(duì)RXC 標(biāo)志采用輪詢方式接收數(shù)據(jù)的例子。當(dāng)數(shù)據(jù)幀少于8 位時(shí),從
UDR 讀取的相應(yīng)的高幾位為0。當(dāng)然,執(zhí)行本段代碼之前首先要初始化USART。
unsigned char USART_Receive( void )
{
while ( !(UCSRA & (1<
return UDR;
}
在讀緩沖器并返回之前,函數(shù)通過(guò)檢查RXC 標(biāo)志來(lái)等待數(shù)據(jù)送入接收緩沖器。
2)以9 個(gè)數(shù)據(jù)位的方式接收幀
如果設(shè)定了9 位數(shù)據(jù)的數(shù)據(jù)幀(UCSZ=7),在從UDR 讀取低8 位之前必須首先讀取寄存
器UCSRB 的RXB8 以獲得第9 位數(shù)據(jù)。這個(gè)規(guī)則同樣適用于狀態(tài)標(biāo)志位FE、DOR 及
UPE。狀態(tài)通過(guò)讀取UCSRA獲得,數(shù)據(jù)通過(guò)UDR獲得。讀取UDR存儲(chǔ)單元會(huì)改變接收緩
沖器FIFO 的狀態(tài),進(jìn)而改變同樣存儲(chǔ)在FIFO 中的TXB8、 FE、DOR 及UPE 位。
接下來(lái)的代碼示例展示了一個(gè)簡(jiǎn)單的USART接收函數(shù),說(shuō)明如何處理9位數(shù)據(jù)及狀態(tài)位。
unsigned int USART_Receive( void )
{
unsigned char status, resh, resl;
while ( !(UCSRA & (1<
status = UCSRA;
resh = UCSRB;
resl = UDR;
if ( status & (1<
resh = (resh >> 1) & 0x01;
return ((resh << 8) | resl);
}
上述例子在進(jìn)行任何計(jì)算之前將所有的I/O寄存器的內(nèi)容讀到寄存器文件中。 這種方法優(yōu)
化了對(duì)接收緩沖器的利用。它盡可能早地釋放了緩沖器以接收新的數(shù)據(jù)。、
3)接收結(jié)束標(biāo)志及中斷
USART 接收器有一個(gè)標(biāo)志用來(lái)指明接收器的狀態(tài)。
接收結(jié)束標(biāo)志(RXC) 用來(lái)說(shuō)明接收緩沖器中是否有未讀出的數(shù)據(jù)。 當(dāng)接收緩沖器中有未
讀出的數(shù)據(jù)時(shí),此位為1,當(dāng)接收緩沖器空時(shí)為0( 即不包含未讀出的數(shù)據(jù))。如果接收器
被禁止(RXEN = 0),接收緩沖器會(huì)被刷新,從而使RXC 清零。
置位UCSRB 的接收結(jié)束中斷使能位(RXCIE) 后,只要RXC 標(biāo)志置位( 且全局中斷只能
) 就會(huì)產(chǎn)生USART 接收結(jié)束中斷。使用中斷方式進(jìn)行數(shù)據(jù)接收時(shí),數(shù)據(jù)接收結(jié)束中斷服
務(wù)程序程序必須從UDR 讀取數(shù)據(jù)以清RXC 標(biāo)志,否則只要中斷處理程序一結(jié)束,一個(gè)
新的中斷就會(huì)產(chǎn)生。
4)接受錯(cuò)誤標(biāo)志
USART 接收器有三個(gè)錯(cuò)誤標(biāo)志::幀錯(cuò)誤(FE)、數(shù)據(jù)溢出(DOR) 及奇偶校驗(yàn)錯(cuò)(UPE)。它
們都位于寄存器UCSRA。錯(cuò)誤標(biāo)志與數(shù)據(jù)幀一起保存在接收緩沖器中。由于讀取UDR
會(huì)改變緩沖器, UCSRA 的內(nèi)容必須在讀接收緩沖器(UDR) 之前讀入。錯(cuò)誤標(biāo)志的另一
個(gè)同一性是它們都不能通過(guò)軟件寫操作來(lái)修改。 但是為了保證與將來(lái)產(chǎn)品的兼容性,對(duì)
執(zhí)行寫操作是必須對(duì)這些錯(cuò)誤標(biāo)志所在的位置寫"0“。所有的錯(cuò)誤標(biāo)志都不能產(chǎn)生中斷。
幀錯(cuò)誤標(biāo)志(FE) 表明了存儲(chǔ)在接收緩沖器中的下一個(gè)可讀幀的第一個(gè)停止位的狀態(tài)。停
止位正確( 為1) 則FE 標(biāo)志為0,否則FE 標(biāo)志為1。 這個(gè)標(biāo)志可用來(lái)檢測(cè)同步丟失、傳
輸中斷,也可用于協(xié)議處理。UCSRC 中USBS 位的設(shè)置不影響FE 標(biāo)志位,因?yàn)槌说?br />一位,接收器忽略所有其他的停止位。 為了與以后的器件相兼容,寫UCSRA 時(shí)這一位必
須置0。
數(shù)據(jù)溢出標(biāo)志(DOR) 表明由于接收緩沖器滿造成了數(shù)據(jù)丟失。當(dāng)接收緩沖器滿( 包含了
兩個(gè)數(shù)據(jù)),接收移位寄存器又有數(shù)據(jù),若此時(shí)檢測(cè)到一個(gè)新的起始位,數(shù)據(jù)溢出就產(chǎn)生
了。DOR 標(biāo)志位置位即表明在最近一次讀取UDR 和下一次讀取UDR 之間丟失了一個(gè)或
更多的數(shù)據(jù)幀。 為了與以后的器件相兼容,寫UCSRA 時(shí)這一位必須置0。當(dāng)數(shù)據(jù)幀成功
地從移位寄存器轉(zhuǎn)入接收緩沖器后, DOR 標(biāo)志被清零。
奇偶校驗(yàn)錯(cuò)標(biāo)志 (UPE) 指出,接收緩沖器中的下一幀數(shù)據(jù)在接收時(shí)有奇偶錯(cuò)誤。 如果不
使能奇偶校驗(yàn),那么UPE 位應(yīng)清零。為了與以后的器件相兼容,寫UCSRA 時(shí)這一位必
須置0。
5)奇偶校驗(yàn)器
奇偶校驗(yàn)?zāi)J轿籙PM1置位將啟動(dòng)奇偶校驗(yàn)器。校驗(yàn)的模式(偶校驗(yàn)還是奇校驗(yàn))由UPM0
確定。奇偶校驗(yàn)使能后,校驗(yàn)器將計(jì)算輸入數(shù)據(jù)的奇偶并把結(jié)果與數(shù)據(jù)幀的奇偶位進(jìn)行比
較。 校驗(yàn)結(jié)果將與數(shù)據(jù)和停止位一起存儲(chǔ)在接收緩沖器中。這樣就可以通過(guò)讀取奇偶校
驗(yàn)錯(cuò)誤標(biāo)志位(UPE) 來(lái)檢查接收的幀中是否有奇偶錯(cuò)誤。
如果下一個(gè)從接收緩沖器中讀出的數(shù)據(jù)有奇偶錯(cuò)誤,并且奇偶校驗(yàn)使能(UPM1 = 1),則
UPE 置位。直到接收緩沖器(UDR) 被讀取,這一位一直有效。
6)禁止接收器
與發(fā)送器對(duì)比,禁止接收器即刻起作用。正在接收的數(shù)據(jù)將丟失。禁止接收器(RXEN 清
零) 后,接收器將不再占用RxD 引腳;接收緩沖器FIFO 也會(huì)被刷新。緩沖器中的數(shù)據(jù)將
丟失。
7)刷新接收緩沖器
禁止接收器時(shí)緩沖器FIFO 被刷新,緩沖器被清空。導(dǎo)致未讀出的數(shù)據(jù)丟失。如果由于出
錯(cuò)而必須在正常操作下刷新緩沖器,則需要一直讀取UDR 直到RXC 標(biāo)志清零。下面的
代碼展示了如何刷新接收緩沖器。
void USART_Flush( void )
{
unsigned char dummy;
while ( UCSRA & (1<
評(píng)論