歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

基於狀態機編程思想的串口接收程序

狀態編程思想的理論知識可以參考之前寫的一篇文章( http://www.linuxidc.com/Linux/2013-04/83616.htm ),本文介紹一個例子--串口接收.狀態機的狀態定義如下:

typedef enum
{
 IS_NULL = 0,
 IS_START,  //已接收到起始符號,准備接收長度
 IS_LEN,   //已經接收到長度,准備接收數據
 IS_DATA,  //已經接收到長度,准備或正在接收數據
 IS_CHECK  //已經接收到數據,准備計算校驗和
}st_InState;

其他的定義如下:

/*******************************************************************************
* 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;
 }
}

 

Copyright © Linux教程網 All Rights Reserved