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*/
上一篇:LPC21XX 串口的接收和发送中断(MDK)
下一篇:LPC17XX串口接收数据死机现象解决办法
推荐阅读最新更新时间:2024-03-16 14:57