N76E003之串口


N76E003包含兩個具備增強的自動地址識別和幀錯誤檢測功能的全雙工串口。由於兩個串口的控制位是一樣的,為了區分兩個串口控制位,串口1的控制位以“_1”結尾(例如SCON_1)。下述詳例以串口0為例。
每個串口都有一種同步工作模式:模式0。三種全雙工異步模式:模式1,2,和3,這意味着收發可以同時連續進行。串口接收帶有接收緩存,意味着在接收的前一個數據在被讀取之前,串口就能接收第二個數據。接收和發送都是對SBUF進行操作訪問,寫入SBUF數據將直接傳到發送寄存器,而讀取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是與外部設備進行同步通信的方式。在該模式下,串行數據由RXD腳進行收發,而TXD 腳用於產生移位時鍾。這種方式下是以半雙工的形式進行通信,每幀接收或發送8位數據。數據的最低位被最先發送或接收,波特率設置為FSYS/12(SM2 (SCON.5) 為 0) 或 FSYS/2 (SM2 為 1)。無論發送或接收數據,串行時鍾將一直由MCU產生,因此串口模式 0 為主機模式。圖13‑1 顯示串口模式0傳輸時序圖

 

如圖所示,數據由雙向RXD引腳進行收發,TXD引腳用來輸出移位時鍾。串口用移位時鍾來一位位接收/發送數據與其他串口通訊。數據移入移出由最低位開始,波特率等於TXD的移位時鍾頻率。

 

 

 

向SBUF的寫入數據將會開啟發送,此時移位時鍾啟動數據從RXD腳串行移出,直至8位數據傳輸完成。傳輸標志位TI (SCON.1) 置 1表示 1 個字節數據傳輸完成。
當REN (SCON.4)=1 且 RI(SCON.0)=0 時串口開始接收數據。該條件告訴串口控制器有數據要移位進入。這個過程將持續到8位數據接收完畢,然后接收標志RI將置1。用戶可以清零RI,以觸發接收下一字節數據。

 

13.2 模式 1
模式1為異步全雙工的工作方式。異步通訊模式通常用於PC間,調制解調器和其它類似接口間通訊。模式1下,10位數據通過TXD發送,通過RXD接收。10位數據組成如下:起始位(邏輯0),8位數據(最低位在前),停止位(邏輯1)。波特率由定時器1決定, SMOD (PCON.7) 設置為1可使波特率加倍.圖13‑2為串口模式1發送和接收的時序圖.

向SBUF寫入數據開始傳輸,傳輸發生在TXD引腳上。首先是開始位,隨后是8位數據位,最后是停止位。停止位出現后,TI(SCON.1)將置1 表示一個字節傳輸完成,所有位的傳輸速度取決於波特率。
當波特率發生器激活且REN(SCON.4) =1時,系統可以隨時開始接收操作,當RXD腳上偵測到1到0的跳變時,數據將開始被采樣並根據波特率的時鍾頻率接收,停止位必須符合一定的條件,接收到數據才能裝載到SBUF:

1. RI (SCON.0) = 0

2. 要么SM2 (SCON.5) = 0, 要么接收到停止位STOP= 1,同時SM2 = 1且被尋址“Given”或符合廣播地址(Broadcast address)匹配時。詳見 13.7 多機通訊 和 13.8 自動地址識別。
如果上述條件滿足,SBUF將加載到接收數據,RB8(SCON.2)為停止位,和RI將被置1,如果條件不滿足,RI保持為0,沒有數據加載。完成接收過程后,串口控制器將等待RXD腳上出現另一個1-0傳輸以開始新的數據接收。

13.3 模式 2
模式2為全雙工異步通信, 與模式1不同的是,模式2是11位收發。數據由起始位(邏輯0),8位數據(最低位在前),第9位數據(TB8或RB8)和停止位(邏輯1)組成。第9位做奇偶校驗位或多機通信時用來區分數據和地址。波特率是系統時鍾頻率的1/32 或1/64,由 SMOD位(PCON.7)來配置。圖13‑3 指示串口模式2的傳輸時序。

 

