当前位置:编程学习 > 网站相关 >>

基于状态机编程思想的串口接收程序

[plain]
typedef enum 

    IS_NULL = 0, 
    IS_START,       //已接收到起始符号,准备接收长度 
    IS_LEN,         //已经接收到长度,准备接收数据 
    IS_DATA,        //已经接收到长度,准备或正在接收数据 
    IS_CHECK        //已经接收到数据,准备计算校验和 
}st_InState; 

typedef enum
{
 IS_NULL = 0,
 IS_START,  //已接收到起始符号,准备接收长度
 IS_LEN,   //已经接收到长度,准备接收数据
 IS_DATA,  //已经接收到长度,准备或正在接收数据
 IS_CHECK  //已经接收到数据,准备计算校验和
}st_InState;其他的定义如下:


[plain]
#define CHAR_STX 0xAA 
#define INFRAME_MAXLEN 40 
 
typedef struct tagINPARSE 

    u8  uInState;                   //接收状态,初始化为IS_NULL 
    u16 tInState;                   //接收状态计时 
    u8 uTotal;                      //需要接收数据的总长度 
    u8 uLen;                        //实际已经接收到的长度 
    u8  uframe_a[INFRAME_MAXLEN];   //接收到的数据帧  
    void* vpUserData; 
}t_INPARSE; 

#define CHAR_STX 0xAA
#define INFRAME_MAXLEN 40

typedef struct tagINPARSE
{
 u8 uInState;     //接收状态,初始化为IS_NULL
 u16 tInState;     //接收状态计时
 u8 uTotal;      //需要接收数据的总长度
 u8 uLen;      //实际已经接收到的长度
 u8 uframe_a[INFRAME_MAXLEN]; //接收到的数据帧
 void* vpUserData;
}t_INPARSE;接下来是程序的主要部分,也就是状态的转换过程.


[plain]
******************************************************************************* 
* Function Name  : FinishInScan 
* Description    : Finish Receive char 
* Input          : The pointer of t_INPARSE 
* Output         : None 
* Return         : None 
*******************************************************************************/ 
void FinishInScan(t_INPARSE *pPtc) 

    pPtc->uInState = IS_NULL; 
    pPtc->uTotal = 0; 
    pPtc->tInState = 0; 

 
/******************************************************************************* 
* Function Name  : InChecksum 
* Description    : Calculate the checksum 
* Input          : The pointer of t_INPARSE 
* Output         : None 
* Return         : The checksum 
*******************************************************************************/ 
u8 InChecksum(t_INPARSE *pPtc) 

    u8 uCheck; 
    u16 i; 
    u8* ptr; 
 
    //uCheck = CHAR_STX ^ HIBYTE(pPtc->uTotal) ^ LOBYTE(pPtc->uTotal); 
    uCheck = CHAR_STX ^ pPtc->uTotal; 
    ptr = (u8*)(pPtc->uframe_a); 
    for (i = pPtc->uTotal; i ; --i,++ptr) 
        uCheck ^= *ptr; 
 
    return uCheck; 

 
/******************************************************************************* 
* Function Name  : OnRevChar 
* Description    : Protocol analysis of the character stream 
* Input          : The pointer of t_INPARSE, Character data from COMx, User data 
* Output         : None 
* Return         : Ptc_R_ 
*******************************************************************************/ 
u8 OnRevChar(t_INPARSE *pPtc,u8 ch,void *vpUserData) 

    switch (pPtc->uInState) 
    { 
    case IS_NULL: 
        if (ch == 0xaa) 
        { 
            pPtc->uInState = IS_START; 
            //pPtc->tInState = 
            return Ptc_R_CONTINUE; 
        } 
        else 
        { 
            printf("Hand error,0x%x\n",ch); 
            return Ptc_R_FALSE; 
        } 
 
    case IS_START:  //已经接收到起始字符,准备接收长度 
        if ((ch <=INFRAME_MAXLEN) && (ch >= 1) ) 
        { 
            pPtc->uTotal = ch; 
            pPtc->uLen = 0; 
            pPtc->uInState = IS_DATA; 
            return Ptc_R_CONTINUE; 
        } 
        else 
        { 
            printf("Hand error,0x%x\n",ch); 
            return Ptc_R_FALSE; 
        } 
    case IS_DATA: 
        pPtc->uframe_a[pPtc->uLen++] = ch; 
        if (pPtc->uLen == pPtc->uTotal) 
        { 
            pPtc->uframe_a[pPtc->uLen] = 0;//添加一个串结束符 
            pPtc->uInS

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,