📄 uart.c
字号:
#include <LPC21xx.h>#include <uart.h>#include <uartdefs.h>#include <armVIC.h>#include <sysdefs.h>//////////////////////////////////////////////////////////////////// this code common to both processors, be carefull not to make// these functions tied to one processors' features!//////////////////////////////////////////////////////////////////// queue and buffer variables.uchar rx0Buffer [RX0BUFFSIZE+1];uchar tx0Buffer [TX0BUFFSIZE+1];volatile ushort tx0RdQue, tx0WrQue, rx0RdQue, rx0WrQue;volatile bool tx0Running;uchar rx1Buffer [RX1BUFFSIZE+1];uchar tx1Buffer [TX1BUFFSIZE+1];volatile ushort tx1RdQue, tx1WrQue, rx1RdQue, rx1WrQue;volatile bool tx1Running;extern bool Tx5Active;void serial0Init (uint16_t baud, uint8_t mode, uint8_t fmode){ // init hardware and connect to interrupt controller.uchar dummy; // change to special function: uart0 PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL; // disable any interrupts currently enabled. U0IER = 0; // wipe fifo clean. U0FCR = fmode | UFCR_RX_FIFO_RESET | UFCR_TX_FIFO_RESET | UFCR_FIFO_ENABLE; // clear any possible interrupt sources. dummy = U0IIR; dummy = U0RBR; dummy = U0LSR; // set the baudrate. U0LCR |= ULCR_DLAB_ENABLE; // turn on DLAB. U0DLL = (uint8_t) baud; U0DLM = (uint8_t)(baud >> 8); // set char bitlen, stopbit(s), parity & break. U0LCR = (mode & ~ULCR_DLAB_ENABLE); // connect our ISR routine to interrupt controller now. Uart0VectCntl = VIC_ENABLE | VIC_UART0; Uart0VectAddr = (uint32_t)serial0ISR; VICIntSelect &= ~VIC_BIT(VIC_UART0); VICIntEnable |= VIC_BIT(VIC_UART0); // init the queue pointers. tx0WrQue = tx0RdQue = rx0WrQue = rx0RdQue = 0; tx0Running = False; // turn on receiver interrupts now. U0IER = UIER_ERBFI | UIER_ETBEI;}void serial1Init (uint16_t baud, uint8_t mode, uint8_t fmode){ // init hardware and connect to interrupt controller.uchar dummy; // change to special function: uart0 PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL; // disable any interrupts currently enabled. U1IER = 0; // wipe fifo clean. U1FCR = fmode | UFCR_RX_FIFO_RESET | UFCR_TX_FIFO_RESET | UFCR_FIFO_ENABLE; // clear any possible interrupt sources. dummy = U1IIR; dummy = U1RBR; dummy = U1LSR; // set the baudrate. U1LCR |= ULCR_DLAB_ENABLE; // turn on DLAB. U1DLL = (uint8_t) baud; U1DLM = (uint8_t)(baud >> 8); // set char bitlen, stopbit(s), parity & break. U1LCR = (mode & ~ULCR_DLAB_ENABLE); // connect our ISR routine to interrupt controller now. Uart1VectCntl = VIC_ENABLE | VIC_UART1; Uart1VectAddr = (uint32_t)serial1ISR; VICIntSelect &= ~VIC_BIT(VIC_UART1); VICIntEnable |= VIC_BIT(VIC_UART1); // init the queue pointers. tx1WrQue = tx1RdQue = rx1WrQue = rx1RdQue = 0; tx1Running = False; // turn on receiver interrupts now. U1IER = UIER_ERBFI | UIER_ETBEI;}void serial0Putch (const uchar ch){ // send a char.ushort txWrIdx;unsigned flags_cpsr; // wait until there is room. txWrIdx = (tx0WrQue+1) & TX0MASK; while (txWrIdx == tx0RdQue); // disable interrupts while stuff char. flags_cpsr = disableIRQ(); // transmitter running? if (tx0Running == False) { // stuff char into TX data register. U0THR = (uint8_t)ch; Tx5Active = True; tx0Running = True; } else { tx0Buffer [tx0WrQue] = ch; tx0WrQue = txWrIdx; } restoreIRQ(flags_cpsr);}void serial0Write (const uchar * buff, int count){// write a group of bytes.int i; for (i=0; i<count; i++) serial0Putch(buff[i]);}int serial0Read (uchar * buff, int count){// read a group of bytes.int i; if (serial0RxCharCount() < count) return 0; for (i=0; i<count; i++) { buff [i] = serial0Getch(); } return count;}void serial0Puts (const uchar *str){// simply a multiple Putch.int i; for (i=0; str[i]; i++) serial0Putch(str[i]);}bool serial0RxHasData (void){ // simple test to see if data pending. return (bool)(rx0RdQue != rx0WrQue);}int serial0RxCharCount (void){ // return number of chars in the buffer. return (int) ((rx0RdQue>rx0WrQue) ? (rx0WrQue + (RX0BUFFSIZE - rx0RdQue)) : (rx0WrQue - rx0RdQue));}bool serial0TxHasData (void){ // simple test to see if data pending. return (bool)(tx0RdQue != tx0WrQue);}uchar serial0Getch (void){// pull one char from the uart.uchar ch; if (rx0RdQue != rx0WrQue) { ch = rx0Buffer [rx0RdQue]; rx0RdQue = (rx0RdQue+1) & RX0MASK; } else ch = (uchar)-1; return ch;}void serial1Putch (const uchar ch){ // send a char.ushort txWrIdx;unsigned flags_cpsr; // wait until there is room. txWrIdx = (tx1WrQue+1) & TX1MASK; while (txWrIdx == tx1RdQue); // disable interrupts while stuff char. flags_cpsr = disableIRQ(); // transmitter running? if (tx1Running == False) { // stuff char into TX data register. U1THR = (uint8_t)ch; tx1Running = True; } else { tx1Buffer [tx1WrQue] = ch; tx1WrQue = txWrIdx; } restoreIRQ(flags_cpsr);}void serial1Write (const uchar * buff, int count){// write a group of bytes.int i; for (i=0; i<count; i++) serial1Putch(buff[i]);}void serial1Puts (const uchar *str){// simply a multiple Putch.int i; for (i=0; str[i]; i++) serial1Putch(str[i]);}bool serial1RxHasData (void){ // simple test to see if data pending. return (bool)(rx1RdQue != rx1WrQue);}bool serial1TxHasData (void){ // simple test to see if data pending. return (bool)(tx1RdQue != tx1WrQue);}uchar serial1Getch (void){// pull one char from the uart.uchar ch; if (rx1RdQue != rx1WrQue) { ch = rx1Buffer [rx1RdQue]; rx1RdQue = (rx1RdQue+1) & RX1MASK; } else ch = (uchar)-1; return ch;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -