⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comm_fw.c

📁 嵌入式软件构件:TMR计时器管理、CLK实时时钟、KEY键盘扫描、LED数码显示、LCD显示、COMM串口通信
💻 C
字号:
/*
*********************************************************************************************************
* Filename   : COMM_FW.C
* Programmer : Haven
* 描述:      串行口通信程序
* DATE:        2007.11.18
****************************************************************************************
*/
#define COMM_GLOBALS
#include "..\includes\includes.H"
DEFINE_THIS_MODULE(COMM_FK)

typedef struct {
    INT16U  RingBufRxCtr;                   
    INT8U  *RingBufRxInPtr;                 
    INT8U  *RingBufRxOutPtr;                
    INT8U   RingBufRx[COMM_RX_BUF_SIZE];   
    INT16U  RingBufTxCtr;                   
    INT8U  *RingBufTxInPtr;                 
    INT8U  *RingBufTxOutPtr;                
    INT8U   RingBufTx[COMM_TX_BUF_SIZE];    
} COMM_RING_BUF;

/*
*********************************************************************************************************
*                                            GLOBAL VARIABLES
*********************************************************************************************************
*/

COMM_RING_BUF  Comm1Buf;
COMM_RING_BUF  Comm2Buf;
COMM_RING_BUF  Comm3Buf;
COMM_RING_BUF  Comm4Buf;

void  CommInit (void)
{
    COMM_RING_BUF *pbuf;

    pbuf                  = &Comm1Buf;                     
    pbuf->RingBufRxCtr    = 0;
    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];
    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
    pbuf->RingBufTxCtr    = 0;
    pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];
    pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

    pbuf                  = &Comm2Buf;                     
    pbuf->RingBufRxCtr    = 0;
    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];
    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
    pbuf->RingBufTxCtr    = 0;
    pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];
    pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
    
    pbuf                  = &Comm3Buf;                     
    pbuf->RingBufRxCtr    = 0;
    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];
    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
    pbuf->RingBufTxCtr    = 0;
    pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];
    pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

    pbuf                  = &Comm4Buf;                     
    pbuf->RingBufRxCtr    = 0;
    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];
    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
    pbuf->RingBufTxCtr    = 0;
    pbuf->RingBufTxInPtr  = &pbuf->RingBufTx[0];
    pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
}
/*
*********************************************************************************************************
清接收缓冲区
********************************************************************************************************
*/
void CommClrRxBuf(INT8U ch)
{
	INT8U err;
    if(!CommIsRxEmpty(ch)){           //如果接收缓冲区不空
        while(!CommIsRxEmpty(ch)){
             CommGetRxChar(ch,&err);
        }
    }
}

/*
*********************************************************************************************************
*中断中发送数据调用,从TX缓冲区取数
********************************************************************************************************
*/

INT8U  CommGetTxChar (INT8U ch, INT8U *err)
{
    INT8U          c;
    COMM_RING_BUF *pbuf;


    switch (ch) {                                         
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        case COMM4:
             pbuf = &Comm4Buf;
             break;
        default:
             *err = COMM_BAD_CH;
             return (NUL);
    }
    if (pbuf->RingBufTxCtr > 0) {                          
        pbuf->RingBufTxCtr--;                              
        c = *pbuf->RingBufTxOutPtr++;                      
        if (pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COMM_TX_BUF_SIZE]) {     
            pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];
        }
        *err = COMM_NO_ERR;
        return (c);                                        
    } else {
        *err = COMM_TX_EMPTY;
        return (NUL);                                     
    }
}
/*
*********************************************************************************************************
** Description : 应用程序发送数据到TX缓冲区
* Arguments     'c'     is the character to send.
* Returns     : COMM_NO_ERR   如果函数调用成功 (如果发送缓冲区不满)
*               COMM_TX_FULL  如果发送缓冲区满
*               COMM_BAD_CH   如果通道错误
*********************************************************************************************************
*/

INT8U  CommPutTxChar (INT8U ch, INT8U c)
{
    COMM_RING_BUF *pbuf;

    switch (ch) {                                          
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        case COMM4:
             pbuf = &Comm4Buf;
             break;
        default:
             return (COMM_BAD_CH);
    }
    OS_ENTER_CRITICAL();
    ASSERT(pbuf->RingBufTxCtr < COMM_TX_BUF_SIZE);
    if (pbuf->RingBufTxCtr < COMM_TX_BUF_SIZE) {           
        pbuf->RingBufTxCtr++;                              
        *pbuf->RingBufTxInPtr++ = c;                      
        if (pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COMM_TX_BUF_SIZE]) { 
            pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];
        }
        if (pbuf->RingBufTxCtr == 1) {                     
            CommTxIntEn(ch);                              
            OS_EXIT_CRITICAL();
        } else {
            OS_EXIT_CRITICAL();
        }
        return (COMM_NO_ERR);
    } else {
        OS_EXIT_CRITICAL();
        return (COMM_TX_FULL);
    }
}
/*
*********************************************************************************************************
* Description : 测试TX缓冲区是否满?
* Returns     : TRUE    如果发送缓冲区满.
*               FALSE   如果发送缓冲区不满
*********************************************************************************************************
*/

