新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > LPC17XX 串口接收發(fā)送中斷(含RS485)最全面驅(qū)動程序

LPC17XX 串口接收發(fā)送中斷(含RS485)最全面驅(qū)動程序

作者: 時間:2016-11-09 來源:網(wǎng)絡 收藏
最近在做一個關于串口的項目,于是把之前的串口程序又拿了出來,重新優(yōu)化了一下!

本文引用地址:http://m.butianyuan.cn/article/201611/318049.htm

1、頭文件《uart.h》如下:

1/*  2******************************************************************************************************    3**                                  Copright(c) 2007-2014,深圳固鐳特電子                                   **    4**                                          All rights reserved.                                        **    5**                                        http://www.greatele.com                                        **    6******************************************************************************************************    7**文件名稱:    uart.h                                                                                      **    8**文件標識:    LPC17xx                                                                                    **    9**摘    要:    串口(UART0、UART1、UART2、UART3)通訊程序頭文件                                            **   10**當前版本:    V1.3                                                                                    **   11**作    者:    江南神槍                                                                                **   12**完成日期:    2011.06.10---V1.0                                                                        **   13**修    改:2011.12.11---V1.1  : 對于IIR_RDA中斷,接收RX_FIFO_SIZE-1個字節(jié),對于剛好是RX_FIFO_SIZE    **   14            的整數(shù)倍個字節(jié)數(shù)據(jù)時,留一個字節(jié)于FIFO中,以產(chǎn)生CTI中斷!                                **   15            解決接收RX_FIFO_SIZE的整數(shù)倍個字節(jié)數(shù)據(jù)時無法創(chuàng)建接收完成標致(RX_OK)的問題!               **   16**            2014.01.01---V1.2  :增加中斷發(fā)送數(shù)據(jù)功能.                                                **   17**            2014.10.18---V1.3  :修改部分bug,調(diào)整通過串口號選擇串口而不通過結構選擇串口!            **   18******************************************************************************************************   19*/ 20#ifdef  UART_GLOBALS   21#define UART_EXT   22#else 23#define UART_EXT extern    24#endif 25 26 27/* 28******************************************************************************************************   29**                                                參數(shù)配置                                              **   30******************************************************************************************************   31*/ 32#define        RX_FIFO_SIZE    (14)                //設置RX FIFO觸發(fā)深度4、8、14. 33#define        TX_FIFO_SIZE    (16)                //設置TX FIFO的使用長度. 34#define        BUFFER_SIZE        (256)                //設置串口收發(fā)數(shù)據(jù)緩沖區(qū)的長度. 35 36/* 37******************************************************************************************************   38**                                                全局變量定義                                          **   39******************************************************************************************************   40*/ 41#define        UART0            0x00                //串口號 42#define        UART1            0x01                   43#define        UART2            0x02                   44#define        UART3            0x03   45 46 UART_EXT    uint32            BaudRate[4];        //波特率.   47 48//對于RX FIFO觸發(fā)深度為1的情況(和不使用FIFO差不多,意義不大),不作處理!默認觸發(fā)深度為8字節(jié)! 49#define        FCR_VAL            ((RX_FIFO_SIZE==4)?0x47:((RX_FIFO_SIZE==8)?0x87:((RX_FIFO_SIZE==14)?0xC7:0x87)))   50 51//把UART1也轉成和別的UART一樣的結構,以便函數(shù)入?yún)⒂?!但程序中會對UART1的結構還原為正確的再使用! 52#define        LPC_UART(x)        ((x==0)?(LPC_UART_TypeDef  *)LPC_UART0_BASE:   53                             ((x==1)?(LPC_UART_TypeDef  *)LPC_UART1_BASE:   54                             ((x==2)?(LPC_UART_TypeDef  *)LPC_UART2_BASE:   55                                     (LPC_UART_TypeDef  *)LPC_UART3_BASE)))   56 57//串口收發(fā)線狀態(tài)位控制(LSR寄存器). 58#define     LSR_RDR            ((uint8)(1<<0))   59#define     LSR_OE            ((uint8)(1<<1))   60#define     LSR_PE            ((uint8)(1<<2))   61#define     LSR_FE            ((uint8)(1<<3))   62#define     LSR_BI            ((uint8)(1<<4))   63#define     LSR_THRE        ((uint8)(1<<5))   64#define     LSR_TEMT        ((uint8)(1<<6))   65#define     LSR_RXFE        ((uint8)(1<<7))   66#define     LSR_BITMASK        ((uint8)(0xFF))   67 68//串口中斷標識位控制(IIR寄存器). 69#define     IIR_INTSTAT        ((uint32)(1<<0))   70#define     IIR_RLS            ((uint32)(3<<1))   71#define     IIR_RDA            ((uint32)(2<<1))   72#define     IIR_CTI            ((uint32)(6<<1))   73#define     IIR_THRE        ((uint32)(1<<1))   74#define     IIR_MASK        ((uint32)(7<<1))   75#define     IIR_BITMASK        ((uint32)(0x3CF))   76 77//串口收發(fā)中斷位控制(IER寄存器). 78#define     IER_RBR            ((uint32)(1<<0))    //接收數(shù)據(jù)可用中斷. 79#define     IER_THRE        ((uint32)(1<<1))    //發(fā)送數(shù)據(jù)緩沖區(qū)為空. 80#define     IER_BITMASK        ((uint32)(0x307))    81#define     IER1_BITMASK    ((uint32)(0x38F))    82 83//中斷類型. 84 typedef enum 85    {   86     IRQ_RBR  = 0,       87     IRQ_THRE = 1 88    }IRQ_TYPE;   89 90//使能狀況. 91 typedef enum 92    {   93     DISABLE = 0,    94     ENABLE  = !DISABLE   95    }State;   96 97//狀態(tài)標志. 98 typedef enum 99    {  100     RESET = 0,                                    //復位. 101     SET   = !RESET                                //置位.102    }BitFlag;  103104//串口相關標志及數(shù)據(jù)緩沖區(qū)結構.105 typedef struct106    {  107     uint8        RX_OK;                            //串口接收完成標志.    0:未接收完成  1:接收完成        108     uint8        TX_OK;                            //串口發(fā)送完成標志.    0:未發(fā)送完成  1:發(fā)送完成109     uint16        RX_cnt;                            //收到字節(jié)計數(shù)器.110     uint16        TX_cnt;                            //發(fā)送字節(jié)計數(shù)器.111     uint16        RX_len;                            //已接收的字節(jié)長度.112     uint16        TX_len;                            //待發(fā)送的字節(jié)長度.113     uint8        RX_Buffer[BUFFER_SIZE];            //串口接收緩沖區(qū).114     uint8        TX_Buffer[BUFFER_SIZE];            //串口發(fā)送緩沖區(qū).            115116    }uart_info;  117118//結構實體定義119 UART_EXT    uart_info        UART[4];            //4個結構對應4個串口.120121122/*123******************************************************************************************************  124**函數(shù)名稱:    UART_IO_INIT(uint8 COM)                                                                     **  125**函數(shù)描述:所有串口IO初始化---RTS根據(jù)自己的實際情況修改!                                             **  126**參    數(shù):    COM--------串口: 0,1,2,3                                                                **  127**返    回:    無                                                                                         **  128******************************************************************************************************  129*/130 UART_EXT void UART_IO_INIT(uint8 COM);  131132/*133******************************************************************************************************  134**函數(shù)名稱:    void UART_INIT(uint8 COM, uint32 BaudRate)                                                 **  135**函數(shù)描述:串口UART初始化                                                                             **  136**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  137**          BaudRate---波特率                                                                         **   138**返    回:    無                                                                                         **  139******************************************************************************************************  140*/141 UART_EXT void UART_INIT(uint8 COM, uint32 BaudRate);  142143/*144******************************************************************************************************  145**函數(shù)名稱:    uint16 UART_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)                **  146**函數(shù)描述:串口UART發(fā)送多個字節(jié)(供外部文件調(diào)用)                                                     **  147**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  148**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  149**            len---------待發(fā)送字節(jié)數(shù)                                                                  **  150**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  151**返    回:    bSent---成功發(fā)送字節(jié)數(shù)                                                                     **  152******************************************************************************************************  153*/154 UART_EXT uint16 UART_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485);  155156/*157******************************************************************************************************  158**函數(shù)名稱:    uint16 UART_SendStrings(uint8 COM, char *txbuf, State USE_RS485)                        **  159**函數(shù)描述:串口UART發(fā)送字符串(供外部文件調(diào)用)                                                         **  160**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  161**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  162**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  163**返    回:    bSent---成功發(fā)送字節(jié)數(shù)                                                                     **  164******************************************************************************************************  165*/166 UART_EXT uint16 UART_SendStrings(uint8 COM, char *txbuf, State USE_RS485);  167168/*169******************************************************************************************************  170**函數(shù)名稱:    void UART_IRQ_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)            **  171**函數(shù)描述:串口UART中斷發(fā)送多個字節(jié)(供外部文件調(diào)用)                                                 **  172**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  173**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  174**            len---------待發(fā)送字節(jié)數(shù)                                                                  **  175**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  176**返    回:    ERR---發(fā)送失敗        OK---發(fā)送成功                                                         **  177******************************************************************************************************  178*/179 UART_EXT void UART_IRQ_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485);  180181/*182******************************************************************************************************  183**函數(shù)名稱:    void UART_IRQ_SendStrings(uint8 COM, char *txbuf, State USE_RS485)                         **  184**函數(shù)描述:串口UART中斷發(fā)送字符串(供外部文件調(diào)用)                                                     **  185**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  186**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  187**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  188**返    回:    ERR---發(fā)送失敗        OK---發(fā)送成功                                                         **  189******************************************************************************************************  190*/191 UART_EXT void UART_IRQ_SendStrings(uint8 COM, char *txbuf, State USE_RS485);  192193/*194******************************************************************************************************  195**函數(shù)名稱:    void UART_Printf(char *fmt,...)                                                          **  196**函數(shù)描述:UART0串口打印程序函數(shù)                                                                    **  197**參    數(shù):    *fmt---格式                                                                                 **  198**返    回:    無                                                                                         **  199******************************************************************************************************  200*/201//構造此函數(shù)必須包含#include 和#include 這兩個頭文件!202203 UART_EXT void UART_Printf(char *fmt,...);  204205/*206******************************************************************************************************  207**                                            End Of File                                             **  208******************************************************************************************************  209*/

