打印
[AVR单片机]

借hotpower手动触发串口的东风……偶继续接龙

[复制链接]
2455|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
坏孩子|  楼主 | 2007-9-13 01:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
既然大家都是高手,我就不多罗嗦了,直接以码会友……
任意数量的串行通讯管道

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);
}

相关帖子

沙发
坏孩子|  楼主 | 2007-9-13 01:17 | 只看该作者

我就编辑了一下帖子,为什么宏的缩进变得如此惨不忍睹…

我就编辑了一下帖子,为什么宏的缩进变得如此惨不忍睹……
貌似所有的“”都不见了……

使用特权

评论回复
板凳
yewuyi| | 2007-9-13 09:12 | 只看该作者

哈哈,TAB不如SPACE好用了把……

使用特权

评论回复
地板
坏孩子|  楼主 | 2007-9-13 10:52 | 只看该作者

我从来不用Tab

我可没有用Tab,我一直都使用space啊……

使用特权

评论回复
5
OneMillion| | 2007-9-13 22:12 | 只看该作者

一看程序的编辑风格就有高手之风。。。顶!

  下午在这看到 农讲所长 SHOW的代码以为仅仅是SHOW而已,
 没想到串口还可以这样用的,鄙人真是震惊自己的落伍!!!!!

使用特权

评论回复
6
hotpower| | 2010-7-27 19:31 | 只看该作者
怀旧一番~~~赠与裤子

使用特权

评论回复
7
123jj| | 2010-7-27 19:42 | 只看该作者
傻孩子写的,的确不错!

使用特权

评论回复
8
xuyiyi| | 2010-7-28 13:37 | 只看该作者
写的不错!
顶!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

10

帖子

1

粉丝