既然大家都是高手,我就不多罗嗦了,直接以码会友…… 任意数量的串行通讯管道
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); }
|
|