识别电力645协议的一段小程序

 

int read_Packet(unsigned char* PacketBuf,const unsigned char* MeterID, const unsigned char* DataID)
{
   int return_stat=0;   // Function return status.
   enum state_table
{
     SEARCH_START,    //search 0x68 of frame head
      SEARCH_METERID, //search meterID {
      PACKET_HEAD,   //search 0x68 of data head
      CTRL_CODE,    //search control code
       DATA_LEN,        //receive data length
       DATA_ID,         //receive dataID
       DATA_CONTENT,    //receive datacontent
       CHECK_SUM,       //receive checksum
       MACHINE_END,     //end receiving
       RECV_ERR,      //error received from meter.
      MACHINE_EXIT   //done.
};

   state_table state;
   int Data_Len=0;

   state = SEARCH_START;      
   // Loop until machine exit.
   do     
{
      switch (state)
      {
          case SEARCH_START:
            return_stat = Read_N_Byte(g_nSfd,PacketBuf,1);
           if (return_stat <= 0)
           {
               return_stat=DLT_READ_ERR;
               state=RECV_ERR;
          }
           else
           {
          if (PacketBuf[0] == STX)
                 state = SEARCH_METERID;
             else
              state = SEARCH_START;
        }
         break;
  
          case SEARCH_METERID:
         return_stat = Read_N_Byte(g_nSfd,PacketBuf+1,6);
         if (return_stat <= 0)
           {
               return_stat=DLT_READ_ERR;
               state=RECV_ERR;
        }
       else
         {
          if(strncmp((const char*)(PacketBuf+1),(const char *)MeterID,6)==0)
                 state=PACKET_HEAD;
               else
               {
                  return_stat=BAD_METERID;
                  state=RECV_ERR;
               }
           }
          break;
  
           case   PACKET_HEAD:   
             return_stat =Read_N_Byte(g_nSfd,PacketBuf+7,1);
             if (return_stat <=0)
           {
             return_stat=DLT_READ_ERR;
            state = RECV_ERR;
          }
           else    
           {
               if(*(PacketBuf+7)==STX)
                state=CTRL_CODE;
               else
               {
                  return_stat=BAD_PACKETHEAD;
                  state=RECV_ERR;
               }
          }
           break;

         case CTRL_CODE :
            return_stat =Read_N_Byte(g_nSfd,PacketBuf+8,1);
            if (return_stat <=0)
           {
             return_stat=DLT_READ_ERR;
            state = RECV_ERR;
          }
             else
             {
              if(*(PacketBuf+8)==Normal)
                  state=DATA_LEN;
               else
               {
                  return_stat=BAD_CTRLCODE;
                  state=RECV_ERR;
               }
             }
         break;

          case DATA_LEN:
            return_stat =Read_N_Byte(g_nSfd,PacketBuf+9,1);
            if(return_stat<=0)
            {
              return_stat=DLT_READ_ERR;
           state = RECV_ERR;
            }
            else
            {
              if(*(PacketBuf+9)>=2)
              {
                 state=DATA_ID;
                 Data_Len=*(PacketBuf+9)-2;
              }
              else
              {
                 return_stat=BAD_DATALEN;
                 state=RECV_ERR;
              }
            }
          break;

          case DATA_ID:
             return_stat =Read_N_Byte(g_nSfd,PacketBuf+10,2);
             if(return_stat<=0)
             {
               return_stat=DLT_READ_ERR;
            state = RECV_ERR;
             }
             else
             {
                if(strncmp((const char*)(PacketBuf+10),(const char*)DataID,2)==0)
                   state=DATA_CONTENT;
                else
                {
                   return_stat=BAD_DATAID;
                   state=RECV_ERR;
                }
              }
          break;

          case DATA_CONTENT:
             return_stat =Read_N_Byte(g_nSfd,PacketBuf+12,Data_Len);
             if(return_stat<=0)
             {
               return_stat=DLT_READ_ERR;
            state = RECV_ERR;
             }
             else state=CHECK_SUM;
          break;

          case CHECK_SUM:
            return_stat =Read_N_Byte(g_nSfd,PacketBuf+12+Data_Len,1);
            if(return_stat<=0)
             {
               return_stat=DLT_READ_ERR;
            state = RECV_ERR;
             }
             else
             {
               if(*(PacketBuf+12+Data_Len)==Cal_BCCSum(PacketBuf,12+Data_Len))
                  state = MACHINE_END;
               else
               {
                 return_stat=BAD_CHECKSUM;
                 state = RECV_ERR;
               }
             }
          break;

          case MACHINE_END:
             return_stat =Read_N_Byte(g_nSfd,PacketBuf+13+Data_Len,1);
             if(return_stat<=0)
             {
               return_stat=DLT_READ_ERR;
            state = RECV_ERR;
             }
             else
             {
               if(*(PacketBuf+13+Data_Len)==ETX)
               {
                 return_stat=READ_SUCC;
                 state=MACHINE_EXIT;
               }
               else
               {
                 return_stat=BAD_ENDCODE;
                 state = RECV_ERR;
               }
             }
          break;

         case RECV_ERR :
          // added   at Apr 25,2002;
           memset(PacketBuf,0x00,FRAME_REC_LEN_MAX);
          // add end ;
         state = MACHINE_EXIT;
        break;

          case MACHINE_EXIT:
      default:break;

      }   // End of switch (state)
} while (state != MACHINE_EXIT);
return (return_stat);
}

int set_baud(int fd,speed_t baud)
{
struct termios oldtio;

tcgetattr(fd,&oldtio);
cfsetispeed(&oldtio,baud);
cfsetospeed(&oldtio,baud);
//added by johnny at Feb 24,2004;
//frame delay 500ms,unit 100 ms;
oldtio.c_cc[VTIME] = 5;
//add end

return(tcsetattr(fd,TCSANOW,&oldtio));
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DLT645协议解析器及modbus CRC和DLT CS校验码计算,支持两种输入格式,带空格和不带空格。默认需要安装微软VS2012发布包。 比如输入FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16,解析出结果如下: [11-05 08:39:58:676] 输入数据: FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16 [11-05 08:39:58:681] 类型=上1结算日C相反向有功电能 [11-05 08:39:58:685] 类型值=76 [11-05 08:39:58:689] 获取结果= 0.00 另外可按键获取如下CRC [11-05 08:39:58:697] *********************************************** [11-05 08:40:08:268] 输入数据:FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16 [11-05 08:40:08:276] DLT645 CRC=0xCC [11-05 08:40:08:283] *********************************************** [11-05 08:40:10:813] 输入数据:FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16 [11-05 08:40:10:821] CRC(Modbus)=0x6FE5 [HIGH LOW]=[6F E5] [11-05 09:05:30:239] 输入数据: 68 30 65 00 00 00 00 68 11 04 33 33 33 33 46 16 [11-05 09:05:30:247] 类型=当前组合有功总电能 [11-05 09:05:30:254] 类型值=1 [11-05 09:05:30:264] 获取结果= 0.00 [11-05 09:06:25:098] 输入数据: 68 29 65 00 00 00 00 68 91 08 35 36 36 33 C9 CC 36 33 C9 16 [11-05 09:06:25:112] 类型=上2结算日组合无功1费率3电能 [11-05 09:06:25:127] 类型值=11 [11-05 09:06:25:142] 获取结果=399.96 [11-05 09:33:10:453] 输入数据: FE FE FE FE 68 29 65 00 00 00 00 68 11 04 35 35 34 33 44 16 [11-05 09:33:10:460] 类型=上2结算日正向有功费率2电能 [11-05 09:33:10:467] 类型值=5 [11-05 09:33:10:476] 获取结果= 0.00 [11-05 09:33:10:484] *********************************************** [11-05 09:33:32:065] 输入数据: FEFEFEFE68296500000000681104353534334416 [11-05 09:33:32:074] 类型=上2结算日正向有功费率2电能 [11-05 09:33:32:086] 类型值=5 [11-05 09:33:32:097] 获取结果= 0.00

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值