向SBUF中寫入數據啟動TXD引腳發送,首先是開始位,然后是8位數據和TB8(SCON.3),最后是停止位,停止位發送后,TI將置位標志傳輸完成。
當REN=1時,串口可進行接收操作。RXD上的下降沿表示接收過程開始,數據根據所配置波特率進行采樣和接收。停止位必須符合一定的條件,接收到數據才能裝載到SBUF:

1. RI (SCON.0) = 0,

2. 要么SM2(SCON.5) = 0, 要么9th位 = 1同時 SM2 = 1且被尋址“Given”或符合廣播地址(Broadcast address)匹配。詳見 13.7 多機通訊 和 13.8 自動地址識別。
如果上述條件滿足,則第9位數據進入RB8(SCON.2),8位數據進入SBUF,且RI置位。否則數據將不會裝載,且RI保持為0。完成接收過程后,串口控制器等待RXD腳上的另一個1-0跳變以開始新的數據接收。
13.4 模式 3
除波特率外模式 3與模式 2相同。模式3采用定時器1的溢出率作為波特率時鍾。圖13‑3 模式3的傳輸時序,與模式2沒有不同。

13.5 波特率
串口的不同模式的波特率時鍾源和速度是完全不同的。詳見表 13–3. 用於設定不同的波特率。
在模式1或模式3,串口0的波特率時鍾源可通過BRCK (T3CON.5)選擇定時器1或定時器3。對於串口1,只有采用定時器3作為唯一的時鍾源。

當采用定時器1作為波特率發生器,需要關閉定時器1中斷。定時器1可配置為計數器或是定時器,三種工作模式都可以。典型應用中,會配置為定時器工作在自動重裝載模式(定時器模式2)。如果采用定時器3作為波特率發生器,同樣也需要關閉定時器3中斷。

模式1和模式3的波特率是可變的,取決於定時器1或2(003芯片)的溢出速率,就是說定時器1每溢出一次,串口發送一次數據。那么我們怎么去計算這兩個模式的波特率設置時相關的寄存器的值呢?可以用公式去計算。  

13.6 幀錯誤檢測
幀錯誤檢測用於異步模式 (模式 1, 2 和 3)。當由於總線干擾或爭奪,導致沒有檢測到有效的停止位時,將發生幀錯誤。串口可以檢測幀錯誤,並通過軟件提示出錯。
FE為幀錯誤標志,位於SCON第7位,這個位正常被用作為SM0 。當SMOD0 (PCON.6)置1時,幀錯誤檢測功能打開,它作為FE標志。SM0和FE其實是相互獨立的標志位。
當幀錯誤發生時,FE標志由硬件置位。如果必要,FE可在串口中斷程序中檢測。注意在對FE標志位進行讀寫時,同時SMOD0必須為1。如果FE被置位,那么下次即使接收到的正確數據幀也不會將其清除。對該位的清除必須由軟件來完成。

 

13.7 多機通訊
N76E003串口支持多機通訊,可讓一個主機(master device)向多個從機(slave device)發送多幀序列信息。在同一串行線上使用該功能過程中不需要中斷其它從機設備工作。該功能只能在模式2或模式3下進行。用戶設置SM2(SCON.5)為1打開這個功能,以便當一個數據幀接收后,當第9位為1時,串口中斷將產生(模式2下,第9位為停止位)。當SM2為1時,如果第9位為0,不會發生中斷。在該情況下,第9位能簡單的把從機地址和數據分開。
當主機需要向多個從機中的一個發送數據時,首先需要發送目標從機的地址。注,地址字節與數據字節是不同的:在地址字節中,第9位為1。而數據字節中第9位為0。地址字節會觸發所有從機,而每台從機檢查接收到的

地址是否與自身匹配。地址匹配的從機,清除SM2,准備接收數據;未被尋址到的從機的SM2 必須保持,從而系統會持續工作,同時忽略接收數據。.
配置多機通信步驟如下:
1. 設置所有設備(主機與從機)為串口模式2或3;
2. 所有從機 SM2 位置為1;
3. 主機傳輸協議:
– 第一個字節:地址,目標從機地址 (第9位 = 1)
– 下一個字節:數據, (第9位 = 0)。
4. 當目標從機接收到第一個字節, 因為第9位數據為1所有從機將中斷。目標從機比較自身地址並且清SM2 位等待接收后面的數據。其它從機則繼續正常運行。