2、程序文件《uart.c》如下:

1/*  2******************************************************************************************************    3**                                  Copright(c) 2007-2014,深圳固鐳特電子                                   **    4**                                          All rights reserved.                                        **    5**                                        http://www.greatele.com                                        **    6******************************************************************************************************    7**文件名稱:    uart.c                                                                                      **    8**文件標識: LPC17xx                                                                                    **    9**摘    要: 串口(UART0、UART1、UART2、UART3)通訊程序                                                **   10**當前版本: V1.3                                                                                    **   11**作    者: 江南神槍                                                                                **   12**完成日期: 2011.06.10---V1.0                                                                        **   13**修    改:2011.12.11---V1.1  : 對于IIR_RDA中斷,接收RX_FIFO_SIZE-1個字節(jié),對于剛好是RX_FIFO_SIZE    **   14            的整數(shù)倍個字節(jié)數(shù)據(jù)時,留一個字節(jié)于FIFO中,以產(chǎn)生CTI中斷!                                **   15            解決接收RX_FIFO_SIZE的整數(shù)倍個字節(jié)數(shù)據(jù)時無法創(chuàng)建接收完成標致(RX_OK)的問題!               **   16**            2014.01.01---V1.2  :增加中斷發(fā)送數(shù)據(jù)功能.                                                **   17**            2014.10.18---V1.3  :修改部分bug,調(diào)整通過串口號選擇串口而不通過結構選擇串口!            **   18******************************************************************************************************   19*/ 20#define  UART_GLOBALS   21 #include "config.h" 22 23/* 24******************************************************************************************************   25**                                            RS485使能信號定義                                          **   26******************************************************************************************************   27*/ 28//本地使用的信號,無須在頭文件中定義!------根據(jù)實際情況修改! 29 30#define        RTS0        (1<<18)        //P1.18 31#define        RTS1        (1<<19)        //P1.19 32#define        RTS2        (1<<20)        //P1.20 33#define        RTS3        (1<<22)        //P1.22 34 35//bit=0 或 bit=1 36#define        RTS_0(bit)    ( (bit==0)? (LPC_GPIO1->FIOCLR |=RTS0):(LPC_GPIO1->FIOSET |=RTS0) )        //UART0收發(fā)使能信號  37#define        RTS_1(bit)    ( (bit==0)? (LPC_GPIO1->FIOCLR |=RTS1):(LPC_GPIO1->FIOSET |=RTS1) )        //UART1收發(fā)使能信號 38#define        RTS_2(bit)    ( (bit==0)? (LPC_GPIO1->FIOCLR |=RTS2):(LPC_GPIO1->FIOSET |=RTS2) )        //UART2收發(fā)使能信號 39#define        RTS_3(bit)    ( (bit==0)? (LPC_GPIO1->FIOCLR |=RTS3):(LPC_GPIO1->FIOSET |=RTS3) )        //UART3收發(fā)使能信號 40 41 42/* 43******************************************************************************************************   44**函數(shù)名稱:    UART_info *BUF_SELECT(uint8 COM)                                                         **   45**函數(shù)描述:串口緩沖區(qū)結構的選擇                                                                     **   46**參    數(shù):    COM---------串口號: 0,1,2,3                                                               **   47**返    回:    UART_INFO---串口信息結構                                                                 **   48******************************************************************************************************   49*/ 50 uart_info *BUF_SELECT(uint8 COM)   51{   52 uart_info    *UART_INFO=NULL;   53 54if(COM == UART0){ UART_INFO = &UART[0]; }   55if(COM == UART1){ UART_INFO = &UART[1]; }   56if(COM == UART2){ UART_INFO = &UART[2]; }   57if(COM == UART3){ UART_INFO = &UART[3]; }   58 59return(UART_INFO);   60}   61 62/* 63******************************************************************************************************   64**函數(shù)名稱:    UART_IO_INIT(uint8 COM)                                                                     **   65**函數(shù)描述:所有串口IO初始化---RTS根據(jù)自己的實際情況修改!                                             **   66**參    數(shù):    COM--------串口: 0,1,2,3                                                                **   67**返    回:    無                                                                                         **   68******************************************************************************************************   69*/ 70void UART_IO_INIT(uint8 COM)   71{   72if(COM == UART0)                   73        {               74         LPC_PINCON->PINSEL0 |=    (1 << 4);        // 引腳配置:TXD0=P0.2 RXD0=P0.3                      75         LPC_PINCON->PINSEL0 |=    (1 << 6);   76         LPC_PINCON->PINSEL3 |=    (0 << 4);        // RST_0=P1.18  GPIO---方向為輸出 77         LPC_GPIO1->FIODIR    |=    RTS0;                            78         RTS_0(0);                               // 初始化為接收狀態(tài) 79        }   80 81if(COM == UART1)                   82        {   83         LPC_PINCON->PINSEL4 |=    (2 << 0);        // 引腳配置:TXD1=P2.0  RXD1=P2.1                        84         LPC_PINCON->PINSEL4 |=    (2 << 2);   85         LPC_PINCON->PINSEL3 |=    (0 << 6);        // RST_1=P1.19   GPIO---方向為輸出 86         LPC_GPIO1->FIODIR    |=    RTS1;                            87         RTS_1(0);                               // 初始化為接收狀態(tài) 88        }   89 90if(COM == UART2)                   91        {   92         LPC_SC->PCONP        |=    0x01000000;        // 使能UART2功率/時鐘控制位---第24位,默認關閉 93         LPC_PINCON->PINSEL4 |=    (2 << 16);        // 引腳配置:TXD2=P2.08  RXD2=P2.09 94         LPC_PINCON->PINSEL4 |=    (2 << 18);                                    95         LPC_PINCON->PINSEL3 |=    (0 <<  8);      // RST_2=P1.20   GPIO---方向為輸出 96         LPC_GPIO1->FIODIR    |=    RTS2;                            97         RTS_2(0);                               // 初始化為接收狀態(tài) 98        }   99100if(COM == UART3)                  101        {  102         LPC_SC->PCONP        |=    0x02000000;        // 使能UART3功率/時鐘控制位---第25位,默認關閉103         LPC_PINCON->PINSEL9 |=    (3 << 24);        // 引腳配置:TXD3=P4.28  RXD3=P4.29                       104         LPC_PINCON->PINSEL9 |=    (3 << 26);  105         LPC_PINCON->PINSEL3 |=    (0 << 12);        // RST_3=P1.22   GPIO---方向為輸出106         LPC_GPIO1->FIODIR    |=    RTS3;  107         RTS_3(0);                               // 初始化為接收狀態(tài)108        }  109}  110111/*112******************************************************************************************************  113**函數(shù)名稱:    void Set_Baudrate(uint32 BaudRate, uint16 *V_DL, uint8 *V_FDR)                             **  114**函數(shù)描述:設置精準的波特率(帶小數(shù)分頻寄存器的設定)                                                 **  115**參    數(shù):    入?yún)?--BaudRate    出參指針---*V_DL、*V_FDR                                                  **  116**返    回:    無                                                                                         **  117******************************************************************************************************  118*/119void Set_Baudrate(uint32 BaudRate, uint16 *V_DL, uint8 *V_FDR)  120{  121//BaudRate = Fpclk / ( 16 * DL * (1 + DIVADDVAL / MULVAL) )  122//           = Fpclk * MULVAL / (DIVADDVAL + MULVAL) / (16 * DL)123124 uint8    d=0, m=0, bestd=0, bestm=0;  125 uint32    divisor=0, tmp_divisor=0, best_divisor=0;  126 uint32    current_error=0, best_error=0;  127128     divisor = (Fpclk>>4)*100/BaudRate;                    //求出最精確的除數(shù)值(取小數(shù)點后2位,即放大100倍)!129     best_error = 0xFFFFFFFF;  130131//查找最佳的DL(DLL和DLM)、DIVADDVAL和MULVAL值---此3個數(shù)值結合運算,結果最接近divisor值(誤差最小)的數(shù)為最佳組合!132for(m=1; m<=15; m++)  133        {  134for(d=0; dRX_OK = FALSE;                            // 串口接收完成標志清零.174     UART_INFO->TX_OK = TRUE;                            // 串口發(fā)送完成標志置位.175176if(COM==UART1)  177        {  178         LPC_UART1->LCR  = 0x83;                            // DLAB = 1, 使能訪問除數(shù)鎖存寄存器.179         LPC_UART1->DLM  = V_DL >> 8;                    // 除數(shù)高8位.180         LPC_UART1->DLL  = V_DL & 0xff;                    // 除數(shù)低8位.181         LPC_UART1->FDR  = V_FDR;                        // 小數(shù)分頻寄存器賦值.182         LPC_UART1->LCR &= 0x7f;                            // DLAB = 0, 禁止訪問除數(shù)鎖存寄存器.183         LPC_UART1->LCR  = 0x03;                            // 8位, 無校驗, 1位停止位.184         LPC_UART1->FCR  = FCR_VAL;                        // 使能FIFO,并設置RX FIFO觸發(fā)深度. 185         LPC_UART1->IER  = 0x01;                            // 使能UART1接收中斷,禁止發(fā)送中斷.186187         NVIC_EnableIRQ(UART1_IRQn);                        // 使能LPC_UART1串口總中斷,中斷優(yōu)先級默認!188        }  189else190        {  191         LPC_UART(COM)->LCR  = 0x83;                        // DLAB = 1, 使能訪問除數(shù)鎖存寄存器.192         LPC_UART(COM)->DLM  = V_DL >> 8;                // 除數(shù)高8位.193         LPC_UART(COM)->DLL  = V_DL & 0xff;                // 除數(shù)低8位.194         LPC_UART(COM)->FDR  = V_FDR;                    // 小數(shù)分頻寄存器賦值.195         LPC_UART(COM)->LCR &= 0x7f;                        // DLAB = 0, 禁止訪問除數(shù)鎖存寄存器.196         LPC_UART(COM)->LCR  = 0x03;                        // 8位, 無校驗, 1位停止位.197         LPC_UART(COM)->FCR  = FCR_VAL;                    // 使能FIFO,并設置RX FIFO觸發(fā)深度. 198         LPC_UART(COM)->IER  = 0x01;                        // 使能UARTx接收中斷,禁止發(fā)送中斷.    199200201if(COM == UART0)                                // 使能LPC_UARTx串口總中斷,中斷優(yōu)先級默認!202            {NVIC_EnableIRQ(UART0_IRQn);}  203if(COM == UART2)  204            {NVIC_EnableIRQ(UART2_IRQn);}  205if(COM == UART3)  206            {NVIC_EnableIRQ(UART3_IRQn);}  207        }      208}  209210/*211******************************************************************************************************  212**函數(shù)名稱:    RS485_EN(uint8 COM, BitFlag Bit, State USE_RS485)                                        **  213**函數(shù)描述:串口RS485方向控制使能                                                                    **  214**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  215**          Bit---RESET:接收        SET:發(fā)送                                                        **  216**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  217**返    回:    無                                                                                         **  218******************************************************************************************************  219*/220void RS485_EN(uint8 COM, BitFlag Bit, State USE_RS485)  221{  222if(USE_RS485)  223        {  224if(COM == UART0){ RTS_0(Bit); }  225if(COM == UART1){ RTS_1(Bit); }  226if(COM == UART2){ RTS_2(Bit); }  227if(COM == UART3){ RTS_3(Bit); }  228        }  229}  230231/*232******************************************************************************************************  233**函數(shù)名稱:    void UART_IRQ_CFG(uint8 COM, IRQ_TYPE IRQ, State NewState)                                 **  234**函數(shù)描述:串口收發(fā)中斷使能配置                                                                     **  235**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  236**          IRQ---中斷類型                                                                             **  237**            NewState---DISABLE:不使能該中斷        ENABLE:使能該中斷                                 **  238**返    回:    無                                                                                         **  239******************************************************************************************************  240*/241void UART_IRQ_CFG(uint8 COM, IRQ_TYPE IRQ, State NewState)  242{  243 uint32    temp=0;  244245//先判斷中斷類型.246switch(IRQ)  247        {  248case IRQ_RBR:  249             temp = IER_RBR;  250break;      251252case IRQ_THRE:  253             temp = IER_THRE;  254break;          255        }  256257//再判斷使能狀況.258if (NewState == ENABLE)  259        {  260if(COM==UART1)  261            {  262             LPC_UART1->IER |= temp;  263            }  264else265            {  266             LPC_UART(COM)->IER |= temp;  267            }  268        }  269else270        {  271if(COM==UART1)  272            {  273             LPC_UART1->IER &= (~temp) & IER1_BITMASK;  274            }  275else276            {  277             LPC_UART(COM)->IER &= (~temp) & IER_BITMASK;  278            }  279        }  280}  281282/*283******************************************************************************************************  284**函數(shù)名稱:    BitFlag UART_CHK_LSR(uint8 COM, uint8 Bit)                                                 **  285**函數(shù)描述:檢查LSR中的某位是為0還是為1                                                                 **  286**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  287**            Bit--------------LSR寄存器中的某位                                                         **  288**返    回:    RESET:該位為0     SET:該位為1                                                             **  289******************************************************************************************************  290*/291BitFlag UART_CHK_LSR(uint8 COM, uint8 Bit)  292{  293uint8    REG_LSR;  294295//找出對應串口的LSR值.296if(COM==UART1) { REG_LSR = LPC_UART1->LSR; }  297else { REG_LSR = LPC_UART(COM)->LSR; }  298299//判斷LSR中的該位是為0還是為1.300if (REG_LSR & Bit){ return SET; }   301else { return RESET; }  302}  303304/*305******************************************************************************************************  306**函數(shù)名稱:    uint32 UART_GET_IIR(uint8 COM)                                                             **  307**函數(shù)描述:讀取串口IIR寄存器的值                                                                     **  308**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  309**返    回:    寄存器的值                                                                                 **  310******************************************************************************************************  311*/312uint32 UART_GET_IIR(uint8 COM)  313{  314if(COM==UART1)  315        {  316return (LPC_UART1->IIR & IIR_BITMASK);  317        }  318else319        {  320return (LPC_UART(COM)->IIR & IIR_BITMASK);  321        }  322323}  324325/*326******************************************************************************************************  327**函數(shù)名稱:    void UART_Send(uint8 COM, uint8 Data)                                                     **  328**函數(shù)描述:串口UART發(fā)送一個字節(jié)                                                                     **  329**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  330**          Data---待發(fā)送字節(jié)                                                                          **   331**返    回:    無                                                                                         **  332******************************************************************************************************  333*/334void UART_Send(uint8 COM, uint8 Data)  335{  336337if(COM==UART1)  338        {  339         LPC_UART1->THR = Data;  340        }  341else342        {  343         LPC_UART(COM)->THR = Data;  344        }  345}  346347/*348******************************************************************************************************  349**函數(shù)名稱:    uint16 UART_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)                **  350**函數(shù)描述:串口UART發(fā)送多個字節(jié)(供外部文件調(diào)用)                                                     **  351**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  352**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  353**            len---------待發(fā)送字節(jié)數(shù)                                                                  **  354**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  355**返    回:    bSent---成功發(fā)送字節(jié)數(shù)                                                                     **  356******************************************************************************************************  357*/358 uint16 UART_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)  359{  360 uint16    bSent=0;  361362     RS485_EN(COM, SET, USE_RS485);                                //RS485收發(fā)使能信號---RST_x為高---發(fā)送數(shù)據(jù).363364while(len--)  365        {  366         UART_Send(COM, (*txbuf++));  367while(UART_CHK_LSR(COM,LSR_TEMT)==RESET);                //等待THR和TSR為空,即發(fā)送數(shù)據(jù)完成.368         bSent++;  369        }  370371     RS485_EN(COM, RESET, USE_RS485);                            //RS485收發(fā)使能信號---RST_x為低---接收數(shù)據(jù).372373return(bSent);  374}  375376/*377******************************************************************************************************  378**函數(shù)名稱:    uint16 UART_SendStrings(uint8 COM, char *txbuf, State USE_RS485)                        **  379**函數(shù)描述:串口UART發(fā)送字符串(供外部文件調(diào)用)                                                         **  380**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  381**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  382**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  383**返    回:    bSent---成功發(fā)送字節(jié)數(shù)                                                                     **  384******************************************************************************************************  385*/386 uint16 UART_SendStrings(uint8 COM, char *txbuf, State USE_RS485)  387{  388 uint16    bSent=0;  389390     RS485_EN(COM, SET, USE_RS485);                                //RS485收發(fā)使能信號---RST_x為高---發(fā)送數(shù)據(jù).391392while(*txbuf != )  393        {  394         UART_Send(COM, (*txbuf++));  395while(UART_CHK_LSR(COM,LSR_TEMT)==RESET);                //等待THR和TSR為空,即發(fā)送數(shù)據(jù)完成.396         bSent++;  397        }  398399     RS485_EN(COM, RESET, USE_RS485);                            //RS485收發(fā)使能信號---RST_x為低---接收數(shù)據(jù).400401return(bSent);  402}  403404/*405******************************************************************************************************  406**函數(shù)名稱:    void UART_IRQ_Send(uint8 COM, State USE_RS485)                                            **  407**函數(shù)描述:串口UART中斷發(fā)送多個字節(jié)(供中斷服務程序調(diào)用)                                             **  408**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  409**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  410**返    回:    無                                                                                         **  411******************************************************************************************************  412*/413void UART_IRQ_Send(uint8 COM, State USE_RS485)  414{  415uint8    FIFO_CNT;  416 uart_info    *UART_INFO;  417418     RS485_EN(COM, SET, USE_RS485);                                //RS485收發(fā)使能信號---RST_x為高---發(fā)送數(shù)據(jù).419     UART_IRQ_CFG(COM, IRQ_THRE, DISABLE);                        //關閉串口THRE發(fā)送中斷.420421while(UART_CHK_LSR(COM,LSR_THRE) == RESET);                    //等待THR為空.                        422     UART_INFO = BUF_SELECT(COM);                                //選擇對應的串口信息結構.        423424     FIFO_CNT  = TX_FIFO_SIZE;      425while(UART_INFO->TX_len && FIFO_CNT)                        //最多可連續(xù)快速向TX_FIFO寫入16個字節(jié)的數(shù)據(jù)!426        {                  427         UART_Send(COM, UART_INFO->TX_Buffer[UART_INFO->TX_cnt]);      428         UART_INFO->TX_cnt++;  429         UART_INFO->TX_len--;  430         FIFO_CNT--;  431        }  432433//如果還有數(shù)據(jù)未發(fā)送完,則使能串口中斷。反之,則關閉串口中斷.434if(UART_CHK_LSR(COM,LSR_THRE) == RESET)                        //THR不為空.435        {  436         UART_IRQ_CFG(COM, IRQ_THRE, ENABLE);                    //使能串口發(fā)送中斷.437         UART_INFO->TX_OK = FALSE;          438        }  439else440        {  441         UART_IRQ_CFG(COM, IRQ_THRE, DISABLE);                    //關閉串口發(fā)送中斷.442         UART_INFO->TX_OK=TRUE;  443         UART_INFO->TX_cnt=0;  444         UART_INFO->TX_len=0;  445446while(UART_CHK_LSR(COM,LSR_TEMT)==RESET);                //等待THR和TSR為空,即最后一個數(shù)據(jù)發(fā)送完成(已移出TSR).447         RS485_EN(COM, RESET, USE_RS485);                        //RS485收發(fā)使能信號---RST_x為低---接收數(shù)據(jù).448        }  449}  450451/*452******************************************************************************************************  453**函數(shù)名稱:    void UART_IRQ_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)            **  454**函數(shù)描述:串口UART中斷發(fā)送多個字節(jié)(供外部文件調(diào)用)                                                 **  455**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  456**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  457**            len---------待發(fā)送字節(jié)數(shù)                                                                  **  458**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  459**返    回:    ERR---發(fā)送失敗        OK---發(fā)送成功                                                         **  460******************************************************************************************************  461*/462void UART_IRQ_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)  463{  464 uart_info    *UART_INFO;  465466     UART_INFO = BUF_SELECT(COM);                                //選擇對應的串口信息結構.467while(!UART_INFO->TX_OK);                                    //等待串口空閑.468469     memcpy(UART_INFO->TX_Buffer, txbuf, len);                    //復制等待發(fā)送的數(shù)據(jù)到發(fā)送緩沖區(qū).470     UART_INFO->TX_len=len;  471     UART_INFO->TX_cnt=0;  472     UART_INFO->TX_OK=FALSE;  473474     UART_IRQ_Send(COM, USE_RS485);                                //將數(shù)據(jù)寫到THR.475476}  477478/*479******************************************************************************************************  480**函數(shù)名稱:    void UART_IRQ_SendStrings(uint8 COM, char *txbuf, State USE_RS485)                         **  481**函數(shù)描述:串口UART中斷發(fā)送字符串(供外部文件調(diào)用)                                                     **  482**參    數(shù):    COM---------串口: 0,1,2,3                                                                 **  483**          txbuf-------數(shù)據(jù)指針,指向發(fā)送緩沖區(qū)                                                     **  484**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  485**返    回:    ERR---發(fā)送失敗        OK---發(fā)送成功                                                         **  486******************************************************************************************************  487*/488void UART_IRQ_SendStrings(uint8 COM, char *txbuf, State USE_RS485)  489{  490 uart_info    *UART_INFO;  491492     UART_INFO = BUF_SELECT(COM);                                //選擇對應的串口信息結構.493while(!UART_INFO->TX_OK);                                    //等待串口空閑.494495     strcpy((char *)(UART_INFO->TX_Buffer), txbuf);                //復制等待發(fā)送的數(shù)據(jù)到發(fā)送緩沖區(qū).496     UART_INFO->TX_len=strlen(txbuf);  497     UART_INFO->TX_cnt=0;  498     UART_INFO->TX_OK=FALSE;  499500     UART_IRQ_Send(COM, USE_RS485);                                //將數(shù)據(jù)寫到THR.501502}  503504/*505******************************************************************************************************  506**函數(shù)名稱:    uint8 UART_Recv(uint8 COM)                                                                **  507**函數(shù)描述:串口UART接收一個字節(jié)                                                                     **  508**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  509**返    回:    接收到的數(shù)據(jù)                                                                             **  510******************************************************************************************************  511*/512uint8 UART_Recv(uint8 COM)  513{  514515if(COM==UART1)  516        {  517return (LPC_UART1->RBR);  518        }  519else520        {  521return (LPC_UART(COM)->RBR);  522        }  523}  524525/*526******************************************************************************************************  527**函數(shù)名稱:    void UART_IRQ_RecvBytes(uint8 COM, uint32 IIR_ID)                                        **  528**函數(shù)描述:串口UART中斷接收多個字節(jié)(供中斷服務程序調(diào)用)                                             **  529**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  530**            IIR_ID-----中斷標識:IIR_RDA或IIR_CTI                                                     **  531**返    回:    無                                                                                         **  532******************************************************************************************************  533*/534void UART_IRQ_RecvBytes(uint8 COM, uint32 IIR_ID)  535{  536uint8 cnt;  537 uart_info    *UART_INFO;  538539     UART_IRQ_CFG(COM, IRQ_RBR, DISABLE);                    //關閉串口接收中斷.540     UART_INFO = BUF_SELECT(COM);                            //選擇對應的串口信息結構.541542switch(IIR_ID)  543        {  544//接收數(shù)據(jù)可用中斷---實際有RX_FIFO_SIZE個字節(jié),但只讀取RX_FIFO_SIZE-1個字節(jié),對于剛好是RX_FIFO_SIZE的整數(shù)倍個數(shù)據(jù)時,留1字節(jié)產(chǎn)生CTI中斷!否則無法創(chuàng)建RX_OK標致!545case IIR_RDA:  546for (cnt=0; cnt<(RX_FIFO_SIZE-1); cnt++)  547                {                              548                 UART_INFO->RX_Buffer[UART_INFO->RX_cnt] = UART_Recv(COM);  549                 UART_INFO->RX_cnt++;  550                }  551break;  552//字符超時中斷.    553case IIR_CTI:  554while(UART_CHK_LSR(COM,LSR_RDR)==SET)            //判斷FIFO中是否還包仿有效數(shù)據(jù),有則繼續(xù)讀取.              555                {  556                 UART_INFO->RX_Buffer[UART_INFO->RX_cnt] = UART_Recv(COM);  557                 UART_INFO->RX_cnt++;  558                }  559             UART_INFO->RX_len = UART_INFO->RX_cnt;  560             UART_INFO->RX_OK  = TRUE;                        //串口接收完成標志置位.561break;      562        }  563564     UART_IRQ_CFG(COM, IRQ_RBR, ENABLE);                        //使能串口接收中斷.565}  566567/*568******************************************************************************************************  569**函數(shù)名稱:    void UART_IRQ_SERVICE(uint8 COM)                                                        **  570**函數(shù)描述:串口中斷服務程序回調(diào)函數(shù)                                                                 **  571**參    數(shù):    COM--------串口: 0,1,2,3                                                                 **  572**返    回:    無                                                                                         **  573******************************************************************************************************  574*/575void UART_IRQ_SERVICE(uint8 COM)  576{  577uint32 IIR_ID;  578579     IIR_ID = UART_GET_IIR(COM) & IIR_MASK;  580581//接收線狀態(tài)中斷---本例不作處理,也沒有使能該中斷.582583/****處理程序****/584585//接收數(shù)據(jù)中斷586if((IIR_ID == IIR_RDA) || (IIR_ID == IIR_CTI))  587        {  588        UART_IRQ_RecvBytes(COM, IIR_ID);  589        }  590591//發(fā)送數(shù)據(jù)中斷592if(IIR_ID == IIR_THRE)  593        {  594        UART_IRQ_Send(COM, ENABLE);  595        }  596}  597598/*599******************************************************************************************************  600**函數(shù)名稱:    void UART0_IRQHandler(void)                                                                 **  601**函數(shù)描述:UART0中斷服務程序                                                                         **  602**參    數(shù):    無                                                                                         **  603**返    回:    無                                                                                         **  604******************************************************************************************************  605*/606void UART0_IRQHandler(void)   607{  608609    UART_IRQ_SERVICE(UART0);  610611}  612613/*614******************************************************************************************************  615**函數(shù)名稱:    void UART1_IRQHandler(void)                                                                 **  616**函數(shù)描述:UART1中斷服務程序                                                                         **  617**參    數(shù):    無                                                                                         **  618**返    回:    無                                                                                         **  619******************************************************************************************************  620*/621void UART1_IRQHandler(void)   622{  623624    UART_IRQ_SERVICE(UART1);  625626}  627628/*629******************************************************************************************************  630**函數(shù)名稱:    void UART2_IRQHandler(void)                                                                 **  631**函數(shù)描述:UART2中斷服務程序                                                                         **  632**參    數(shù):    無                                                                                         **  633**返    回:    無                                                                                         **  634******************************************************************************************************  635*/636void UART2_IRQHandler(void)   637{  638639    UART_IRQ_SERVICE(UART2);  640641}  642643/*644******************************************************************************************************  645**函數(shù)名稱:    void UART3_IRQHandler(void)                                                                 **  646**函數(shù)描述:UART3中斷服務程序                                                                         **  647**參    數(shù):    無                                                                                         **  648**返    回:    無                                                                                         **  649******************************************************************************************************  650*/651void UART3_IRQHandler(void)   652{  653654    UART_IRQ_SERVICE(UART3);  655656}  657658659660/*661******************************************************************************************************  662**                                    另類printf函數(shù)構造方法                                             **  663******************************************************************************************************  664*/665666/*667******************************************************************************************************  668**函數(shù)名稱:    void UART_Printf(char *fmt,...)                                                          **  669**函數(shù)描述:UART0串口打印程序函數(shù)                                                                    **  670**參    數(shù):    *fmt---格式                                                                                 **  671**返    回:    無                                                                                         **  672******************************************************************************************************  673*/674//構造此函數(shù)必須包含#include 和#include 這兩個頭文件!675676void UART_Printf(char *fmt,...)   677{   678679    va_list ap;   680charstring[1024];                          //此處切勿用字符串指針!?。?--用指針很容易死機?。?! 681682    va_start(ap,fmt);   683     vsprintf(string,fmt,ap);  684685//中斷方式發(fā)送686     UART_IRQ_SendStrings(UART0,string,ENABLE);    //串口UART0發(fā)送字符串函數(shù)---須自行構造!   687688//非中斷方式發(fā)送  689//UART_SendStrings(UART0,string,ENABLE);    //串口UART0發(fā)送字符串函數(shù)---須自行構造! 690691    va_end(ap);   692}  693694/*695******************************************************************************************************  696**                                            End Of File                                             **  697******************************************************************************************************  698*/



評論


技術專區(qū)

關閉