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