微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > LPC17XX 串口接收发送中断(含RS485)最全面驱动程序

LPC17XX 串口接收发送中断(含RS485)最全面驱动程序

时间:11-09 来源:互联网 点击:

** 173** txbuf-------数据指针,指向发送缓冲区 ** 174** len---------待发送字节数 ** 175** USE_RS485---DISABLE:不使能RS485_EN ENABLE:使能RS485_EN ** 176**返 回: ERR---发送失败 OK---发送成功 ** 177****************************************************************************************************** 178*/179 UART_EXT void UART_IRQ_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485); 180181/*182****************************************************************************************************** 183**函数名称: void UART_IRQ_SendStrings(uint8 COM, char *txbuf, State USE_RS485) ** 184**函数描述:串口UART中断发送字符串(供外部文件调用) ** 185**参 数: COM---------串口: 0,1,2,3 ** 186** txbuf-------数据指针,指向发送缓冲区 ** 187** USE_RS485---DISABLE:不使能RS485_EN ENABLE:使能RS485_EN ** 188**返 回: ERR---发送失败 OK---发送成功 ** 189****************************************************************************************************** 190*/191 UART_EXT void UART_IRQ_SendStrings(uint8 COM, char *txbuf, State USE_RS485); 192193/*194****************************************************************************************************** 195**函数名称: void UART_Printf(char *fmt,...) ** 196**函数描述:UART0串口打印程序函数 ** 197**参 数: *fmt---格式 ** 198**返 回: 无 ** 199****************************************************************************************************** 200*/201//构造此函数必须包含#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个字节,对于刚好是RX_FIFO_SIZE    **   14            的整数倍个字节数据时,留一个字节于FIFO中,以产生CTI中断!                                **   15            解决接收RX_FIFO_SIZE的整数倍个字节数据时无法创建接收完成标致(RX_OK)的问题!               **   16**            2014.01.01---V1.2  :增加中断发送数据功能.                                                **   17**            2014.10.18---V1.3  :修改部分bug,调整通过串口号选择串口而不通过结构选择串口!            **   18******************************************************************************************************   19*/ 20#define  UART_GLOBALS   21 #include "config.h" 22 23/* 24******************************************************************************************************   25**                                            RS485使能信号定义                                          **   26******************************************************************************************************   27*/ 28//本地使用的信号,无须在头文件中定义!------根据实际情况修改! 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收发使能信号  37#define        RTS_1(bit)    ( (bit==0)? (LPC_GPIO1->FIOCLR |=RTS1):(LPC_GPIO1->FIOSET |=RTS1) )        //UART1收发使能信号 38#define        RTS_2(bit)    ( (bit==0)? (LPC_GPIO1->FIOCLR |=RTS2):(LPC_GPIO1->FIOSET |=RTS2) )        //UART2收发使能信号 39#define        RTS_3(bit)    ( (bit==0)? (LPC_GPIO1->FIOCLR |=RTS3):(LPC_GPIO1->FIOSET |=RTS3) )        //UART3收发使能信号 40 41 42/* 43******************************************************************************************************   44**函数名称:    UART_info *BUF_SELECT(uint8 COM)                                                         **   45**函数描述:串口缓冲区结构的选择                                                                     **   46**参    数:    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**函数名称:    UART_IO_INIT(uint8 COM)                                                                     **   65**函数描述:所有串口IO初始化---RTS根据自己的实际情况修改!                                             **   66**参    数:    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);                               // 初始化为接收状态 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);                               // 初始化为接收状态 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);                               // 初始化为接收状态 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);                               // 初始化为接收状态108        }  109}  110111/*112******************************************************************************************************  113**函数名称:    void Set_Baudrate(uint32 BaudRate, uint16 *V_DL, uint8 *V_FDR)                             **  114**函数描述:设置精准的波特率(带小数分频寄存器的设定)                                                 **  115**参    数:    入参---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;                    //求出最精确的除数值(取小数点后2位,即放大100倍)!129     best_error = 0xFFFFFFFF;  130131//查找最佳的DL(DLL和DLM)、divADDVAL和MULVAL值---此3个数值结合运算,结果最接近divisor值(误差最小)的数为最佳组合!132for(m=1; m<=15; m++)  133        {  134for(d=0; dRX_OK = FALSE;                            // 串口接收完成标志清零.174     UART_INFO->TX_OK = TRUE;                            // 串口发送完成标志置位.175176if(COM==UART1)  177        {  178         LPC_UART1->LCR  = 0x83;                            // DLAB = 1, 使能访问除数锁存寄存器.179         LPC_UART1->DLM  = V_DL >> 8;                    // 除数高8位.180         LPC_UART1->DLL  = V_DL & 0xff;                    // 除数低8位.181         LPC_UART1->FDR  = V_FDR;                        // 小数分频寄存器赋值.182         LPC_UART1->LCR &= 0x7f;                            // DLAB = 0, 禁止访问除数锁存寄存器.183         LPC_UART1->LCR  = 0x03;                            // 8位, 无校验, 1位停止位.184         LPC_UART1->FCR  = FCR_VAL;                        // 使能FIFO,并设置RX FIFO触发深度. 185         LPC_UART1->IER  = 0x01;                            // 使能UART1接收中断,禁止发送中断.186187         NVIC_EnableIRQ(UART1_IRQn);                        // 使能LPC_UART1串口总中断,中断优先级默认!188        }  189else190        {  191         LPC_UART(COM)->LCR  = 0x83;                        // DLAB = 1, 使能访问除数锁存寄存器.192         LPC_UART(COM)->DLM  = V_DL >> 8;                // 除数高8位.193         LPC_UART(COM)->DLL  = V_DL & 0xff;                // 除数低8位.194         LPC_UART(COM)->FDR  = V_FDR;                    // 小数分频寄存器赋值.195         LPC_UART(COM)->LCR &= 0x7f;                        // DLAB = 0, 禁止访问除数锁存寄存器.196         LPC_UART(COM)->LCR  = 0x03;                        // 8位, 无校验, 1位停止位.197         LPC_UART(COM)->FCR  = FCR_VAL;                    // 使能FIFO,并设置RX FIFO触发深度. 198         LPC_UART(COM)->IER  = 0x01;                        // 使能UARTx接收中断,禁止发送中断.    199200201if(COM == UART0)                                // 使能LPC_UARTx串口总中断,中断优先级默认!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**函数名称:    RS485_EN(uint8 COM, BitFlag Bit, State USE_RS485)                                        **  213**函数描述:串口RS485方向控制使能                                                                    **  214**参    数:    COM--------串口: 0,1,2,3                                                                 **  215**          Bit---RESET:接收        SET:发送                                                        **  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**函数名称:    void UART_IRQ_CFG(uint8 COM, IRQ_TYPE IRQ, State NewState)                                 **  234**函数描述:串口收发中断使能配置                                                                     **  235**参    数:    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**函数名称:    BitFlag UART_CHK_LSR(uint8 COM, uint8 Bit)                                                 **  285**函数描述:检查LSR中的某位是为0还是为1                                                                 **  286**参    数:    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**函数名称:    uint32 UART_GET_IIR(uint8 COM)                                                             **  307**函数描述:读取串口IIR寄存器的值                                                                     **  308**参    数:    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**函数名称:    void UART_Send(uint8 COM, uint8 Data)                                                     **  328**函数描述:串口UART发送一个字节                                                                     **  329**参    数:    COM--------串口: 0,1,2,3                                                                 **  330**          Data---待发送字节                                                                          **   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**函数名称:    uint16 UART_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)                **  350**函数描述:串口UART发送多个字节(供外部文件调用)                                                     **  351**参    数:    COM---------串口: 0,1,2,3                                                                 **  352**          txbuf-------数据指针,指向发送缓冲区                                                     **  353**            len---------待发送字节数                                                                  **  354**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  355**返    回:    bSent---成功发送字节数                                                                     **  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收发使能信号---RST_x为高---发送数据.363364while(len--)  365        {  366         UART_Send(COM, (*txbuf++));  367while(UART_CHK_LSR(COM,LSR_TEMT)==RESET);                //等待THR和TSR为空,即发送数据完成.368         bSent++;  369        }  370371     RS485_EN(COM, RESET, USE_RS485);                            //RS485收发使能信号---RST_x为低---接收数据.372373return(bSent);  374}  375376/*377******************************************************************************************************  378**函数名称:    uint16 UART_SendStrings(uint8 COM, char *txbuf, State USE_RS485)                        **  379**函数描述:串口UART发送字符串(供外部文件调用)                                                         **  380**参    数:    COM---------串口: 0,1,2,3                                                                 **  381**          txbuf-------数据指针,指向发送缓冲区                                                     **  382**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  383**返    回:    bSent---成功发送字节数                                                                     **  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收发使能信号---RST_x为高---发送数据.391392while(*txbuf != )  393        {  394         UART_Send(COM, (*txbuf++));  395while(UART_CHK_LSR(COM,LSR_TEMT)==RESET);                //等待THR和TSR为空,即发送数据完成.396         bSent++;  397        }  398399     RS485_EN(COM, RESET, USE_RS485);                            //RS485收发使能信号---RST_x为低---接收数据.400401return(bSent);  402}  403404/*405******************************************************************************************************  406**函数名称:    void UART_IRQ_Send(uint8 COM, State USE_RS485)                                            **  407**函数描述:串口UART中断发送多个字节(供中断服务程序调用)                                             **  408**参    数:    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收发使能信号---RST_x为高---发送数据.419     UART_IRQ_CFG(COM, IRQ_THRE, DISABLE);                        //关闭串口THRE发送中断.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)                        //最多可连续快速向TX_FIFO写入16个字节的数据!426        {                  427         UART_Send(COM, UART_INFO->TX_Buffer[UART_INFO->TX_cnt]);      428         UART_INFO->TX_cnt++;  429         UART_INFO->TX_len--;  

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top