uart驱动(for keil rtx)
2012-06-02
标签: uart

#define UART0_BPS9600

#define UART0_RXBUF_SIZE 32

#defineUART0_TXBUF_SIZE 32

#define UART_NO_ERR0

#define UART_TX_EMPTY1

extern void uart0_init (void);

extern void uart0_putc (uint8_t c);

extern void uart0_puts (uint8_t *pbuf, uint16_t len);

extern uint8_t uart0_getc (void);

typedef struct {

OS_SEMrx_sem;// Rx信号量

uint16_trx_cnt;// Rx缓冲中字符数

uint8_t*rx_pi;// 指向下一字符将被插入的位置

uint8_t*rx_po;// 指向下一字符将被提取的位置

uint8_trx_buf[UART0_RXBUF_SIZE];// Rx缓冲

OS_SEMtx_sem;// Tx信号量

uint16_ttx_cnt;// Tx缓冲中字符数

uint8_t*tx_pi;// 指向下一字符将被插入的位置

uint8_t*tx_po;// 指向下一字符将被提取的位置

uint8_ttx_buf[UART0_TXBUF_SIZE];// Tx缓冲

uint8_ttx_busy;// Tx忙标志

} UART0_BUF;

static UART0_BUF uart0_buf;

static UART0_BUF *pbuf0 = &uart0_buf;

void uart0_putrx (uint8_t c)

{

if (pbuf0->rx_cnt < UART0_RXBUF_SIZE) {

pbuf0->rx_cnt++;

*pbuf0->rx_pi++ = c;

if(pbuf0->rx_pi == &pbuf0->rx_buf[UART0_RXBUF_SIZE]) {

pbuf0->rx_pi = &pbuf0->rx_buf[0];

}

isr_sem_send (pbuf0->rx_sem);

}

}

uint8_t uart0_gettx (uint8_t *perr)

{

uint8_tc;

if (pbuf0->tx_cnt > 0) {

pbuf0->tx_cnt--;

c = *pbuf0->tx_po++;

if (pbuf0->tx_po == &pbuf0->tx_buf[UART0_TXBUF_SIZE]) {

pbuf0->tx_po = &pbuf0->tx_buf[0];

}

isr_sem_send (pbuf0->tx_sem);

*perr = UART_NO_ERR;

return (c);

} else {

*perr = UART_TX_EMPTY;

return (0);

}

}

void uart0_proc (void) __irq

{

uint8_t iir, c;

uint8_t i, err;

while (((iir = U0IIR) & 0x01) ==0) {

switch (iir & 0x0E) {

case 0x04:

case 0x0C:

for (i=0; i<16; i++) {

if ((U0LSR & 0x01)==0) break;

uart0_putrx (U0RBR);

}

break;

case 0x02:

for (i=0; i<16; i++) {

c = uart0_gettx (&err);

if (err == UART_NO_ERR) {

U0THR = c;

} else {

pbuf0->tx_busy = 0;

break;

}

}

break;

}

}

VICVectAddr = 0x00;

}

void uart0_init (void)

{

PINSEL0 &= 0xFFFFFFF0;

PINSEL0 |= 0x00000005;

U0LCR = 0x83;

U0DLM = (FPCLK / 16) / UART0_BPS / 256;

U0DLL = (FPCLK / 16) / UART0_BPS % 256;

U0LCR = 0x03;

U0FCR = 0x87;

U0IER = 0x03;

pbuf0->rx_cnt = 0;

pbuf0->rx_pi= &pbuf0->rx_buf[0];

pbuf0->rx_po= &pbuf0->rx_buf[0];

os_sem_init (pbuf0->rx_sem, 0);

pbuf0->tx_cnt = 0;

pbuf0->tx_pi= &pbuf0->tx_buf[0];

pbuf0->tx_po= &pbuf0->tx_buf[0];

os_sem_init (pbuf0->tx_sem, UART0_TXBUF_SIZE);

pbuf0->tx_busy = 0;

VICVectCntl0 = 0x26;

VICVectAddr0 = (uint32_t)uart0_proc;

VICIntEnable|= 0x40;

}

uint8_t uart0_getc (void)

{

uint8_t c;

os_sem_wait (pbuf0->rx_sem, 0xFFFF);

irq_lock ();

pbuf0->rx_cnt--;

c = *pbuf0->rx_po++;

if (pbuf0->rx_po == &pbuf0->rx_buf[UART0_RXBUF_SIZE]) {

pbuf0->rx_po = &pbuf0->rx_buf[0];

}

irq_unlock ();

return (c);

}

void uart0_putc (uint8_t c)

{

os_sem_wait (pbuf0->tx_sem, 0xFFFF);

irq_lock ();

pbuf0->tx_cnt++;

*pbuf0->tx_pi++ = c;

if (pbuf0->tx_pi == &pbuf0->tx_buf[UART0_TXBUF_SIZE]){

pbuf0->tx_pi = &pbuf0->tx_buf[0];

}

if (pbuf0->tx_busy == 0) {

pbuf0->tx_busy = 1;

pbuf0->tx_cnt--;

c = *pbuf0->tx_po++;

if (pbuf0->tx_po == &pbuf0->tx_buf[UART0_TXBUF_SIZE]) {

pbuf0->tx_po = &pbuf0->tx_buf[0];

}

os_sem_send (pbuf0->tx_sem);

U0THR = c;

}

irq_unlock ();

}

void uart0_puts (uint8_t *pbuf, uint16_t len)

{

while (len--) {

uart0_putc (*pbuf++);

}

}

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号