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

发布者:ohp991养生的香菇最新更新时间:2016-06-14 来源: eefocus关键字:LPC17XX  串口  接收发送中断  RS485 手机看文章 扫描二维码
随时随地手机看文章
最近在做一个关于串口的项目,于是把之前的串口程序又拿了出来,重新优化了一下!

 

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个字节,对于刚好是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#ifdef  UART_GLOBALS   21#define UART_EXT   22#else 23#define UART_EXT extern    24#endif 25 26 27/* 28******************************************************************************************************   29**                                                参数配置                                              **   30******************************************************************************************************   31*/ 32#define        RX_FIFO_SIZE    (14)                //设置RX FIFO触发深度4、8、14. 33#define        TX_FIFO_SIZE    (16)                //设置TX FIFO的使用长度. 34#define        BUFFER_SIZE        (256)                //设置串口收发数据缓冲区的长度. 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触发深度为1的情况(和不使用FIFO差不多,意义不大),不作处理!默认触发深度为8字节! 49#define        FCR_VAL            ((RX_FIFO_SIZE==4)?0x47:((RX_FIFO_SIZE==8)?0x87:((RX_FIFO_SIZE==14)?0xC7:0x87)))   50 51//把UART1也转成和别的UART一样的结构,以便函数入参用!但程序中会对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//串口收发线状态位控制(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//串口收发中断位控制(IER寄存器). 78#define     IER_RBR            ((uint32)(1<<0))    //接收数据可用中断. 79#define     IER_THRE        ((uint32)(1<<1))    //发送数据缓冲区为空. 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//状态标志. 98 typedef enum 99    {  100     RESET = 0,                                    //复位. 101     SET   = !RESET                                //置位.102    }BitFlag;  103104//串口相关标志及数据缓冲区结构.105 typedef struct106    {  107     uint8        RX_OK;                            //串口接收完成标志.    0:未接收完成  1:接收完成        108     uint8        TX_OK;                            //串口发送完成标志.    0:未发送完成  1:发送完成109     uint16        RX_cnt;                            //收到字节计数器.110     uint16        TX_cnt;                            //发送字节计数器.111     uint16        RX_len;                            //已接收的字节长度.112     uint16        TX_len;                            //待发送的字节长度.113     uint8        RX_Buffer[BUFFER_SIZE];            //串口接收缓冲区.114     uint8        TX_Buffer[BUFFER_SIZE];            //串口发送缓冲区.            115116    }uart_info;  117118//结构实体定义119 UART_EXT    uart_info        UART[4];            //4个结构对应4个串口.120121122/*123******************************************************************************************************  124**函数名称:    UART_IO_INIT(uint8 COM)                                                                     **  125**函数描述:所有串口IO初始化---RTS根据自己的实际情况修改!                                             **  126**参    数:    COM--------串口: 0,1,2,3                                                                **  127**返    回:    无                                                                                         **  128******************************************************************************************************  129*/130 UART_EXT void UART_IO_INIT(uint8 COM);  131132/*133******************************************************************************************************  134**函数名称:    void UART_INIT(uint8 COM, uint32 BaudRate)                                                 **  135**函数描述:串口UART初始化                                                                             **  136**参    数:    COM--------串口: 0,1,2,3                                                                 **  137**          BaudRate---波特率                                                                         **   138**返    回:    无                                                                                         **  139******************************************************************************************************  140*/141 UART_EXT void UART_INIT(uint8 COM, uint32 BaudRate);  142143/*144******************************************************************************************************  145**函数名称:    uint16 UART_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)                **  146**函数描述:串口UART发送多个字节(供外部文件调用)                                                     **  147**参    数:    COM---------串口: 0,1,2,3                                                                 **  148**          txbuf-------数据指针,指向发送缓冲区                                                     **  149**            len---------待发送字节数                                                                  **  150**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  151**返    回:    bSent---成功发送字节数                                                                     **  152******************************************************************************************************  153*/154 UART_EXT uint16 UART_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485);  155156/*157******************************************************************************************************  158**函数名称:    uint16 UART_SendStrings(uint8 COM, char *txbuf, State USE_RS485)                        **  159**函数描述:串口UART发送字符串(供外部文件调用)                                                         **  160**参    数:    COM---------串口: 0,1,2,3                                                                 **  161**          txbuf-------数据指针,指向发送缓冲区                                                     **  162**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  163**返    回:    bSent---成功发送字节数                                                                     **  164******************************************************************************************************  165*/166 UART_EXT uint16 UART_SendStrings(uint8 COM, char *txbuf, State USE_RS485);  167168/*169******************************************************************************************************  170**函数名称:    void UART_IRQ_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)            **  171**函数描述:串口UART中断发送多个字节(供外部文件调用)                                                 **  172**参    数:    COM---------串口: 0,1,2,3                                                                 **  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--;  430         FIFO_CNT--;  431        }  432433//如果还有数据未发送完,则使能串口中断。反之,则关闭串口中断.434if(UART_CHK_LSR(COM,LSR_THRE) == RESET)                        //THR不为空.435        {  436         UART_IRQ_CFG(COM, IRQ_THRE, ENABLE);                    //使能串口发送中断.437         UART_INFO->TX_OK = FALSE;          438        }  439else440        {  441         UART_IRQ_CFG(COM, IRQ_THRE, DISABLE);                    //关闭串口发送中断.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为空,即最后一个数据发送完成(已移出TSR).447         RS485_EN(COM, RESET, USE_RS485);                        //RS485收发使能信号---RST_x为低---接收数据.448        }  449}  450451/*452******************************************************************************************************  453**函数名称:    void UART_IRQ_SendBytes(uint8 COM, uint8 *txbuf, uint16 len, State USE_RS485)            **  454**函数描述:串口UART中断发送多个字节(供外部文件调用)                                                 **  455**参    数:    COM---------串口: 0,1,2,3                                                                 **  456**          txbuf-------数据指针,指向发送缓冲区                                                     **  457**            len---------待发送字节数                                                                  **  458**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  459**返    回:    ERR---发送失败        OK---发送成功                                                         **  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);                    //复制等待发送的数据到发送缓冲区.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);                                //将数据写到THR.475476}  477478/*479******************************************************************************************************  480**函数名称:    void UART_IRQ_SendStrings(uint8 COM, char *txbuf, State USE_RS485)                         **  481**函数描述:串口UART中断发送字符串(供外部文件调用)                                                     **  482**参    数:    COM---------串口: 0,1,2,3                                                                 **  483**          txbuf-------数据指针,指向发送缓冲区                                                     **  484**            USE_RS485---DISABLE:不使能RS485_EN        ENABLE:使能RS485_EN                             **  485**返    回:    ERR---发送失败        OK---发送成功                                                         **  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);                //复制等待发送的数据到发送缓冲区.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);                                //将数据写到THR.501502}  503504/*505******************************************************************************************************  506**函数名称:    uint8 UART_Recv(uint8 COM)                                                                **  507**函数描述:串口UART接收一个字节                                                                     **  508**参    数:    COM--------串口: 0,1,2,3                                                                 **  509**返    回:    接收到的数据                                                                             **  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**函数名称:    void UART_IRQ_RecvBytes(uint8 COM, uint32 IIR_ID)                                        **  528**函数描述:串口UART中断接收多个字节(供中断服务程序调用)                                             **  529**参    数:    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//接收数据可用中断---实际有RX_FIFO_SIZE个字节,但只读取RX_FIFO_SIZE-1个字节,对于刚好是RX_FIFO_SIZE的整数倍个数据时,留1字节产生CTI中断!否则无法创建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中是否还包仿有效数据,有则继续读取.              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**函数名称:    void UART_IRQ_SERVICE(uint8 COM)                                                        **  570**函数描述:串口中断服务程序回调函数                                                                 **  571**参    数:    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//接收线状态中断---本例不作处理,也没有使能该中断.582583/****处理程序****/584585//接收数据中断586if((IIR_ID == IIR_RDA) || (IIR_ID == IIR_CTI))  587        {  588        UART_IRQ_RecvBytes(COM, IIR_ID);  589        }  590591//发送数据中断592if(IIR_ID == IIR_THRE)  593        {  594        UART_IRQ_Send(COM, ENABLE);  595        }  596}  597598/*599******************************************************************************************************  600**函数名称:    void UART0_IRQHandler(void)                                                                 **  601**函数描述:UART0中断服务程序                                                                         **  602**参    数:    无                                                                                         **  603**返    回:    无                                                                                         **  604******************************************************************************************************  605*/606void UART0_IRQHandler(void)   607{  608609    UART_IRQ_SERVICE(UART0);  610611}  612613/*614******************************************************************************************************  615**函数名称:    void UART1_IRQHandler(void)                                                                 **  616**函数描述:UART1中断服务程序                                                                         **  617**参    数:    无                                                                                         **  618**返    回:    无                                                                                         **  619******************************************************************************************************  620*/621void UART1_IRQHandler(void)   622{  623624    UART_IRQ_SERVICE(UART1);  625626}  627628/*629******************************************************************************************************  630**函数名称:    void UART2_IRQHandler(void)                                                                 **  631**函数描述:UART2中断服务程序                                                                         **  632**参    数:    无                                                                                         **  633**返    回:    无                                                                                         **  634******************************************************************************************************  635*/636void UART2_IRQHandler(void)   637{  638639    UART_IRQ_SERVICE(UART2);  640641}  642643/*644******************************************************************************************************  645**函数名称:    void UART3_IRQHandler(void)                                                                 **  646**函数描述:UART3中断服务程序                                                                         **  647**参    数:    无                                                                                         **  648**返    回:    无                                                                                         **  649******************************************************************************************************  650*/651void UART3_IRQHandler(void)   652{  653654    UART_IRQ_SERVICE(UART3);  655656}  657658659660/*661******************************************************************************************************  662**                                    另类printf函数构造方法                                             **  663******************************************************************************************************  664*/665666/*667******************************************************************************************************  668**函数名称:    void UART_Printf(char *fmt,...)                                                          **  669**函数描述:UART0串口打印程序函数                                                                    **  670**参    数:    *fmt---格式                                                                                 **  671**返    回:    无                                                                                         **  672******************************************************************************************************  673*/674//构造此函数必须包含#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//中断方式发送686     UART_IRQ_SendStrings(UART0,string,ENABLE);    //串口UART0发送字符串函数---须自行构造!   687688//非中断方式发送  689//UART_SendStrings(UART0,string,ENABLE);    //串口UART0发送字符串函数---须自行构造! 690691    va_end(ap);   692}  693694/*695******************************************************************************************************  696**                                            End Of File                                             **  697******************************************************************************************************  698*/

