搜索
bottom↓
回复: 0

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

[复制链接]

出0入0汤圆

发表于 2012-5-4 00:05:50 | 显示全部楼层 |阅读模式






#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[UART_RX_SIZE])
                {
                        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[UART_TX_SIZE])
                {
                        pqueue->txPush = pqueue->txBuf;
                }
                n++;
                if(pqueue->txTick == 0)
                {
                        pqueue->txTick = 1;
                        *thr = *pqueue->txPop;
                        pqueue->txPop++;
                        if(pqueue->txPop == &pqueue->txBuf[UART_TX_SIZE])
                        {
                                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[UART_TX_SIZE])
                {
                        pqueue->txPush = pqueue->txBuf;
                }
        }
        return n;
}

/*
        UART0 ISR
*/

__inline void Uart0RxIsr(void)
{
        INT8U c,cnt;
        cnt = UartQueue0.rxSem.cnt[1];
        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[UART_RX_SIZE])
                        {
                                UartQueue0.rxPush = UartQueue0.rxBuf;
                        }
                }
        }
}


__inline void Uart0TxIsr(void)
{
        INT16U n,cnt;
        cnt = UART_TX_SIZE - UartQueue0.txSem.cnt[1];
        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[UART_TX_SIZE])
                        {
                                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[1];
        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[UART_RX_SIZE])
                        {
                                UartQueue1.rxPush = UartQueue1.rxBuf;
                        }
                }
        }
}


__inline void Uart1TxIsr(void)
{
        INT16U n,cnt;
        cnt = UART_TX_SIZE - UartQueue1.txSem.cnt[1];
        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[UART_TX_SIZE])
                        {
                                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);               
        }
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 10:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表