BOOLEAN  CommIsTxFull (INT8U ch)
{
    BOOLEAN        full;
    COMM_RING_BUF *pbuf;


    switch (ch) {                                         
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        case COMM4:
             pbuf = &Comm4Buf;
             break;
        default:
             return (NUL);
    }
    OS_ENTER_CRITICAL();
    if (pbuf->RingBufTxCtr < COMM_TX_BUF_SIZE) {          
        full = FALSE;                                     
    } else {
        full = TRUE;                                       
    }
    OS_EXIT_CRITICAL();
    return (full);
}
/*
*********************************************************************************************************
* Description : 接收数据放入缓冲区(接收中断调用)
* Arguments   : 把'c'插入到环形缓冲区
*               不能插入,则丢弃.
*********************************************************************************************************
*/

void  CommPutRxChar (INT8U ch, INT8U c)
{
    COMM_RING_BUF *pbuf;

    switch (ch) {                                         
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        case COMM4:
             pbuf = &Comm4Buf;
             break;
    }
    ASSERT(pbuf->RingBufRxCtr < COMM_RX_BUF_SIZE);
    if (pbuf->RingBufRxCtr < COMM_RX_BUF_SIZE) {           
        pbuf->RingBufRxCtr++;                              
        *pbuf->RingBufRxInPtr++ = c;                       
        if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) {
            pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
        }
    }
}

/*
*********************************************************************************************************
*应用中调用,从RX缓冲区取数
*********************************************************************************************************
*/
INT8U  CommGetRxChar (INT8U ch, INT8U *err)
{
    INT8U          c;
    COMM_RING_BUF *pbuf;

    switch (ch) {                                         
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        case COMM4:
             pbuf = &Comm4Buf;
             break;
        default:
             *err = COMM_BAD_CH;
             return (NUL);
    }
    OS_ENTER_CRITICAL();
    if (pbuf->RingBufRxCtr > 0) {                          
        pbuf->RingBufRxCtr--;                              
        c = *pbuf->RingBufRxOutPtr++;                     
        if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COMM_RX_BUF_SIZE]) {     
            pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
        }
        OS_EXIT_CRITICAL();
        *err = COMM_NO_ERR;
        return (c);
    } else {
        OS_EXIT_CRITICAL();
        *err = COMM_RX_EMPTY;
        c    = NUL;                                        
        return (c);
    }
}

/*
*********************************************************************************************************
* Description : 测试接收RX缓冲区是否为空
* Returns     : TRUE    如果接收缓冲区为空.
*               FALSE   如果接收缓冲区为不空
*********************************************************************************************************
*/

BOOLEAN  CommIsRxEmpty(INT8U ch)
{
    BOOLEAN        empty;
    COMM_RING_BUF *pbuf;


    switch (ch) {                                         
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        case COMM4:
             pbuf = &Comm4Buf;
             break;
        default:
             return (NUL);
    }
    OS_ENTER_CRITICAL();
    if (pbuf->RingBufRxCtr > 0) {                          
        empty = FALSE;                                     
    } else {
        empty = TRUE;                                      
    }
    OS_EXIT_CRITICAL();
    return (empty);
}
/*
*********************************************************************************************************
* Description : 测试接收RX缓冲区是否为空
* Returns     : TRUE    如果接收缓冲区为空.
*               FALSE   如果接收缓冲区为不空
*********************************************************************************************************
*/
BOOLEAN  CommIsRxEmptyISR(INT8U ch)
{
    BOOLEAN        empty;
    COMM_RING_BUF *pbuf;


    switch (ch) {                                         
        case COMM1:
             pbuf = &Comm1Buf;
             break;
        case COMM2:
             pbuf = &Comm2Buf;
             break;
        case COMM3:
             pbuf = &Comm3Buf;
             break;
        case COMM4:
             pbuf = &Comm4Buf;
             break;
        default:
             return (NUL);
    }
    if (pbuf->RingBufRxCtr > 0) {                          
        empty = FALSE;                                     
    } else {
        empty = TRUE;                                      
    }
    return (empty);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -