您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!
N76E003包含兩個(gè)具備增強(qiáng)的自動(dòng)地址識(shí)別和幀錯(cuò)誤檢測(cè)功能的全雙工串口。由于兩個(gè)串口的控制位是一樣的,為了區(qū)分兩個(gè)串口控制位,串口1的控制位以“_1”結(jié)尾(例如SCON_1)。下述詳例以串口0為例。
每個(gè)串口都有一種同步工作模式:模式0。三種全雙工異步模式:模式1,2,和3,這意味著收發(fā)可以同時(shí)連續(xù)進(jìn)行。串口接收帶有接收緩存,意味著在接收的前一個(gè)數(shù)據(jù)在被讀取之前,串口就能接收第二個(gè)數(shù)據(jù)。接收和發(fā)送都是對(duì)SBUF進(jìn)行操作訪問(wèn),寫(xiě)入SBUF數(shù)據(jù)將直接傳到發(fā)送寄存器,而讀取SBUF是訪問(wèn)一個(gè)具有獨(dú)立物理地址的接收寄存器。串口共有4種操作模式,任何一種模式,任何以操作SBUF的指令都將開(kāi)始一次傳輸。注意,在使用串口功能前,串口所用管腳P0.7及 P0.6 (RXD 及 TXD引腳) 或者 P0.2及 P1.6 (RXD_1 及 TXD_1)必須先置1。N76E003提供更靈活的管腳配置,可將串口0的TXD及RXD通過(guò)UART0PX (AUXR1.2)更改位置。
13.1 模式 0
模式0是與外部設(shè)備進(jìn)行同步通信的方式。在該模式下,串行數(shù)據(jù)由RXD腳進(jìn)行收發(fā),而TXD 腳用于產(chǎn)生移位時(shí)鐘。這種方式下是以半雙工的形式進(jìn)行通信,每幀接收或發(fā)送8位數(shù)據(jù)。數(shù)據(jù)的最低位被最先發(fā)送或接收,波特率設(shè)置為FSYS/12(SM2 (SCON.5) 為 0) 或 FSYS/2 (SM2 為 1)。無(wú)論發(fā)送或接收數(shù)據(jù),串行時(shí)鐘將一直由MCU產(chǎn)生,因此串口模式 0 為主機(jī)模式。圖13?1 顯示串口模式0傳輸時(shí)序圖
如圖所示,數(shù)據(jù)由雙向RXD引腳進(jìn)行收發(fā),TXD引腳用來(lái)輸出移位時(shí)鐘。串口用移位時(shí)鐘來(lái)一位位接收/發(fā)送數(shù)據(jù)與其他串口通訊。數(shù)據(jù)移入移出由最低位開(kāi)始,波特率等于TXD的移位時(shí)鐘頻率。
向SBUF的寫(xiě)入數(shù)據(jù)將會(huì)開(kāi)啟發(fā)送,此時(shí)移位時(shí)鐘啟動(dòng)數(shù)據(jù)從RXD腳串行移出,直至8位數(shù)據(jù)傳輸完成。傳輸標(biāo)志位TI (SCON.1) 置 1表示 1 個(gè)字節(jié)數(shù)據(jù)傳輸完成。
當(dāng)REN (SCON.4)=1 且 RI(SCON.0)=0 時(shí)串口開(kāi)始接收數(shù)據(jù)。該條件告訴串口控制器有數(shù)據(jù)要移位進(jìn)入。這個(gè)過(guò)程將持續(xù)到8位數(shù)據(jù)接收完畢,然后接收標(biāo)志RI將置1。用戶(hù)可以清零RI,以觸發(fā)接收下一字節(jié)數(shù)據(jù)。
13.2 模式 1
模式1為異步全雙工的工作方式。異步通訊模式通常用于PC間,調(diào)制解調(diào)器和其它類(lèi)似接口間通訊。模式1下,10位數(shù)據(jù)通過(guò)TXD發(fā)送,通過(guò)RXD接收。10位數(shù)據(jù)組成如下:起始位(邏輯0),8位數(shù)據(jù)(最低位在前),停止位(邏輯1)。波特率由定時(shí)器1決定, SMOD (PCON.7) 設(shè)置為1可使波特率加倍.圖13?2為串口模式1發(fā)送和接收的時(shí)序圖.
向SBUF寫(xiě)入數(shù)據(jù)開(kāi)始傳輸,傳輸發(fā)生在TXD引腳上。首先是開(kāi)始位,隨后是8位數(shù)據(jù)位,最后是停止位。停止位出現(xiàn)后,TI(SCON.1)將置1 表示一個(gè)字節(jié)傳輸完成,所有位的傳輸速度取決于波特率。
當(dāng)波特率發(fā)生器激活且REN(SCON.4) =1時(shí),系統(tǒng)可以隨時(shí)開(kāi)始接收操作,當(dāng)RXD腳上偵測(cè)到1到0的跳變時(shí),數(shù)據(jù)將開(kāi)始被采樣并根據(jù)波特率的時(shí)鐘頻率接收,停止位必須符合一定的條件,接收到數(shù)據(jù)才能裝載到SBUF:
1. RI (SCON.0) = 0
2. 要么SM2 (SCON.5) = 0, 要么接收到停止位STOP= 1,同時(shí)SM2 = 1且被尋址“Given”或符合廣播地址(Broadcast address)匹配時(shí)。詳見(jiàn) 13.7 多機(jī)通訊 和 13.8 自動(dòng)地址識(shí)別。
如果上述條件滿(mǎn)足,SBUF將加載到接收數(shù)據(jù),RB8(SCON.2)為停止位,和RI將被置1,如果條件不滿(mǎn)足,RI保持為0,沒(méi)有數(shù)據(jù)加載。完成接收過(guò)程后,串口控制器將等待RXD腳上出現(xiàn)另一個(gè)1-0傳輸以開(kāi)始新的數(shù)據(jù)接收。
13.3 模式 2
模式2為全雙工異步通信, 與模式1不同的是,模式2是11位收發(fā)。數(shù)據(jù)由起始位(邏輯0),8位數(shù)據(jù)(最低位在前),第9位數(shù)據(jù)(TB8或RB8)和停止位(邏輯1)組成。第9位做奇偶校驗(yàn)位或多機(jī)通信時(shí)用來(lái)區(qū)分?jǐn)?shù)據(jù)和地址。波特率是系統(tǒng)時(shí)鐘頻率的1/32 或1/64,由 SMOD位(PCON.7)來(lái)配置。圖13?3 指示串口模式2的傳輸時(shí)序。
向SBUF中寫(xiě)入數(shù)據(jù)啟動(dòng)TXD引腳發(fā)送,首先是開(kāi)始位,然后是8位數(shù)據(jù)和TB8(SCON.3),最后是停止位,停止位發(fā)送后,TI將置位標(biāo)志傳輸完成。
當(dāng)REN=1時(shí),串口可進(jìn)行接收操作。RXD上的下降沿表示接收過(guò)程開(kāi)始,數(shù)據(jù)根據(jù)所配置波特率進(jìn)行采樣和接收。停止位必須符合一定的條件,接收到數(shù)據(jù)才能裝載到SBUF:
1. RI (SCON.0) = 0,
2. 要么SM2(SCON.5) = 0, 要么9th位 = 1同時(shí) SM2 = 1且被尋址“Given”或符合廣播地址(Broadcast address)匹配。詳見(jiàn) 13.7 多機(jī)通訊 和 13.8 自動(dòng)地址識(shí)別。
如果上述條件滿(mǎn)足,則第9位數(shù)據(jù)進(jìn)入RB8(SCON.2),8位數(shù)據(jù)進(jìn)入SBUF,且RI置位。否則數(shù)據(jù)將不會(huì)裝載,且RI保持為0。完成接收過(guò)程后,串口控制器等待RXD腳上的另一個(gè)1-0跳變以開(kāi)始新的數(shù)據(jù)接收。
13.4 模式 3
除波特率外模式 3與模式 2相同。模式3采用定時(shí)器1的溢出率作為波特率時(shí)鐘。圖13?3 模式3的傳輸時(shí)序,與模式2沒(méi)有不同。
13.5 波特率
串口的不同模式的波特率時(shí)鐘源和速度是完全不同的。詳見(jiàn)表 13–3. 用于設(shè)定不同的波特率。
在模式1或模式3,串口0的波特率時(shí)鐘源可通過(guò)BRCK (T3CON.5)選擇定時(shí)器1或定時(shí)器3。對(duì)于串口1,只有采用定時(shí)器3作為唯一的時(shí)鐘源。
當(dāng)采用定時(shí)器1作為波特率發(fā)生器,需要關(guān)閉定時(shí)器1中斷。定時(shí)器1可配置為計(jì)數(shù)器或是定時(shí)器,三種工作模式都可以。典型應(yīng)用中,會(huì)配置為定時(shí)器工作在自動(dòng)重裝載模式(定時(shí)器模式2)。如果采用定時(shí)器3作為波特率發(fā)生器,同樣也需要關(guān)閉定時(shí)器3中斷。
模式1和模式3的波特率是可變的,取決于定時(shí)器1或2(003芯片)的溢出速率,就是說(shuō)定時(shí)器1每溢出一次,串口發(fā)送一次數(shù)據(jù)。那么我們?cè)趺慈ビ?jì)算這兩個(gè)模式的波特率設(shè)置時(shí)相關(guān)的寄存器的值呢?可以用公式去計(jì)算。
13.6 幀錯(cuò)誤檢測(cè)
幀錯(cuò)誤檢測(cè)用于異步模式 (模式 1, 2 和 3)。當(dāng)由于總線干擾或爭(zhēng)奪,導(dǎo)致沒(méi)有檢測(cè)到有效的停止位時(shí),將發(fā)生幀錯(cuò)誤。串口可以檢測(cè)幀錯(cuò)誤,并通過(guò)軟件提示出錯(cuò)。
FE為幀錯(cuò)誤標(biāo)志,位于SCON第7位,這個(gè)位正常被用作為SM0 。當(dāng)SMOD0 (PCON.6)置1時(shí),幀錯(cuò)誤檢測(cè)功能打開(kāi),它作為FE標(biāo)志。SM0和FE其實(shí)是相互獨(dú)立的標(biāo)志位。
當(dāng)幀錯(cuò)誤發(fā)生時(shí),F(xiàn)E標(biāo)志由硬件置位。如果必要,F(xiàn)E可在串口中斷程序中檢測(cè)。注意在對(duì)FE標(biāo)志位進(jìn)行讀寫(xiě)時(shí),同時(shí)SMOD0必須為1。如果FE被置位,那么下次即使接收到的正確數(shù)據(jù)幀也不會(huì)將其清除。對(duì)該位的清除必須由軟件來(lái)完成。
13.7 多機(jī)通訊
N76E003串口支持多機(jī)通訊,可讓一個(gè)主機(jī)(master device)向多個(gè)從機(jī)(slave device)發(fā)送多幀序列信息。在同一串行線上使用該功能過(guò)程中不需要中斷其它從機(jī)設(shè)備工作。該功能只能在模式2或模式3下進(jìn)行。用戶(hù)設(shè)置SM2(SCON.5)為1打開(kāi)這個(gè)功能,以便當(dāng)一個(gè)數(shù)據(jù)幀接收后,當(dāng)?shù)?位為1時(shí),串口中斷將產(chǎn)生(模式2下,第9位為停止位)。當(dāng)SM2為1時(shí),如果第9位為0,不會(huì)發(fā)生中斷。在該情況下,第9位能簡(jiǎn)單的把從機(jī)地址和數(shù)據(jù)分開(kāi)。
當(dāng)主機(jī)需要向多個(gè)從機(jī)中的一個(gè)發(fā)送數(shù)據(jù)時(shí),首先需要發(fā)送目標(biāo)從機(jī)的地址。注,地址字節(jié)與數(shù)據(jù)字節(jié)是不同的:在地址字節(jié)中,第9位為1。而數(shù)據(jù)字節(jié)中第9位為0。地址字節(jié)會(huì)觸發(fā)所有從機(jī),而每臺(tái)從機(jī)檢查接收到的
地址是否與自身匹配。地址匹配的從機(jī),清除SM2,準(zhǔn)備接收數(shù)據(jù);未被尋址到的從機(jī)的SM2 必須保持,從而系統(tǒng)會(huì)持續(xù)工作,同時(shí)忽略接收數(shù)據(jù)。.
配置多機(jī)通信步驟如下:
1. 設(shè)置所有設(shè)備(主機(jī)與從機(jī))為串口模式2或3;
2. 所有從機(jī) SM2 位置為1;
3. 主機(jī)傳輸協(xié)議:
– 第一個(gè)字節(jié):地址,目標(biāo)從機(jī)地址 (第9位 = 1)
– 下一個(gè)字節(jié):數(shù)據(jù), (第9位 = 0)。
4. 當(dāng)目標(biāo)從機(jī)接收到第一個(gè)字節(jié), 因?yàn)榈?位數(shù)據(jù)為1所有從機(jī)將中斷。目標(biāo)從機(jī)比較自身地址并且清SM2 位等待接收后面的數(shù)據(jù)。其它從機(jī)則繼續(xù)正常運(yùn)行。
5. 接收到所有數(shù)據(jù)后,置 SM2 為 1 等待下一地址。
SM2 在模式 0 下無(wú)效。若 SM2 置 1,模式1可用于檢測(cè)有效的停止位。同時(shí)將不會(huì)產(chǎn)生中斷除非有效停止位已經(jīng)接收。
13.8 自動(dòng)地址識(shí)別
自動(dòng)地址識(shí)別功能提高了多機(jī)通訊功能,允許UART通過(guò)硬件比較,來(lái)識(shí)別特別的地址信息在接收的比特流中。該功能可以節(jié)省軟件識(shí)別地址而所占用的程序空間,僅當(dāng)串口識(shí)別到自身地址時(shí),接收器置位RI位并請(qǐng)求中斷。當(dāng)多機(jī)通信特征使能時(shí)(SM2置位),就使能自動(dòng)地址識(shí)別。
如果需要,用戶(hù)可以在模式1下使能自動(dòng)地址識(shí)別功能。在這種配置下,停止位取代第九位的數(shù)據(jù)位。僅當(dāng)接收命令的幀地址與器件地址匹配和有效的停止位時(shí),RI置位。
使用自動(dòng)地址識(shí)別功能,允許一個(gè)主機(jī)通過(guò)從機(jī)地址選擇性與一個(gè)或幾個(gè)從機(jī)通信。所有從機(jī)可以通過(guò)“廣播”地址聯(lián)系。有兩個(gè)特殊功能寄存器用于定義從機(jī)地址 SADDR和從機(jī)地址掩碼SADEN。 SADEN 用于定義SADDR的哪些位被用,哪些位不必關(guān)心. SADEN掩碼可以與SADDR以“邏輯與”的方式以創(chuàng)建每個(gè)從機(jī)的“Given” 地址。使用 “Given”地址允許多從機(jī)被識(shí)別。
下列范例用以說(shuō)明該功能的靈活應(yīng)用
范例 1, 從機(jī) 0:
SADDR = 11000000b
SADEN = 11111101b
Given = 110000X0b
范例 2, 從機(jī) 1:
SADDR = 11000000b
SADEN = 11111110b
Given = 1100000Xb
在上面的例子中SADDR是相同的,SADEN的數(shù)據(jù)用于區(qū)分兩個(gè)從機(jī)。從機(jī)0要求位0為” ”而忽略位1,從機(jī)1要求位1為” ”而位0被忽略。一個(gè)從機(jī)0唯一的地址11000010B,由于從機(jī)1要求位1為0。一個(gè)從機(jī)1唯一的地址將自1位11000001b將排除從機(jī)0。這兩個(gè)從機(jī)可以選擇在同一時(shí)間,地址位0 = 0(從機(jī)0)和第1位= 0(從機(jī)1)。因此,使用廣播地址(Boadcast address) 11000000b就可以同時(shí)尋址。
更復(fù)雜應(yīng)用可用于排除從機(jī)0之后,選擇從機(jī)1或2:
范例 1, 從機(jī) 0:
SADDR = 11000000b
SADEN = 11111001b
Given = 11000XX0b
范例 2, 從機(jī) 1:
SADDR = 11100000b
SADEN = 11111010b
Given = 11100X0Xb
范例 3, 從機(jī) 2:
SADDR = 11000000b
SADEN = 11111100b
Given = 110000XXb
在上面的例子中,3個(gè)從機(jī)的分別是在地址的低3位。從機(jī)0要求位0 = 0,它可用11100110b解決。從機(jī)1要求位1= 0,它可用11100101b識(shí)別。從機(jī)2要求位2= 0,其獨(dú)立的地址是11100011b。要選擇從機(jī)0和1,去除從機(jī)2,可使用地址11100100b,因?yàn)樗潜匾牡?位= 1來(lái)排除從機(jī)2。
每個(gè)從機(jī)的“廣播”地址的計(jì)算是通過(guò)邏輯或SADDR和SADEN。結(jié)果中的零位被視為“無(wú)關(guān)”位。例如:
SADDR = 01010110b
SADEN = 11111100b
Broadcast = 1111111Xb
使用“無(wú)關(guān)”位可在廣播模式下,提供更靈活的應(yīng)用。不過(guò)在大部分應(yīng)用條件下,廣播地址全部使用FFH。
復(fù)位后,SADDR和SADEN初始化為00H。這將對(duì)于所有“無(wú)關(guān)”地址產(chǎn)生一個(gè)“Given”地址,以及一個(gè)“廣播”地址對(duì)應(yīng)所有XXXXXXXXb地址(所有“無(wú)關(guān)”位)。這樣有效地禁止了自動(dòng)尋址模式,允許微控制器保持標(biāo)準(zhǔn)串口模式而不使用這個(gè)功能。
N76E003屬于增強(qiáng)型51內(nèi)核單片機(jī),一般這種都是提供簡(jiǎn)單的串口UART使用的。
那么我們先看這個(gè)單片機(jī)一共幾個(gè)串口。
手冊(cè)中提到:N76E003包含兩個(gè)具備增強(qiáng)的自動(dòng)地址識(shí)別和幀錯(cuò)誤檢測(cè)功能的全雙工串口。也就是2個(gè)串口。分別叫串口0和串口1.
我們也可以從手冊(cè)發(fā)現(xiàn)每個(gè)串口具備4種模式,見(jiàn)下表
官方有提供的例程來(lái)操作這兩個(gè)串口,全部是最常用的模式1
串口0可以使用定時(shí)器1或者定時(shí)器3產(chǎn)生波特率,并提供了對(duì)應(yīng)的收發(fā)函數(shù)
串口1可以使用定時(shí)器3產(chǎn)生波特率,并提供了對(duì)應(yīng)的收發(fā)函數(shù)。
基本上大家也用不上其他模式的。常規(guī)的應(yīng)用足夠了,我至今還沒(méi)有用過(guò)串口的其他模式。
如果需要,可以參考這個(gè)庫(kù)函數(shù)進(jìn)行對(duì)應(yīng)的寄存器修改。
關(guān)于波特率,我在定時(shí)器的博客上有描述
#include "N76E003.h" #include "Common.h" #include "Delay.h" #include "SFR_Macro.h" #include "Function_define.h" /****************************************************************************** * FUNCTION_PURPOSE: Serial interrupt, echo received data. * FUNCTION_INPUTS : P0.7(RXD) serial input * FUNCTION_OUTPUTS: P0.6(TXD) serial output * Following setting in Common.c ******************************************************************************/ #if 0 //void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1 //{ // P06_Quasi_Mode; // P07_Quasi_Mode; // // SCON = 0x52; //UART0 Mode1,REN=1,TI=1 // TMOD |= 0x20; //Timer1 Mode1 // // set_SMOD; //UART0 Double Rate Enable // set_T1M; // clr_BRCK; //Serial port 0 baud rate clock source = Timer1 // //#ifdef FOSC_160000 // TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */ //#endif // set_TR1; //} ////--------------------------------------------------------------- //void InitialUART0_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator //{ // P06_Quasi_Mode; // P07_Quasi_Mode; // // SCON = 0x52; //UART0 Mode1,REN=1,TI=1 // set_SMOD; //UART0 Double Rate Enable // T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1) // set_BRCK; //UART0 baud rate clock source = Timer3 //#ifdef FOSC_160000 // RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ // RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ //#endif // set_TR3; //Trigger Timer3 //} #endif /******************************************************************************* * FUNCTION_PURPOSE: Main function ******************************************************************************/ void main (void) { #if 0 InitialUART0_Timer1(9600); //UART0 Baudrate initial,T1M=0,SMOD=0 while(1) Send_Data_To_UART0(0x55); #else InitialUART0_Timer3(115200); while(1) Send_Data_To_UART0(0x55); #endif }
//void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1 //{ // P06_Quasi_Mode; // P07_Quasi_Mode; // // SCON = 0x52; //UART0 Mode1,REN=1,TI=1 // TMOD |= 0x20; //Timer1 Mode1 // // set_SMOD; //UART0 Double Rate Enable // set_T1M; // clr_BRCK; //Serial port 0 baud rate clock source = Timer1 // //#ifdef FOSC_160000 // TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */ //#endif // set_TR1; //}
SCON = 0x52; //01010010 SM0=0,SM1=1即為模式一,REN=1,打開(kāi)串口0在模式1,2或3模式下的接收功能。TI=1串口發(fā)送中斷標(biāo)志位,在發(fā)送到數(shù)據(jù)最后一位后由硬件置位。當(dāng)串口0中斷使能,將執(zhí)行中斷服務(wù)程序。該位必須由軟件來(lái)清除。
TMOD |= 0x20; //Timer1 Mode2
set_SMOD;
#define set_SMOD PCON |= SET_BIT7
#define SET_BIT7 0x80
#define set_T1M CKCON |= SET_BIT4
#define set_BRCK T3CON |= SET_BIT5
#ifdef FOSC_160000
TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
#endif
#ifdef FOSC_166000
TH1 = 256 - (1037500/u32Baudrate); /*16.6 MHz */
#endif
set_TR1;
set_TI; //For printf function must setting TI = 1
}
方式1的波特率= 即 (2^smod /32)*T1的溢出率,即 ((2^smod /32)*16000000)/(256-x)
通常都是固定的,一般都是根據(jù)所使用的波特率來(lái)求定時(shí)器初值。
TH1 = 256 - (1000000/u32Baudrate+1); 256-TH1-1=1000000/u32Baudrate u32Baudrate=1000000/(256-TH1-1)
set_TR1;
set_TI; //For printf function must setting TI = 1
void Send_Data_To_UART0 (UINT8 c) { TI = 0; SBUF = c; while(TI==0); }
下面這個(gè)是一個(gè)串口零模式1的小案例
#include <stdio.h> #include "N76E003.h" #include "Common.h" #include "Delay.h" #include "SFR_Macro.h" #include "Function_Define.h" /****************************************************************************** * FUNCTION_PURPOSE: Serial interrupt, echo received data. * FUNCTION_INPUTS : P0.7(RXD) serial input * FUNCTION_OUTPUTS: P0.6(TXD) serial output * Following setting in Common.c ******************************************************************************/ #if 0 //void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1 //{ // P06_Quasi_Mode; // P07_Quasi_Mode; // // SCON = 0x52; //UART0 Mode1,REN=1,TI=1 // TMOD |= 0x20; //Timer1 Mode1 // // set_SMOD; //UART0 Double Rate Enable // set_T1M; // clr_BRCK; //Serial port 0 baud rate clock source = Timer1 // //#ifdef FOSC_160000 // TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */ //#endif // set_TR1; //} ////--------------------------------------------------------------- //void InitialUART0_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator //{ // P06_Quasi_Mode; // P07_Quasi_Mode; // // SCON = 0x52; //UART0 Mode1,REN=1,TI=1 // set_SMOD; //UART0 Double Rate Enable // T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1) // set_BRCK; //UART0 baud rate clock source = Timer3 //#ifdef FOSC_160000 // RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ // RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ //#endif // set_TR3; //Trigger Timer3 //} #endif void DelayTime(UINT32 u32CNT) { UINT32 i; i=u32CNT; while(i--); } /******************************************************************************* * FUNCTION_PURPOSE: Main function ******************************************************************************/ void main (void) { #if 1 InitialUART0_Timer1(9600); //UART0 Baudrate from Timer1 while(1) { Send_Data_To_UART0(0x33); Timer0_Delay1ms(500);//Ñóê±500mS } #else InitialUART0_Timer3(115200); //UART0 Baudrate from Timer3 while(1) { Send_Data_To_UART0(0x55); Timer0_Delay1ms(500); //Ñóê±500mS } #endif }
串口0可選定時(shí)器3或定時(shí)器1,我們?cè)倏匆幌,串口?模式三
模式2為全雙工異步通信, 模式2是11位收發(fā)。數(shù)據(jù)由起始位(邏輯0),8位數(shù)據(jù)(最低位在前),第9位數(shù)據(jù)(TB8或RB8)和停止位(邏輯1)組成。第9位做奇偶校驗(yàn)位或多機(jī)通信時(shí)用來(lái)區(qū)分?jǐn)?shù)據(jù)和地址。波特率是系統(tǒng)時(shí)鐘頻率的1/32 或1/64,由 SMOD位(PCON.7)來(lái)配置。圖13?3 指示串口模式2的傳輸時(shí)序。
串口零模式三 要采用定時(shí)器1做時(shí)鐘。
#include "N76E003.h" #include "SFR_Macro.h" #include "Common.h" #include "Delay.h" #include "Function_define.h" #define BUFFER_SIZE 16 UINT8 UART_BUFFER[BUFFER_SIZE],temp; UINT16 u16CNT=0,u16CNT1=0; bit riflag; /** * FUNCTION_PURPOSE: serial interrupt, echo received data. * FUNCTION_INPUTS: P0.7(RXD) serial input * FUNCTION_OUTPUTS: P0.6(TXD) serial output */ void SerialPort0_ISR(void) interrupt 4 { if (RI==1) { /* if reception occur */ clr_RI; /* clear reception flag for next reception */ UART_BUFFER[u16CNT] = SBUF; u16CNT ++; riflag =1; } if(TI==1) { clr_TI; /* if emission occur */ } } /************************************************************************************************************ * Main function ************************************************************************************************************/ void main (void) { P12_PushPull_Mode; P06_Quasi_Mode; P07_Quasi_Mode; SCON = 0xD0; // Special setting the mode 3 and TMOD |= 0x20; //Timer1 Mode1 set_SMOD; //UART0 Double Rate Enable set_T1M; //sys clk clr_BRCK; //Serial port 0 baud rate clock source = Timer1 TH1 = 256 - (1000000/115200+1); /*16 MHz */ set_TR1; set_RB8; //This bit is for setting the stop bit 2 high/low status, clr_TI; set_ES; //enable UART interrupt set_EA; //enable global interrupt while(1) { if (riflag) { P12 = ~P12; //In debug mode check UART_BUFFER[u16CNT] to check receive data riflag = 0; } } }
接下來(lái),是串口一,對(duì)于串口1,只有采用定時(shí)器3作為唯一的時(shí)鐘源。
#include "N76E003.h" #include "Common.h" #include "Delay.h" #include "SFR_Macro.h" #include "Function_define.h" #define BUFFER_SIZE 16 UINT8 UART_BUFFER[BUFFER_SIZE],temp; UINT16 u16CNT=0,u16CNT1=0; bit riflag; /****************************************************************************** * FUNCTION_PURPOSE: Serial port 1 interrupt, echo received data. * FUNCTION_INPUTS : P0.2(RXD) serial input * FUNCTION_OUTPUTS: P1.6(TXD) serial output * Following setting in Common.c ******************************************************************************/ #if 0 //void InitialUART1_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator //{ // P02_Quasi_Mode; //Setting UART pin as Quasi mode for transmit // P16_Quasi_Mode; //Setting UART pin as Quasi mode for transmit // // SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1 // T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1 // clr_BRCK; // //#ifdef FOSC_160000 // RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ // RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ //#endif //#ifdef FOSC_166000 // RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */ // RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */ //#endif // set_TR3; //Trigger Timer3 //} #endif void SerialPort1_ISR(void) interrupt 15 { if (RI_1==1) { /* if reception occur */ clr_RI_1; /* clear reception flag for next reception */ UART_BUFFER[u16CNT] = SBUF_1; u16CNT ++; riflag =1; } if(TI_1==1) { clr_TI_1; /* if emission occur */ } } /**************************************************************************************************************** * FUNCTION_PURPOSE: Main function !!! N76E003 UART1 pin also occupied by debug pin, please remove Nu-link or not in debug mode to test UART1 function. External UART1 connect also disturb debug download ***************************************************************************************************************/ void main (void) { P12_PushPull_Mode; // For I/O toggle display #if 0 //for Simple use UART1 transmit out InitialUART1_Timer3(115200); while(1) Send_Data_To_UART1(0x55); #else // For interrupt setting check receive InitialUART1_Timer3(115200); set_ES_1; //For interrupt enable set_EA; while(1) { if (riflag) { P12 = ~ P12; //Receive each byte P12 toggle, never work under debug mode riflag = 0; } } #endif }
void InitialUART1_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator { P02_Quasi_Mode; //Setting UART pin as Quasi mode for transmit P16_Quasi_Mode; //Setting UART pin as Quasi mode for transmit SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1 T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1 clr_BRCK; #ifdef FOSC_160000 RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */ #endif #ifdef FOSC_166000 RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */ RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */ #endif set_TR3; //Trigger Timer3 }
SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1
T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1
#ifdef FOSC_160000
RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
#endif
#ifdef FOSC_166000
RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
#endif
set_TR3; //Trigger Timer3
set_ES_1; //For interrupt enable
set_EA;
串口1只能用定時(shí)器3,串口0只能做定時(shí)器1或3,但是串口0模式三只能用定時(shí)器1,串口零其他模式正常
還有一個(gè)比較重要的問(wèn)題,由于ICP燒錄的時(shí)候,與串口一是重合的,由于是引腳復(fù)用的關(guān)系,所以串口功能發(fā)生作用時(shí),就會(huì)出現(xiàn)燒錄不進(jìn)去的情況,這時(shí)只需要讓串口收發(fā)不了數(shù)據(jù)就能燒錄程序了。
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬(wàn)眾潤(rùn)豐創(chuàng)業(yè)園A棟2樓A08