关键字:LPC17XX  串口  接收发送中断  RS485 引用地址:LPC17XX 串口接收发送中断(含RS485)最全面驱动程序

上一篇:LPC21XX 串口的接收和发送中断(MDK)
下一篇:LPC17XX串口接收数据死机现象解决办法

推荐阅读最新更新时间:2024-03-16 14:57

STM32 串口通信OLED屏幕显示(IIC)心得体会
主机:单片机 从机:oled 当主机向从机写入数据时,从机需要向主机返回应答信号 每写入一个字节,则需等待应答信号:在scl和sda都为高时 当主机向从机中读取数据时,主机需要向从机给应答信号 此时,给应答信号,则表示还需要读取数据;如果给非应答信号,则表示不再读取数据 IIC模式 SDA PA1 //D1 SCL PA2 //D0 DC PA3 //地址选择 0 地址为0x78 1 地址为0x7A RES PA4 //复位引脚 CS PA5 //默认接地 电阻R3换到R1 R8短接 16(8x16)号字体 一个字符纵向占两个字节 横向占一个字节 12(6x8)号字体 一个字符纵向占1个字节 横向占6bit 主
[单片机]
将JZ2440调试串口改成COM2
众所周知,JZ2440 V2很小巧,精致。今天单就JZ2440的串口来讨论一些问题。我们在用串口进行调试的时候,需要用JZ2440自带的一根USB线连接电脑USB口和开发板的USB-com1口。先来看一下JZ2440的串口大致连接图: 从S3C2440芯片上引出TXD0和RXD0到芯片PL2303,大家都知道PL2303是干嘛用的。在单片机开发板上一般都用这个芯片,它的作用就是USB转TTL电平,经过PL2303的转换之后,电脑和开发板即可通信,设置好参数后也就能够显示出开发板的打印信息了。JZ2440在这一点上还有一处可以说说,就是它没有使用其他品牌开发板常用的RS232 DB9接口,这在很大程度上减小了开发板的体积,同时也节
[单片机]
将JZ2440调试<font color='red'>串口</font>改成COM2
stm32——串口1和串口2初始化
void USART1_Initialise(u32 bound) { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //USART1_TX PA.9 GPIO_InitStructur
[单片机]
基于LabVIEW的步进电机控制
    步进电机是一种将电脉冲信号转换成角位移或线位移的机电元件。它在在工业自动化控制、数控机床、机器人等领域有着广泛的应用。在远程实验系统中,经常有需要利用步进电机对一些旋钮、位置等进行自动调节。本文设计了基于虚拟仪器技术的步进电机控制方案。该方案采用虚拟仪器控制步进电机,编程简单,界面友好,易于更改程序功能,控制灵活性得到了提高。 1 步进电机工作原理     步进电机按其力矩产生原理可以分为反应式、永磁式和混合式几种。本文采用的是反应式二相四线步进电机,定子有两个线圈绕组,设其中一个线圈绕组为A相,另一个线圈绕组为B相。当给A相绕组通电时,该绕组即产生磁场,转子齿与A相绕组各齿对齐;当给B相绕组通电时,转子齿将与B相绕组各齿对
[嵌入式]
RS485总线与M-Bus 总线技术对比
目前工控中采用较多多的通讯方式仍然以RS485总线为主,这使得原本为工业自动化数据采集而设计的少结点(一般不多于100点)、短距离(一般数百米)、可规范布线的485总线通讯在多结点(以千、万计)、长距离(数千米)、任意分布的布线方式的通讯中难以可靠应用,即使目前在工业自动化应用领域中,多结点、远距离的数据通讯也早以采用了PRFBUS、CAN、HART、FF等通讯方式。在欧洲,户用仪表的通讯方式以M-BUS为主,它可以解决多结点、长距离的通讯问题.      目前国内诸多大型水、电、气、热表企业已采用或拟采用MBUS总线通讯技术。     M-BUS是一种低成本的一点对多点的总线通讯系统,具有通讯设备容量大(500点),通讯速率高
[嵌入式]
基于STM32F103——DS18B20温度采集+串口打印
DS18B20相关介绍 DS18B20特性 1.独特的单总线接口,就需一条线则可实现双向通信(测温) 2.测温范围:-55℃~+125℃,可通过编程设定9—12位分辨率,对应分辨温度分别为0.5、0.25、0.125、0.0625℃。 3.支持多点组网(可连接多个DS18B20温度传感器),多个DS18B20可以并联(3或2线)实现多个组网测温,但注意超过8个要解决好供电问题,否则电压过低会导致传输不稳定,从而数据不准确。 4.工作电压:3.0~5.5V (寄生电源方式下可由数据线供电) 5.在使用过程中不需要外围电路,全部传感元件及转换电路都在芯片内了。(上拉电阻) 6.测温结果直接是数字量输出,单总线串行传送方式,同时可传送C
[单片机]
基于STM32F103——DS18B20温度采集+<font color='red'>串口</font>打印
S3C2440串口(1)
1.S3C2440串口概述 串口通讯一般要增加电平转换电路,原因是TTL/CMOS电平与RS232电平不一致: TTL/CMOS电平: CMOS电平: 常用的电平转换芯片是MAX3232。 S3C2440有3个独立的异步串口,可以选择工作在中断或DMA方式下。每个UART包括一个波特率发生器、发送器、接收器和一个控制单元。 UART有FIFO模式和非FIFO模式。FIFO模式下可以利用64字节的发送/接收缓冲寄存器,非FIFO模式下只使用了发送/接收缓冲寄存器中的1个字节。本篇入门级以非FIFO为例。 2.串口设置及相关寄存器 串口引脚是GPIO复用的。本篇UART只用3根引脚:TXD、RXD、GND。 TXD0 – G
[单片机]
基于STM8L15x单片机的串口printf输出程序分享
这里我们以STM8L15x系列单片机使用ADC内部参考电压测量VDD电压并将电压值value通过窗口打印为例编写程序,(STM8L使用ADC内部参考电压通道测量VDD电压) usart.h头文件: #ifndef _usart_H #define _usart_H #include “stm8l15x.h” void Usart_Init(void); #endif usart.c源文件: #include “usart.h” void Usart_Init(void) { CLK_PeripheralClockConfig (CLK_Peripheral_USART1,ENABLE); //开启USART1时钟 USART_
[单片机]
基于STM8L15x单片机的<font color='red'>串口</font>printf输出程序分享
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved