104转发modbus

/************************************************************************                                             
  规约解析函数                                                                
  void rule_parser(ST_UCHAR *buf, ST_INT len);                    
                                                     
  挑帧函数                                                    
  输入参数: c收到的字符,pbuf 已接收的buf index 当前接收到的位置
  输出参数: framelen  根据报文解析出来的长度                
  ST_BOOLEAN sio_handle_rule(ST_UCHAR c, ST_UCHAR* pbuf,     
           ST_UINT index, ST_UINT* framelen);                                 
                                                             
  下发数据调用的函数                                                              
  void ChkLoopTime();                                                                           
                                                         
  收到消息,譬如遥控,设定等                                                    
  void downMsg(DBMSG*);                                                               
************************************************************************/

#include "dblib2.h"
#include "glbfun_s.h"
int  fun;
ST_BOOLEAN sio_handle_rule(ST_UCHAR c, ST_UCHAR* pbuf,                 
          ST_UINT index, ST_UINT* framelen)//读取有用报文
{
    ST_INT devaddr= -1;
    //ST_UINT16 crc1, crc2;
    if(index == 6)    //如果还没有检测到侦头  装置地址
    {
        devaddr = c;      //从机地址
        // 判断装置地址是否在列表中
        //PutInfo("devaddr = %d", devaddr);
        if (SD_FALSE == ChkDevAddr(devaddr))
            return SD_FALSE;
        return SD_TRUE;
    }
    else if (index == 5)
    {
        if (c == 6)
            *framelen = c+6;
        else   //其他功能码暂不支持
            return SD_FALSE;
        return SD_TRUE;    
        //PutInfo("c = %d len = %d", c, *framelen);
    }
    
    return SD_TRUE;
}

/************************************************************************
  规约解析函数                                                   
************************************************************************/
ST_VOID rule_parser(ST_ULONG assoc_ID,ST_UCHAR *buf, ST_INT len)
{
    ST_INT devaddr =-1, i,j,dpi,point,startaddr,inum,framenum,index=0,ykval;
    ST_INT funccode = -1, errCode, ym_value;
     ST_INT16 sval;
     ST_UINT16 crc;

    devaddr = buf[6];
    funccode = buf[7];
    startaddr = buf[8]*256 + buf[9];
    inum = buf[10]*256 + buf[11];    
    
    point = startaddr;
    switch(funccode)    //按不同的功能码解析报文
    {
    case 2:  // 按位遥信
         framenum = inum / 8;   //遥信8个一个字节
         if ((inum%8) !=0)      //剩余还需要一个自己
             framenum++;
         buf[8] = framenum;
         buf[5] = framenum+3;
         memset(&buf[9],0,3);
         for (i=0;i<framenum;i++)
         {
             for (j=0;j<8;j++)
             {
                 GetYx(devaddr,point,&dpi);
                 point++;  //转发地址
                 buf[9+i] |= (dpi << j);
                 index++;
                 if (index>= inum)
                     break;
             }
         }
         SendBufToCom(assoc_ID,buf, 8+framenum+1);
          break;
    case 3:                         // 遥测、遥脉
         //framenum = inum*2;
         //buf[2] = framenum;
         //memset(&buf[3],0,5);
         //index = 3;
         if(point>=0x00) //遥脉
         {
                 framenum = inum*2;
                 buf[8] = framenum;
                buf[5] = framenum +3;
                 memset(&buf[9],0,framenum);
                 index = 9;
                 
            for (i=0;i<inum/2;i++)
            {
                   GetYm(devaddr,point,&ym_value);
               buf[index++] = ((ym_value >>24) &0xff);
               buf[index++] = ((ym_value >>16) &0xff);
               buf[index++] = ((ym_value >>8) &0xff);
               buf[index++] = (ym_value & 0xff);
               point++;  
               point++; //转发地址
            }
         }
         else    //遥测
         {
                 framenum = inum*2;
                 buf[8] = framenum;
                buf[5] = framenum+3;
                 memset(&buf[9],0,framenum);
                 index = 9;
                 
            for (i=0;i<inum;i++)
            {
                GetYc(devaddr,point,&sval);
                buf[index++] = ((sval >>8) &0xff);
                buf[index++] = (sval & 0xff);
                point++;  //转发地址
            }
         }
         
         SendBufToCom(assoc_ID,buf, index);
        break;
    case 5:
        ykval = inum;   //遥控参数
        if (ykval == 0)   //分
        {
            SetYk(assoc_ID,devaddr, point, 1);
        }
        else
        {
            SetYk(assoc_ID,devaddr, point, 2);
        }
        break;
    }
    if (funccode & 0x80)
    {
        errCode = buf[2];
        //差错处理
        PutInfo("非法功能码,错误原因%d", errCode);
    }
}


/************************************************************************
收到消息,譬如遥控,设定等
************************************************************************/
void downMsgAck(ST_ULONG assoc_ID,ST_UINT devaddr, ST_INT point, ST_UCHAR ucval,ST_UCHAR ucret)
{
    ST_UCHAR sendbuf[100]={0};
    ST_INT index=0;
    ST_UINT16 usval;
     ST_UINT16 crc;    
    sendbuf[index++] = devaddr;
    sendbuf[index++] = 5;
    if (ucval==2)
        usval=0xff00;
    else
        usval=0x0000;
    
    if (ucret)
    {
         sendbuf[index++] = ((point >>8) &0xff);
         sendbuf[index++] = (point &0xff);    
         sendbuf[index++] = ((usval >>8) &0xff);
         sendbuf[index++] = (usval &0xff);     
    }
    else
        sendbuf[index++] = 1; 
    crc =cau_crc16(&sendbuf[0], index);
    sendbuf[index++] = crc & 0x00FF;
    sendbuf[index++] = (crc>>8) & 0x00FF;
    SendBufToCom(assoc_ID,sendbuf, index);
  
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值