luoyiming1984 发表于 2012-5-4 00:05:50

LPC2142 在keil RTX-ARM操作系统下 UART使用队列的方式。







#include "uart.h"


//#define uart0_unlock();           VICIntEnable = 1 << VIC_UART0
//#define uart0_lock();      VICIntEnClr= 1 << VIC_UART0

#define QueuePush(p)

//static
UartQueue_t UartQueue0;
UartQueue_t UartQueue1;


static void UartQueueInit(UartQueue_t* queue)
{
        os_sem_init (queue->rxSem.sem, 0);
        queue->rxPush = queue->rxBuf;
        queue->rxPop= queue->rxBuf;
        queue->rxTick = 0;
       
        os_sem_init (queue->txSem.sem,UART_TX_SIZE);
        queue->txPush = queue->txBuf;
        queue->txPop= queue->txBuf;
        queue->txTick = 0;
}





INT16U UartRead(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
        INT16U n;
        UartQueue_t *pqueue;
        switch(port)
        {
                case PORT_UART0:
                        pqueue = &UartQueue0;
                break;
               
                case PORT_UART1:
                        pqueue = &UartQueue1;
                break;
        }
        for(n=0;n<size;n++)
        {
                if(OS_R_TMO == os_sem_wait(pqueue->rxSem.sem,timeout))
                {
                        break;
                }
                *buf = *pqueue->rxPop;
                buf++;
                pqueue->rxPop++;
                if(pqueue->rxPop == &pqueue->rxBuf)
                {
                        pqueue->rxPop = pqueue->rxBuf;
                }
        }
        return n;
}



INT16U UartWrite(INT8U port,INT8U *buf,INT16U size,INT16U timeout)
{
        INT16U n = 0;
        UartQueue_t *pqueue;
        INT8U*thr;
        INT32U *ier;
        //tsk_lock();
        switch(port)
        {
                case PORT_UART0:
                {
                        pqueue = &UartQueue0;
                        thr = (INT8U*)&U0THR;
                        ier = (INT32U*)&U0IER;
                }
                break;
               
                case PORT_UART1:
                {
                        pqueue = &UartQueue1;
                        thr = (INT8U*)&U1THR;
                        ier = (INT32U*)&U1IER;
                }
                break;
        }
       
        *ier &= ~0x02;
        if(OS_R_TMO != os_sem_wait(pqueue->txSem.sem,0))
        {
                *pqueue->txPush = *buf;
                buf++;
                pqueue->txPush++;
                if(pqueue->txPush == &pqueue->txBuf)
                {
                        pqueue->txPush = pqueue->txBuf;
                }
                n++;
                if(pqueue->txTick == 0)
                {
                        pqueue->txTick = 1;
                        *thr = *pqueue->txPop;
                        pqueue->txPop++;
                        if(pqueue->txPop == &pqueue->txBuf)
                        {
                                pqueue->txPop = pqueue->txBuf;
                        }
                        os_sem_send(pqueue->txSem.sem);
                }
        }
        *ier |= 0x02;
       
        for(;n<size;n++)
        {
                if(OS_R_TMO == os_sem_wait(pqueue->txSem.sem,timeout))
                {
                        break;
                }
                *pqueue->txPush = *buf;
                buf++;
                pqueue->txPush++;
                if(pqueue->txPush == &pqueue->txBuf)
                {
                        pqueue->txPush = pqueue->txBuf;
                }
        }
        return n;
}

/*
        UART0 ISR
*/

__inline void Uart0RxIsr(void)
{
        INT8U c,cnt;
        cnt = UartQueue0.rxSem.cnt;
        while(U0LSR & 0x01)//data in fifo
        {
                c = U0RBR;
                if(cnt < UART_RX_SIZE)
                {
                        isr_sem_send(UartQueue0.rxSem.sem);
                        cnt++;
                        *UartQueue0.rxPush = c;
                        UartQueue0.rxPush++;
                        if(UartQueue0.rxPush == &UartQueue0.rxBuf)
                        {
                                UartQueue0.rxPush = UartQueue0.rxBuf;
                        }
                }
        }
}


__inline void Uart0TxIsr(void)
{
        INT16U n,cnt;
        cnt = UART_TX_SIZE - UartQueue0.txSem.cnt;
        if(cnt)
        {
                for(n=0;n<16;n++)
                {
                        if(0==cnt)
                        {
                                break;
                        }
                        isr_sem_send(UartQueue0.txSem.sem);
                        cnt--;
                        U0THR = *UartQueue0.txPop;
                        UartQueue0.txPop++;
                        if(UartQueue0.txPop == &UartQueue0.txBuf)
                        {
                                UartQueue0.txPop = UartQueue0.txBuf;
                        }
                }
                UartQueue0.txTick = n;
        }
        else
        {
                UartQueue0.txTick = 0;
        }
}


