您好,歡迎進入深圳市穎特新科技有限公司官方網(wǎng)站!
N76E003包含兩個具備增強的自動地址識別和幀錯誤檢測功能的全雙工串口。由于兩個串口的控制位是一樣的,為了區(qū)分兩個串口控制位,串口1的控制位以“_1”結(jié)尾(例如SCON_1)。下述詳例以串口0為例。
每個串口都有一種同步工作模式:模式0。三種全雙工異步模式:模式1,2,和3,這意味著收發(fā)可以同時連續(xù)進行。串口接收帶有接收緩存,意味著在接收的前一個數(shù)據(jù)在被讀取之前,串口就能接收第二個數(shù)據(jù)。接收和發(fā)送都是對SBUF進行操作訪問,寫入SBUF數(shù)據(jù)將直接傳到發(fā)送寄存器,而讀取SBUF是訪問一個具有獨立物理地址的接收寄存器。串口共有4種操作模式,任何一種模式,任何以操作SBUF的指令都將開始一次傳輸。注意,在使用串口功能前,串口所用管腳P0.7及 P0.6 (RXD 及 TXD引腳) 或者 P0.2及 P1.6 (RXD_1 及 TXD_1)必須先置1。N76E003提供更靈活的管腳配置,可將串口0的TXD及RXD通過UART0PX (AUXR1.2)更改位置。
13.1 模式 0
模式0是與外部設(shè)備進行同步通信的方式。在該模式下,串行數(shù)據(jù)由RXD腳進行收發(fā),而TXD 腳用于產(chǎn)生移位時鐘。這種方式下是以半雙工的形式進行通信,每幀接收或發(fā)送8位數(shù)據(jù)。數(shù)據(jù)的最低位被最先發(fā)送或接收,波特率設(shè)置為FSYS/12(SM2 (SCON.5) 為 0) 或 FSYS/2 (SM2 為 1)。無論發(fā)送或接收數(shù)據(jù),串行時鐘將一直由MCU產(chǎn)生,因此串口模式 0 為主機模式。圖13?1 顯示串口模式0傳輸時序圖
如圖所示,數(shù)據(jù)由雙向RXD引腳進行收發(fā),TXD引腳用來輸出移位時鐘。串口用移位時鐘來一位位接收/發(fā)送數(shù)據(jù)與其他串口通訊。數(shù)據(jù)移入移出由最低位開始,波特率等于TXD的移位時鐘頻率。
向SBUF的寫入數(shù)據(jù)將會開啟發(fā)送,此時移位時鐘啟動數(shù)據(jù)從RXD腳串行移出,直至8位數(shù)據(jù)傳輸完成。傳輸標(biāo)志位TI (SCON.1) 置 1表示 1 個字節(jié)數(shù)據(jù)傳輸完成。
當(dāng)REN (SCON.4)=1 且 RI(SCON.0)=0 時串口開始接收數(shù)據(jù)。該條件告訴串口控制器有數(shù)據(jù)要移位進入。這個過程將持續(xù)到8位數(shù)據(jù)接收完畢,然后接收標(biāo)志RI將置1。用戶可以清零RI,以觸發(fā)接收下一字節(jié)數(shù)據(jù)。
13.2 模式 1
模式1為異步全雙工的工作方式。異步通訊模式通常用于PC間,調(diào)制解調(diào)器和其它類似接口間通訊。模式1下,10位數(shù)據(jù)通過TXD發(fā)送,通過RXD接收。10位數(shù)據(jù)組成如下:起始位(邏輯0),8位數(shù)據(jù)(最低位在前),停止位(邏輯1)。波特率由定時器1決定, SMOD (PCON.7) 設(shè)置為1可使波特率加倍.圖13?2為串口模式1發(fā)送和接收的時序圖.
向SBUF寫入數(shù)據(jù)開始傳輸,傳輸發(fā)生在TXD引腳上。首先是開始位,隨后是8位數(shù)據(jù)位,最后是停止位。停止位出現(xiàn)后,TI(SCON.1)將置1 表示一個字節(jié)傳輸完成,所有位的傳輸速度取決于波特率。
當(dāng)波特率發(fā)生器激活且REN(SCON.4) =1時,系統(tǒng)可以隨時開始接收操作,當(dāng)RXD腳上偵測到1到0的跳變時,數(shù)據(jù)將開始被采樣并根據(jù)波特率的時鐘頻率接收,停止位必須符合一定的條件,接收到數(shù)據(jù)才能裝載到SBUF:
1. RI (SCON.0) = 0
2. 要么SM2 (SCON.5) = 0, 要么接收到停止位STOP= 1,同時SM2 = 1且被尋址“Given”或符合廣播地址(Broadcast address)匹配時。詳見 13.7 多機通訊 和 13.8 自動地址識別。
如果上述條件滿足,SBUF將加載到接收數(shù)據(jù),RB8(SCON.2)為停止位,和RI將被置1,如果條件不滿足,RI保持為0,沒有數(shù)據(jù)加載。完成接收過程后,串口控制器將等待RXD腳上出現(xiàn)另一個1-0傳輸以開始新的數(shù)據(jù)接收。
13.3 模式 2
模式2為全雙工異步通信, 與模式1不同的是,模式2是11位收發(fā)。數(shù)據(jù)由起始位(邏輯0),8位數(shù)據(jù)(最低位在前),第9位數(shù)據(jù)(TB8或RB8)和停止位(邏輯1)組成。第9位做奇偶校驗位或多機通信時用來區(qū)分?jǐn)?shù)據(jù)和地址。波特率是系統(tǒng)時鐘頻率的1/32 或1/64,由 SMOD位(PCON.7)來配置。圖13?3 指示串口模式2的傳輸時序。
向SBUF中寫入數(shù)據(jù)啟動TXD引腳發(fā)送,首先是開始位,然后是8位數(shù)據(jù)和TB8(SCON.3),最后是停止位,停止位發(fā)送后,TI將置位標(biāo)志傳輸完成。
當(dāng)REN=1時,串口可進行接收操作。RXD上的下降沿表示接收過程開始,數(shù)據(jù)根據(jù)所配置波特率進行采樣和接收。停止位必須符合一定的條件,接收到數(shù)據(jù)才能裝載到SBUF:
1. RI (SCON.0) = 0,
2. 要么SM2(SCON.5) = 0, 要么9th位 = 1同時 SM2 = 1且被尋址“Given”或符合廣播地址(Broadcast address)匹配。詳見 13.7 多機通訊 和 13.8 自動地址識別。
如果上述條件滿足,則第9位數(shù)據(jù)進入RB8(SCON.2),8位數(shù)據(jù)進入SBUF,且RI置位。否則數(shù)據(jù)將不會裝載,且RI保持為0。完成接收過程后,串口控制器等待RXD腳上的另一個1-0跳變以開始新的數(shù)據(jù)接收。
13.4 模式 3
除波特率外模式 3與模式 2相同。模式3采用定時器1的溢出率作為波特率時鐘。圖13?3 模式3的傳輸時序,與模式2沒有不同。
13.5 波特率
串口的不同模式的波特率時鐘源和速度是完全不同的。詳見表 13–3. 用于設(shè)定不同的波特率。
在模式1或模式3,串口0的波特率時鐘源可通過BRCK (T3CON.5)選擇定時器1或定時器3。對于串口1,只有采用定時器3作為唯一的時鐘源。
當(dāng)采用定時器1作為波特率發(fā)生器,需要關(guān)閉定時器1中斷。定時器1可配置為計數(shù)器或是定時器,三種工作模式都可以。典型應(yīng)用中,會配置為定時器工作在自動重裝載模式(定時器模式2)。如果采用定時器3作為波特率發(fā)生器,同樣也需要關(guān)閉定時器3中斷。
模式1和模式3的波特率是可變的,取決于定時器1或2(003芯片)的溢出速率,就是說定時器1每溢出一次,串口發(fā)送一次數(shù)據(jù)。那么我們怎么去計算這兩個模式的波特率設(shè)置時相關(guān)的寄存器的值呢?可以用公式去計算。
13.6 幀錯誤檢測
幀錯誤檢測用于異步模式 (模式 1, 2 和 3)。當(dāng)由于總線干擾或爭奪,導(dǎo)致沒有檢測到有效的停止位時,將發(fā)生幀錯誤。串口可以檢測幀錯誤,并通過軟件提示出錯。
FE為幀錯誤標(biāo)志,位于SCON第7位,這個位正常被用作為SM0 。當(dāng)SMOD0 (PCON.6)置1時,幀錯誤檢測功能打開,它作為FE標(biāo)志。SM0和FE其實是相互獨立的標(biāo)志位。
當(dāng)幀錯誤發(fā)生時,F(xiàn)E標(biāo)志由硬件置位。如果必要,F(xiàn)E可在串口中斷程序中檢測。注意在對FE標(biāo)志位進行讀寫時,同時SMOD0必須為1。如果FE被置位,那么下次即使接收到的正確數(shù)據(jù)幀也不會將其清除。對該位的清除必須由軟件來完成。
13.7 多機通訊
N76E003串口支持多機通訊,可讓一個主機(master device)向多個從機(slave device)發(fā)送多幀序列信息。在同一串行線上使用該功能過程中不需要中斷其它從機設(shè)備工作。該功能只能在模式2或模式3下進行。用戶設(shè)置SM2(SCON.5)為1打開這個功能,以便當(dāng)一個數(shù)據(jù)幀接收后,當(dāng)?shù)?位為1時,串口中斷將產(chǎn)生(模式2下,第9位為停止位)。當(dāng)SM2為1時,如果第9位為0,不會發(fā)生中斷。在該情況下,第9位能簡單的把從機地址和數(shù)據(jù)分開。
當(dāng)主機需要向多個從機中的一個發(fā)送數(shù)據(jù)時,首先需要發(fā)送目標(biāo)從機的地址。注,地址字節(jié)與數(shù)據(jù)字節(jié)是不同的:在地址字節(jié)中,第9位為1。而數(shù)據(jù)字節(jié)中第9位為0。地址字節(jié)會觸發(fā)所有從機,而每臺從機檢查接收到的
地址是否與自身匹配。地址匹配的從機,清除SM2,準(zhǔn)備接收數(shù)據(jù);未被尋址到的從機的SM2 必須保持,從而系統(tǒng)會持續(xù)工作,同時忽略接收數(shù)據(jù)。.
配置多機通信步驟如下:
1. 設(shè)置所有設(shè)備(主機與從機)為串口模式2或3;
2. 所有從機 SM2 位置為1;
3. 主機傳輸協(xié)議:
– 第一個字節(jié):地址,目標(biāo)從機地址 (第9位 = 1)
– 下一個字節(jié):數(shù)據(jù), (第9位 = 0)。
4. 當(dāng)目標(biāo)從機接收到第一個字節(jié), 因為第9位數(shù)據(jù)為1所有從機將中斷。目標(biāo)從機比較自身地址并且清SM2 位等待接收后面的數(shù)據(jù)。其它從機則繼續(xù)正常運行。
5. 接收到所有數(shù)據(jù)后,置 SM2 為 1 等待下一地址。
SM2 在模式 0 下無效。若 SM2 置 1,模式1可用于檢測有效的停止位。同時將不會產(chǎn)生中斷除非有效停止位已經(jīng)接收。
13.8 自動地址識別
自動地址識別功能提高了多機通訊功能,允許UART通過硬件比較,來識別特別的地址信息在接收的比特流中。該功能可以節(jié)省軟件識別地址而所占用的程序空間,僅當(dāng)串口識別到自身地址時,接收器置位RI位并請求中斷。當(dāng)多機通信特征使能時(SM2置位),就使能自動地址識別。
如果需要,用戶可以在模式1下使能自動地址識別功能。在這種配置下,停止位取代第九位的數(shù)據(jù)位。僅當(dāng)接收命令的幀地址與器件地址匹配和有效的停止位時,RI置位。
使用自動地址識別功能,允許一個主機通過從機地址選擇性與一個或幾個從機通信。所有從機可以通過“廣播”地址聯(lián)系。有兩個特殊功能寄存器用于定義從機地址 SADDR和從機地址掩碼SADEN。 SADEN 用于定義SADDR的哪些位被用,哪些位不必關(guān)心. SADEN掩碼可以與SADDR以“邏輯與”的方式以創(chuàng)建每個從機的“Given” 地址。使用 “Given”地址允許多從機被識別。
下列范例用以說明該功能的靈活應(yīng)用
范例 1, 從機 0:
SADDR = 11000000b
SADEN = 11111101b
Given = 110000X0b
范例 2, 從機 1:
SADDR = 11000000b
SADEN = 11111110b
Given = 1100000Xb
在上面的例子中SADDR是相同的,SADEN的數(shù)據(jù)用于區(qū)分兩個從機。從機0要求位0為” ”而忽略位1,從機1要求位1為” ”而位0被忽略。一個從機0唯一的地址11000010B,由于從機1要求位1為0。一個從機1唯一的地址將自1位11000001b將排除從機0。這兩個從機可以選擇在同一時間,地址位0 = 0(從機0)和第1位= 0(從機1)。因此,使用廣播地址(Boadcast address) 11000000b就可以同時尋址。
更復(fù)雜應(yīng)用可用于排除從機0之后,選擇從機1或2:
范例 1, 從機 0:
SADDR = 11000000b
SADEN = 11111001b
Given = 11000XX0b
范例 2, 從機 1:
SADDR = 11100000b
SADEN = 11111010b
Given = 11100X0Xb
范例 3, 從機 2:
SADDR = 11000000b
SADEN = 11111100b
Given = 110000XXb
在上面的例子中,3個從機的分別是在地址的低3位。從機0要求位0 = 0,它可用11100110b解決。從機1要求位1= 0,它可用11100101b識別。從機2要求位2= 0,其獨立的地址是11100011b。要選擇從機0和1,去除從機2,可使用地址11100100b,因為它是必要的第2位= 1來排除從機2。
每個從機的“廣播”地址的計算是通過邏輯或SADDR和SADEN。結(jié)果中的零位被視為“無關(guān)”位。例如:
SADDR = 01010110b
SADEN = 11111100b
Broadcast = 1111111Xb
使用“無關(guān)”位可在廣播模式下,提供更靈活的應(yīng)用。不過在大部分應(yīng)用條件下,廣播地址全部使用FFH。
復(fù)位后,SADDR和SADEN初始化為00H。這將對于所有“無關(guān)”地址產(chǎn)生一個“Given”地址,以及一個“廣播”地址對應(yīng)所有XXXXXXXXb地址(所有“無關(guān)”位)。這樣有效地禁止了自動尋址模式,允許微控制器保持標(biāo)準(zhǔn)串口模式而不使用這個功能。
N76E003屬于增強型51內(nèi)核單片機,一般這種都是提供簡單的串口UART使用的。
那么我們先看這個單片機一共幾個串口。
手冊中提到:N76E003包含兩個具備增強的自動地址識別和幀錯誤檢測功能的全雙工串口。也就是2個串口。分別叫串口0和串口1.
我們也可以從手冊發(fā)現(xiàn)每個串口具備4種模式,見下表
官方有提供的例程來操作這兩個串口,全部是最常用的模式1
串口0可以使用定時器1或者定時器3產(chǎn)生波特率,并提供了對應(yīng)的收發(fā)函數(shù)
串口1可以使用定時器3產(chǎn)生波特率,并提供了對應(yīng)的收發(fā)函數(shù)。
基本上大家也用不上其他模式的。常規(guī)的應(yīng)用足夠了,我至今還沒有用過串口的其他模式。
如果需要,可以參考這個庫函數(shù)進行對應(yīng)的寄存器修改。
關(guān)于波特率,我在定時器的博客上有描述
#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,打開串口0在模式1,2或3模式下的接收功能。TI=1串口發(fā)送中斷標(biāo)志位,在發(fā)送到數(shù)據(jù)最后一位后由硬件置位。當(dāng)串口0中斷使能,將執(zhí)行中斷服務(wù)程序。該位必須由軟件來清除。
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ù)所使用的波特率來求定時器初值。
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); }
下面這個是一個串口零模式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可選定時器3或定時器1,我們再看一下,串口零 模式三
模式2為全雙工異步通信, 模式2是11位收發(fā)。數(shù)據(jù)由起始位(邏輯0),8位數(shù)據(jù)(最低位在前),第9位數(shù)據(jù)(TB8或RB8)和停止位(邏輯1)組成。第9位做奇偶校驗位或多機通信時用來區(qū)分?jǐn)?shù)據(jù)和地址。波特率是系統(tǒng)時鐘頻率的1/32 或1/64,由 SMOD位(PCON.7)來配置。圖13?3 指示串口模式2的傳輸時序。
串口零模式三 要采用定時器1做時鐘。
#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; } } }
接下來,是串口一,對于串口1,只有采用定時器3作為唯一的時鐘源。
#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只能用定時器3,串口0只能做定時器1或3,但是串口0模式三只能用定時器1,串口零其他模式正常
還有一個比較重要的問題,由于ICP燒錄的時候,與串口一是重合的,由于是引腳復(fù)用的關(guān)系,所以串口功能發(fā)生作用時,就會出現(xiàn)燒錄不進去的情況,這時只需要讓串口收發(fā)不了數(shù)據(jù)就能燒錄程序了。
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08