| 
 
| 既然大家都是高手,我就不多罗嗦了,直接以码会友…… 任意数量的串行通讯管道
 
 RD_ADT_QUEUE.h
 ------------------------------------------------------------
 
 #ifndef _USE_ADT_QUEUE_H_
 #define _USE_ADT_QUEUE_H_
 /***********************************************************
 *   声明库说明:抽象数据类型(ADT)队列声明库                *
 *   版本:      v1.01                                      *
 *   作者:      王卓然                                     *
 *   创建日期:  2007年3月23日                              *
 * -------------------------------------------------------- *
 *  [支 持 库]                                              *
 *   支持库名称:                                           *
 *   需要版本:                                             *
 *   支持库说明:                                           *
 * -------------------------------------------------------- *
 *  [版本更新]                                              *
 *   修改:      王卓然                                     *
 *   修改日期:  2007年4月17日                              *
 *   版本:      v1.01                                      *
 * -------------------------------------------------------- *
 *  [版本历史]                                              *
 *       v1.00   该版本提供了基本的抽象数据类型队列的结构定 *
 *               义,以及默认的环形队列处理函数。           *
 *       v1.01   增加了队列空判断函数,和队列首数据预览函数 *
 * -------------------------------------------------------- *
 *  [使用说明]                                              *
 ***********************************************************/
 
 /********************
 * 头 文 件 配 置 区 *
 ********************/
 
 /********************
 *   系 统 宏 定 义  *
 ********************/
 
 /*------------------*
 *   常 数 宏 定 义  *
 *------------------*/
 
 /*------------------*
 *   动 作 宏 定 义  *
 *------------------*/
 # define ADT_QUEUE_DEFAULT_ADD_TO_BUFFER_FUNCTION       ADT_Queue_Add_To_Buffer
 # define ADT_QUEUE_DEFAULT_GET_FROM_BUFFER_FUNCTION     ADT_Queue_Get_From_Buffer
 # define ADT_QUEUE_DEFAULT_CHECK_EMPTY_FUNCTION         ADT_Queue_Check_Empty
 # define ADT_QUEUE_DEFAULT_PEEK_FROM_BUFFER_FUNCTION    ADT_Queue_Peek_From_Buffer
 
 # define START_DEFINE_ADT_QUEUE(Name,Size)  ADT_QUEUE ADTQ_##Name;                                            uint8 ADTQ_##Name##_Buffer[(Size)];                                            void ADT_Queue_##Name##_INIT(void)                                            {                                                ADT_QUEUE *pQueue = &(ADTQ_##Name);                                                pQueue->pBuffer = ADTQ_##Name##_Buffer;                                                pQueue->nSize = (Size);                                                pQueue->nHead = 0;                                                pQueue->nTail = 0;                                                pQueue->nCount = 0;                                                pQueue->fnAddToBuffer = ADT_QUEUE_DEFAULT_ADD_TO_BUFFER_FUNCTION;                                                pQueue->fnGetFromBuffer = ADT_QUEUE_DEFAULT_GET_FROM_BUFFER_FUNCTION;                                                pQueue->fnCheckEmpty = ADT_QUEUE_DEFAULT_CHECK_EMPTY_FUNCTION;                                                pQueue->fnPeekFromBuffer = ADT_QUEUE_DEFAULT_PEEK_FROM_BUFFER_FUNCTION;
 
 
 # define SET_ADT_QUEUE_ADD_FUNCTION(Func)           pQueue->fnAddToBuffer = &(Func);
 # define SET_ADT_QUEUE_GET_FUNCTION(Func)           pQueue->fnGetFromBuffer = &(Func);
 # define SET_ADT_QUEUE_CHECK_EMPTY_FUNCITON(Func)   pQueue->fnCheckEmpty = &(Func);
 # define SET_ADT_QUEUE_PEEK_FUNCTION(Func)          pQueue->fnPeekFromBuffer = &(Func);
 
 # define END_DEFINE_ADT_QUEUE               }
 # define ADT_QUEUE(Name)                    ADTQ_##Name
 # define INIT_ADT_QUEUE(Name)               ADT_Queue_##Name##_INIT();
 
 # define SET_ADT_QUEUE(Queue,Buffer,Size,FuncA,FuncB,FuncC,FuncD) {                        (Queue).pBuffer = (Buffer);                        (Queue).nSize = (Size);                        (Queue).nHead = 0;                        (Queue).nTail = 0;                        (Queue).nCount = 0;                        (Queue).fnAddToBuffer = &(FuncA);                        (Queue).fnGetFromBuffer = &(FuncB);                        (Queue).fnCheckEmpty = &(FuncC);                        (Queue).fnPeekFromBuffer = &(FuncD);                                                }
 # define NEW_ADT_QUEUE(Queue,Size,FuncA,FuncB,FuncC,FuncD) {                        SET_ADT_QUEUE((Queue),NULL,Size,(FuncA),(FuncB),(FuncC),(FuncD))                        Queue.pBuffer = (uint8 *)malloc((Size));                        Queue.nSize = (Size);                                               }
 # define ADT_QUEUE_LET_EMPTY(Queue)     {                        (Queue).nHead = 0;                        (Queue).nTail = 0;                        (Queue).nCount = 0;                                        }
 
 # define ADT_ADD_DATA_TO_QUEUE(Queue,Data)      (*((Queue).fnAddToBuffer))(&(Queue),(Data))
 # define ADT_GET_DATA_FROM_QUEUE(Queue,Var)     (*((Queue).fnGetFromBuffer))(&(Queue),&(Var))
 # define ADT_CHECK_QUEUE_EMPTY(Queue)           (*((Queue).fnCheckEmpty))(&(Queue))
 # define ADT_PEEK_DATA_FROM_QUEUE(Queue,Var)     (*((Queue).fnPeekFromBuffer))(&(Queue),&(Var))
 
 /********************
 *  用户变量类型定义 *
 ********************/
 typedef struct AbstructDataTypeQueue ADT_QUEUE;
 typedef BOOL (*ADD_BUFFER)(ADT_QUEUE *pQueue,uint8 cData);
 typedef BOOL (*GET_BUFFER)(ADT_QUEUE *pQueue,uint8 *pData);
 typedef BOOL (*CHECK_EMPTY)(ADT_QUEUE *pQueue);
 typedef BOOL (*PEEK_BUFFER)(ADT_QUEUE *pQueue,uint8 *pData);
 
 /********************
 *    结构体定义区   *
 ********************/
 struct AbstructDataTypeQueue
 {
 uint8          *pBuffer;
 uint            nSize;
 uint            nHead;
 uint            nTail;
 uint            nCount;
 ADD_BUFFER      fnAddToBuffer;
 GET_BUFFER      fnGetFromBuffer;
 CHECK_EMPTY     fnCheckEmpty;
 PEEK_BUFFER     fnPeekFromBuffer;
 };
 
 /********************
 *   函 数 引 用 区  *
 ********************/
 extern BOOL ADT_Queue_Add_To_Buffer(ADT_QUEUE *pQueue,uint8 cData);
 extern BOOL ADT_Queue_Get_From_Buffer(ADT_QUEUE *pQueue,uint8 *pData);
 extern BOOL ADT_Queue_Check_Empty(ADT_QUEUE *pQueue);
 extern BOOL ADT_Queue_Peek_From_Buffer(ADT_QUEUE *pQueue,uint8 *pData);
 
 /********************
 *   全局变量引用区  *
 ********************/
 
 #endif
 
 
 
 
 RD_ADT_QUEUE.c
 
 -------------------------------------------------------------
 /***********************************************************
 *   函数库说明:抽象数据类型(ADT)队列函数库                *
 *   版本:      v1.01                                      *
 *   作者:      王卓然                                     *
 *   创建日期:  2007年3月23日                              *
 * -------------------------------------------------------- *
 *  [支 持 库]                                              *
 *   支持库名称:RD_MacroAndConst.h                         *
 *   需要版本:  v0.01 &abv                                 *
 *   支持库说明:系统常用宏定义库                           *
 *                                                          *
 *   支持库名称:RD_ADT_QUEUE.h                             *
 *   需要版本:  -----                                      *
 *   支持库说明:抽象数据类型(ADT)队列声明库                *
 * -------------------------------------------------------- *
 *  [版本更新]                                              *
 *   修改:      王卓然                                     *
 *   修改日期:  2007年4月17日                              *
 *   版本:      v1.01                                      *
 * -------------------------------------------------------- *
 *  [版本历史]                                              *
 *       v1.00   该版本提供了基本的抽象数据类型队列的结构定 *
 *               义,以及默认的环形队列处理函数。           *
 *       v1.01   增加了队列空判断函数,和队列首数据预览函数 *
 * -------------------------------------------------------- *
 *  [使用说明]                                              *
 ***********************************************************/
 
 /********************
 * 头 文 件 配 置 区 *
 ********************/
 # include "RD_MacroAndConst.h"
 # include "RD_ADT_QUEUE.h"
 
 /********************
 *   系 统 宏 定 义  *
 ********************/
 
 /*------------------*
 *   常 数 宏 定 义  *
 *------------------*/
 
 /*------------------*
 *   动 作 宏 定 义  *
 *------------------*/
 
 /********************
 *    结构体定义区   *
 ********************/
 
 /********************
 *   模块函数声明区  *
 ********************/
 
 /********************
 *   全局函数声明区  *
 ********************/
 BOOL ADT_Queue_Add_To_Buffer(ADT_QUEUE *pQueue,uint8 cData);
 BOOL ADT_Queue_Get_From_Buffer(ADT_QUEUE *pQueue,uint8 *pData);
 BOOL ADT_Queue_Check_Empty(ADT_QUEUE *pQueue);
 BOOL ADT_Queue_Peek_From_Buffer(ADT_QUEUE *pQueue,uint8 *pData);
 
 /********************
 *   模块变量声明区  *
 ********************/
 
 /********************
 *   全局变量声明区  *
 ********************/
 
 /***********************************************************
 *   函数说明:抽象数据类型队列,系统默认队列缓冲添加函数   *
 *   输入:    要添加到缓冲区的数据                         *
 *   输出:    添加是否成功                                 *
 *   调用函数:无                                           *
 ***********************************************************/
 BOOL ADT_Queue_Add_To_Buffer(ADT_QUEUE *pQueue,uint8 cData)
 {
 uint8 *pBuffer;
 uint   nSize;
 uint   nTail;
 uint   nHead;
 uint   nCount;
 
 SAFE_CODE_PERFORMANCE                                   //原子操作
 (
 pBuffer = pQueue->pBuffer;
 nSize = pQueue->nSize;
 
 if ((pBuffer == NULL) || (!nSize))
 {
 SEI();
 return FALSE;                                   //缓冲区未分配空间
 }
 nTail = pQueue->nTail;
 nHead = pQueue->nHead;
 nCount = pQueue->nCount;
 
 
 if ((nTail == nHead) && (nCount == nSize))          //缓冲区已满
 {
 SEI();
 return FALSE;
 }
 
 pBuffer[nTail] = cData;
 nTail++;
 nCount++;
 if (nTail == nSize)
 {
 nTail = 0;
 }
 
 pQueue->nTail = nTail;
 pQueue->nCount = nCount;
 )
 
 return TRUE;
 }
 
 /***********************************************************
 *   函数说明:抽象数据类型队列,系统默认队列缓冲区读取函数 *
 *   输入:    存放读取变量的空间指针                       *
 *   输出:    队列是否为空                                 *
 *   调用函数:无                                           *
 ***********************************************************/
 BOOL ADT_Queue_Get_From_Buffer(ADT_QUEUE *pQueue,uint8 *pData)
 {
 uint8 *pBuffer;
 uint   nSize;
 uint   nTail;
 uint   nHead;
 uint   nCount;
 
 SAFE_CODE_PERFORMANCE                                   //原子操作
 (
 pBuffer = pQueue->pBuffer;
 nSize = pQueue->nSize;
 
 if ((pBuffer == NULL) || (!nSize))
 {
 SEI();
 return FALSE;                                   //缓冲区未分配空间
 }
 nTail = pQueue->nTail;
 nHead = pQueue->nHead;
 nCount = pQueue->nCount;
 
 
 if ((nTail == nHead) && (nCount == 0))              //缓冲区为空
 {
 SEI();
 return FALSE;
 }
 
 (*pData) = pBuffer[nHead++];
 
 nCount--;
 if (nHead == nSize)
 {
 nHead = 0;
 }
 
 pQueue->nHead = nHead;
 pQueue->nCount = nCount;
 )
 
 return TRUE;
 }
 
 /***********************************************************
 *   函数说明:队列判空函数                                 *
 *   输入:    队列指针                                     *
 *   输出:    队列是否为空                                 *
 *   调用函数:无                                           *
 ***********************************************************/
 BOOL ADT_Queue_Check_Empty(ADT_QUEUE *pQueue)
 {
 uint8 *pBuffer;
 
 SAFE_CODE_PERFORMANCE
 (
 pBuffer = pQueue->pBuffer;
 
 if ((pBuffer == NULL) || (!(pQueue->nSize)))
 {
 SEI();
 return TRUE;                                    //缓冲区未分配空间
 }
 
 
 if (((pQueue->nTail) == (pQueue->nHead))
 && ((pQueue->nCount) == 0))                       //缓冲区为空
 {
 SEI();
 return TRUE;
 }
 )
 
 return FALSE;
 }
 
 /***********************************************************
 *   函数说明:队列首个数据预览函数                         *
 *   输入:    存放读取变量的空间指针                       *
 *   输出:    队列是否为空                                 *
 *   调用函数:无                                           *
 ***********************************************************/
 BOOL ADT_Queue_Peek_From_Buffer(ADT_QUEUE *pQueue,uint8 *pData)
 {
 uint8 *pBuffer;
 uint   nSize;
 uint   nTail;
 uint   nHead;
 uint   nCount;
 
 SAFE_CODE_PERFORMANCE                                   //原子操作
 (
 pBuffer = pQueue->pBuffer;
 nSize = pQueue->nSize;
 
 if ((pBuffer == NULL) || (!nSize))
 {
 SEI();
 return FALSE;                                   //缓冲区未分配空间
 }
 nTail = pQueue->nTail;
 nHead = pQueue->nHead;
 nCount = pQueue->nCount;
 
 
 if ((nTail == nHead) && (nCount == 0))              //缓冲区为空
 {
 SEI();
 return FALSE;
 }
 
 (*pData) = pBuffer[nHead];
 )
 
 return TRUE;
 }
 
 
 
 核心代码:
 RD_Serial_Buffer.h
 
 ----------------------------------------------------------------
 #ifndef _USE_SERIAL_BUFFER_H_
 #define _USE_SERIAL_BUFFER_H_
 /***********************************************************
 *   声明库说明:串行通讯缓冲区函数声明库                   *
 *   版本:      v1.00                                      *
 *   作者:      王卓然                                     *
 *   创建日期:  2007年7月18日                              *
 * -------------------------------------------------------- *
 *  [支 持 库]                                              *
 *   支持库名称:RD_ADT_QUEUE.h                             *
 *   需要版本:  v1.01                                      *
 *   支持库说明:抽象数据类型(ADT)队列声明库                *
 * -------------------------------------------------------- *
 *  [版本更新]                                              *
 *   修改:                                                 *
 *   修改日期:                                             *
 *   版本:                                                 *
 * -------------------------------------------------------- *
 *  [版本历史]                                              *
 * -------------------------------------------------------- *
 *  [使用说明]                                              *
 ***********************************************************/
 
 /********************
 * 头 文 件 配 置 区 *
 ********************/
 # include "RD_ADT_QUEUE.h"
 
 /********************
 *   系 统 宏 定 义  *
 ********************/
 
 /*------------------*
 *   常 数 宏 定 义  *
 *------------------*/
 
 /*------------------*
 *   动 作 宏 定 义  *
 *------------------*/
 #ifndef SERIAL_DISABLE_WRITE
 # define SERIAL_DISABLE_WRITE ;
 #endif
 #ifndef SERIAL_ENABLE_WRITE
 # define SERIAL_ENABLE_WRITE ;
 #endif
 
 # define START_DEFINE_SERIAL_COM_BUFFER(Name,RXSize,TXSize,COM_PORT,EN_TX_Code,DIS_TX_Code)                 START_DEFINE_ADT_QUEUE(Name##_RX,RXSize)                END_DEFINE_ADT_QUEUE                START_DEFINE_ADT_QUEUE(Name##_TX,TXSize)                END_DEFINE_ADT_QUEUE                BOOL g_bSCB_##Name##TXFlag = TRUE;                BOOL PROC_SCB_##Name(void)                {                    uint8 cTransmitByte = 0;                    SAFE_CODE_PERFORMANCE                    (                        if (g_bSCB_##Name##TXFlag)                        {                            if (!ADT_GET_DATA_FROM_QUEUE                                    (                                        ADT_QUEUE(Name##_TX),                                        cTransmitByte                                    )                               )                            {                                DIS_TX_Code                                SEI();                                return TRUE;                            }                            else                            {                                EN_TX_Code                            }                            g_bSCB_##Name##TXFlag = FALSE;                            COM_PORT = cTransmitByte;                        }                    )                    return TRUE;                }
 
 # define INSERT_RX_ISR_CODE(Name,Value) ADT_ADD_DATA_TO_QUEUE                                            (                                                ADT_QUEUE(Name##_RX),                                                (Value)                                            )
 
 # define INSERT_TX_ISR_CODE(Name)   {                                        extern BOOL g_bSCB_##Name##TXFlag;                                        g_bSCB_##Name##TXFlag = TRUE;                                    }
 # define SERIAL_IN(Name,Var)    ADT_GET_DATA_FROM_QUEUE                                    (                                        ADT_QUEUE(Name##_RX),                                        Var                                    )
 
 # define SERIAL_OUT(Name,Value) ADT_ADD_DATA_TO_QUEUE                                    (                                        ADT_QUEUE(Name##_TX),                                        (Value)                                    )
 
 # define INIT_SERIAL_COM_BUFF(Name) {                                        INIT_ADT_QUEUE(Name##_TX);                                        INIT_ADT_QUEUE(Name##_RX);                                    }
 # define SERIAL_COM_BUFF_PROC(Name) PROC_SCB_##Name
 
 # define END_DEFINE_SERIAL_COM_BUFFER
 
 
 /********************
 *  用户变量类型定义 *
 ********************/
 
 /********************
 *    结构体定义区   *
 ********************/
 
 /********************
 *   函 数 引 用 区  *
 ********************/
 
 /********************
 *   全局变量引用区  *
 ********************/
 
 #endif
 
 
 
 -------------------------------------------------------------
 使用举例:定义了两个管道
 START_DEFINE_SERIAL_COM_BUFFER(InterfaceWithPC104,256,128,UDR0,;,;)
 END_DEFINE_SERIAL_COM_BUFFER
 START_DEFINE_SERIAL_COM_BUFFER(InterfaceWithRobot,64,64,UDR1,;,;)
 END_DEFINE_SERIAL_COM_BUFFER
 
 /***********************************************************
 *   函数说明:软件驱动初始化函数                           *
 *   输入:    无                                           *
 *   输出:    无                                           *
 *   调用函数:无                                           *
 ***********************************************************/
 void Driver_INIT(void)
 {
 ……
 
 INIT_SERIAL_COM_BUFF(InterfaceWithPC104)
 INIT_SERIAL_COM_BUFF(InterfaceWithRobot)
 
 ……
 }
 
 我们甚至可以这样
 extern SERIAL_COM_BUFFER(InterfaceWithPC104);
 extern SERIAL_COM_BUFFER(InterfaceWithRobot);
 
 使用的时候:
 uint8 cData = 0;
 
 if (SERIAL_IN(InterfaceWithPC104,cData))
 {
 //从一个管道转发到另外一个管道……
 SERIAL_OUT(InterfaceWithRobot,cData);
 }
 
 
 | 
 |