首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

51通讯协议—CRC16校验(3)

51通讯协议—CRC16校验(3)

/****************************************************
** 函数名称: UartIRQ
** 输    入: 无
** 输    出: 无
** 功能描述: 串口中断服务程序
*****************************************************/
void UartIRQ(void)interrupt 4
{
     static UINT8  uccnt=0;
         UINT8  uclen;
   UINT16 uscrc;   
     if(RI) //是否接收到数据
     {
        RI=0;
        PktCrcEx.p[uccnt++]=SBUF;//获取单个字节
        if(PktCrcEx.r.m_ucHead1 == DCMD_CTRL_HEAD1)//是否有效的数据帧头部1
        {
           if(uccnt<CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength+CRC16_LEN)//是否接收完所有数据
           {
              if(uccnt>=2 && PktCrcEx.r.m_ucHead2!=DCMD_CTRL_HEAD2)//是否有效的数据帧头部2
              {
                 uccnt=0;
                 return;
              }                  
           }
           else
           {      
        uclen=CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength;//获取数据帧有效长度(不包括校验值)
     uscrc=CRC16Check(PktCrcEx.p,uclen);//计算校验值
          //这样做的原因是因为有时写数据长度不一样,导致PktCrcEx.r.m_szCrc会出现为0的情况,所以使用BufCpy将校验值复制到相应的位置
     BufCpy(PktCrcEx.r.m_szCrc,&PktCrcEx.p[uclen],CRC16_LEN);
     if((UINT8)(uscrc>>8) !=PktCrcEx.r.m_szCrc[1]\
      ||(UINT8) uscrc     !=PktCrcEx.r.m_szCrc[0])//校验值是否匹配
     {
         uccnt=0;
         return;
     }
              switch(PktCrcEx.r.m_ucOptCode)//从命令码中获取相对应的操作
              {
                case DCMD_CTRL_BELL://控制蜂鸣器命令码
                {
      if(DCTRL_BELL_ON==PktCrcEx.r.m_szDataBuf[0])//数据部分含控制码
      {
         bBellOn=TRUE;
      }
      else
      {
         bBellOn=FALSE;
      }
                }
                break;
                case DCMD_CTRL_LED://控制LED命令码
                {
      if(DCTRL_LED_ON==PktCrcEx.r.m_szDataBuf[0])//数据部分含控制码
      {
         bLedOn=TRUE;
      }
      else
      {
         bLedOn=FALSE;
      }
                }
                break;
                case DCMD_REQ_DATA://请求数据命令码
                {
                     bReqData=TRUE;
                }
                break;
              }
              uccnt=0;
              return;
           }
        }
        else
        {
            uccnt=0;
        }
     }
}
/****************************************************
** 函数名称: main
** 输    入: 无
** 输    出: 无
** 功能描述: 函数主题
*****************************************************/
void main(void)
{
     UINT8 i=0;
  UINT16 uscrc=0;
  UartInit();//串口初始化
  EA=1;      //开总中断
     while(1)
     {
          if(bLedOn)  //是否点亮Led
    {
       LED(ON);
    }
    else
    {
       LED(OFF);
    }   
    if(bBellOn)//是否响蜂鸣器
    {
       BELL(ON);
    }
    else
    {
       BELL(OFF);
    }   
    if(bReqData)//是否请求数据
    {
       bReqData=FALSE;
    NOT_EN_UART(); //禁止串口中断   
    PktCrcEx.r.m_ucHead1=UCMD_CTRL_HEAD1;//MCU上传数据帧头部1
    PktCrcEx.r.m_ucHead2=UCMD_CTRL_HEAD2;//MCU上传数据帧头部2
    PktCrcEx.r.m_ucOptCode=UCMD_REQ_DATA;//MCU上传数据帧命令码   
    uscrc=CRC16Check(PktCrcEx.p,CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength);//计算校验值
             PktCrcEx.r.m_szCrc[0]=(UINT8) uscrc;    //校验值低字节
             PktCrcEx.r.m_szCrc[1]=(UINT8)(uscrc>>8);//校验值高字节
          //这样做的原因是因为有时写数据长度不一样,导致PktCrcEx.r.m_szCrc会出现为0的情况,所以使用BufCpy将校验值复制到相应的位置
    BufCpy(&PktCrcEx.p[CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength],PktCrcEx.r.m_szCrc,CRC16_LEN);   
    UartSendNBytes(PktCrcEx.p,CTRL_FRAME_LEN+PktCrcEx.r.m_ucDataLength+CRC16_LEN);//发送数据
    EN_UART();//允许串口中断      
    }
     }
}
继承事业,薪火相传
返回列表