void UART0_IRQ(void) __irq
{
        INT32U INT_ID;
        INT_ID = U0IIR & 0x0E;
        switch(INT_ID)
        {
                case 0x04:
                case 0x0C:
                        Uart0RxIsr();
                break;
               
                case 0x02:
                        Uart0TxIsr();
                break;
               
                default:
                       
                break;
        }
        VICVectAddr = 0;                  /* Acknowledge Interrupt               */       
}



/*
        UART1 ISR
*/

__inline void Uart1RxIsr(void)
{
        INT8U c,cnt;
        cnt = UartQueue1.rxSem.cnt;
        while(U1LSR & 0x01)//data in fifo
        {
                c = U1RBR;
                if(cnt < UART_RX_SIZE)
                {
                        isr_sem_send(UartQueue1.rxSem.sem);
                        cnt++;
                        *UartQueue1.rxPush = c;
                        UartQueue1.rxPush++;
                        if(UartQueue1.rxPush == &UartQueue1.rxBuf)
                        {
                                UartQueue1.rxPush = UartQueue1.rxBuf;
                        }
                }
        }
}


__inline void Uart1TxIsr(void)
{
        INT16U n,cnt;
        cnt = UART_TX_SIZE - UartQueue1.txSem.cnt;
        if(cnt)
        {
                for(n=0;n<16;n++)
                {
                        if(0==cnt)
                        {
                                break;
                        }
                        isr_sem_send(UartQueue0.txSem.sem);
                        cnt--;
                        U0THR = *UartQueue1.txPop;
                        UartQueue1.txPop++;
                        if(UartQueue1.txPop == &UartQueue1.txBuf)
                        {
                                UartQueue1.txPop = UartQueue1.txBuf;
                        }
                }
                UartQueue1.txTick = n;
        }
        else
        {
                UartQueue1.txTick = 0;
        }
}


void UART1_IRQ(void) __irq
{
        INT32U INT_ID;
        INT_ID = U1IIR & 0x0E;
        if ((0x04 == INT_ID) || (0x0C == INT_ID))
        {
                /* Receive interrupt */
                Uart1RxIsr();
        }
                                    
        else if (0x02 == INT_ID)
        {
                /* Transmit interrupt */
                Uart1TxIsr();
        }
        VICVectAddr = 0;                  /* Acknowledge Interrupt               */       
}



/*UART INIT */
void UartIntConfig(INT8U port,INT8U slot,INT32U baud)
{
        if(port == PORT_UART0)
        {
    PINSEL0 &= 0xFFFFFFF0;
    PINSEL0 |= 0x00000005;
                PCONP = PCONP|0x08;
    U0LCR = 0x83;
    U0DLM = (FPCLK / 16) / baud / 256;
    U0DLL = (FPCLK / 16) / baud % 256;
    U0LCR = 0x03;
       
                U0FCR = 0x87;
                U0IER = 0x03;
    *(INT32U*)((INT32U)(&VICVectAddr0) + slot*4) = (U32)UART0_IRQ;
    *(INT32U*)((INT32U)(&VICVectCntl0) + slot*4) = (0x20 | VIC_UART0);
    VICIntEnable = (INT32U)(1 << VIC_UART0);
                UartQueueInit(&UartQueue0);
        }
        else if(port == PORT_UART1)
        {
    PINSEL0 &= 0xFFFFFFF0;
    PINSEL0 |= 0x00000005;
                PCONP = PCONP|0x08;
    U1LCR = 0x83;
    U1DLM = (FPCLK / 16) / baud / 256;
    U1DLL = (FPCLK / 16) / baud % 256;
    U1LCR = 0x03;
       
                U1FCR = 0x87;
                U1IER = 0x03;
    *(INT32U*)((INT32U)(&VICVectAddr0) + slot*4) = (U32)UART1_IRQ;
    *(INT32U*)((INT32U)(&VICVectCntl0) + slot*4) = (0x20 | VIC_UART1);
    VICIntEnable = (INT32U)(1 << VIC_UART1);
                UartQueueInit(&UartQueue1);               
        }
}
页: [1]
查看完整版本: LPC2142 在keil RTX-ARM操作系统下 UART使用队列的方式。