5. 接收到所有數據后,置 SM2 為 1 等待下一地址。
SM2 在模式 0 下無效。若 SM2 置 1,模式1可用於檢測有效的停止位。同時將不會產生中斷除非有效停止位已經接收。
13.8 自動地址識別
自動地址識別功能提高了多機通訊功能,允許UART通過硬件比較,來識別特別的地址信息在接收的比特流中。該功能可以節省軟件識別地址而所占用的程序空間,僅當串口識別到自身地址時,接收器置位RI位並請求中斷。當多機通信特征使能時(SM2置位),就使能自動地址識別。
如果需要,用戶可以在模式1下使能自動地址識別功能。在這種配置下,停止位取代第九位的數據位。僅當接收命令的幀地址與器件地址匹配和有效的停止位時,RI置位。

使用自動地址識別功能,允許一個主機通過從機地址選擇性與一個或幾個從機通信。所有從機可以通過“廣播”地址聯系。有兩個特殊功能寄存器用於定義從機地址 SADDR和從機地址掩碼SADEN。 SADEN 用於定義SADDR的哪些位被用,哪些位不必關心. SADEN掩碼可以與SADDR以“邏輯與”的方式以創建每個從機的“Given” 地址。使用 “Given”地址允許多從機被識別。

 

下列范例用以說明該功能的靈活應用
范例 1, 從機 0:
SADDR = 11000000b
SADEN = 11111101b
Given = 110000X0b
范例 2, 從機 1:
SADDR = 11000000b
SADEN = 11111110b
Given = 1100000Xb
在上面的例子中SADDR是相同的,SADEN的數據用於區分兩個從機。從機0要求位0為” ”而忽略位1,從機1要求位1為” ”而位0被忽略。一個從機0唯一的地址11000010B,由於從機1要求位1為0。一個從機1唯一的地址將自1位11000001b將排除從機0。這兩個從機可以選擇在同一時間,地址位0 = 0(從機0)和第1位= 0(從機1)。因此,使用廣播地址(Boadcast address) 11000000b就可以同時尋址。
更復雜應用可用於排除從機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。結果中的零位被視為“無關”位。例如:

SADDR = 01010110b
SADEN = 11111100b
Broadcast = 1111111Xb
使用“無關”位可在廣播模式下,提供更靈活的應用。不過在大部分應用條件下,廣播地址全部使用FFH。
復位后,SADDR和SADEN初始化為00H。這將對於所有“無關”地址產生一個“Given”地址,以及一個“廣播”地址對應所有XXXXXXXXb地址(所有“無關”位)。這樣有效地禁止了自動尋址模式,允許微控制器保持標准串口模式而不使用這個功能。

N76E003屬於增強型51內核單片機,一般這種都是提供簡單的串口UART使用的。
那么我們先看這個單片機一共幾個串口。
手冊中提到:N76E003包含兩個具備增強的自動地址識別和幀錯誤檢測功能的全雙工串口。也就是2個串口。分別叫串口0和串口1.
我們也可以從手冊發現每個串口具備4種模式,見下表

官方有提供的例程來操作這兩個串口,全部是最常用的模式1
串口0可以使用定時器1或者定時器3產生波特率,並提供了對應的收發函數
串口1可以使用定時器3產生波特率,並提供了對應的收發函數。
基本上大家也用不上其他模式的。常規的應用足夠了,我至今還沒有用過串口的其他模式。
如果需要,可以參考這個庫函數進行對應的寄存器修改。

關於波特率,我在定時器的博客上有描述

 

#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串口發送中斷標志位,在發送到數據最后一位后由硬件置位。當串口0中斷使能,將執行中斷服務程序。該位必須由軟件來清除。

 
        
 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)

通常都是固定的,一般都是根據所使用的波特率來求定時器初值。

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位收發。數據由起始位(邏輯0),8位數據(最低位在前),第9位數據(TB8或RB8)和停止位(邏輯1)組成。第9位做奇偶校驗位或多機通信時用來區分數據和地址。波特率是系統時鍾頻率的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燒錄的時候,與串口一是重合的,由於是引腳復用的關系,所以串口功能發生作用時,就會出現燒錄不進去的情況,這時只需要讓串口收發不了數據就能燒錄程序了。

 

 

 

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM