郴州卖房网站/口碑营销的步骤
基于状态机编程思想的串口接收程序
状态编程思想的理论知识可以参考之前写的一篇博客(http://blog.csdn.net/ce123/article/details/8222673),本文介绍一个例子--串口接收.状态机的状态定义如下:
typedef enum
{IS_NULL = 0,IS_START, //已接收到起始符号,准备接收长度IS_LEN, //已经接收到长度,准备接收数据IS_DATA, //已经接收到长度,准备或正在接收数据IS_CHECK //已经接收到数据,准备计算校验和
}st_InState;
其他的定义如下:
#define CHAR_STX 0xAA
#define INFRAME_MAXLEN 40typedef struct tagINPARSE
{u8 uInState; //接收状态,初始化为IS_NULLu16 tInState; //接收状态计时u8 uTotal; //需要接收数据的总长度u8 uLen; //实际已经接收到的长度u8 uframe_a[INFRAME_MAXLEN]; //接收到的数据帧 void* vpUserData;
}t_INPARSE;
接下来是程序的主要部分,也就是状态的转换过程.
/*******************************************************************************
* 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->uInState = IS_CHECK;}return Ptc_R_CONTINUE;default:u8 uCheck = InChecksum(pPtc);if (uCheck == ch){return Ptc_R_FRAME;}else{printf("Handset Frame CheckReeor.Rev = 0x%x,Calc = 0x%x\n",ch,uCheck);return Ptc_R_FALSE;}break;}
}/*******************************************************************************
* Function Name : Rev_PutChar
* Description : Character process
* Input : The pointer of t_INPARSE, Character data from COMx, User data
* Output : None
* Return : Ptc_R_
*******************************************************************************/
u8 Rev_PutChar(t_INPARSE *pPtc,u8 ch,void *vpUserData)
{u8 rtn = OnRevChar(pPtc,ch,vpUserData);if (rtn == Ptc_R_CONTINUE){return Ptc_R_FALSE;}else if (rtn == Ptc_R_FALSE){FinishInScan(pPtc);return rtn;}else{FinishInScan(pPtc);return Ptc_R_FRAME;}
}