Modbus通信时数据接收和发布的处理

在项目中遇到MCU(stm32)与上位机工具通过modbus传输数据,MCU中数据是小端存储,modbus数据默认是大端存储。所以在modbus通信时需要处理大小端对齐的问题。

1. MCU发送uint16数据的处理

/*Data是MCU需要发送的数据(小端存储),经过转化后发送给modbus*/

tPrjUInt16 Byte_exchange(tPrjUInt16 Data)
{
    tPrjUInt8 Temp_data;
    Temp_data= (tPrjUInt8)(Data>>8);
    Data = (Data<<8)|Temp_data;
    return(Data);
}

2.MCU发送float(32bit)数据的处理

modbus 一个保持寄存器是16bit,接收一个浮点数需要2个寄存器来存储。低地址的寄存器保存float数据的低16位,高地址寄存器保存float的高16bit。

方法一: 

tPrjFloat32 Float_byte_exchange(tPrjFloat32 Data)
{     
    tPrjFloat32 bigEndianValue;
    volatile char *littleEndianBytes = ( char *)&Data;
    char *bigEndianBytes = ( char *)&bigEndianValue;
    
    bigEndianBytes[0] = *(littleEndianBytes+1);
    bigEndianBytes[1] = *(littleEndianBytes);
    bigEndianBytes[2] = *(littleEndianBytes+3);
    bigEndianBytes[3] = *(littleEndianBytes+2);
    
    return bigEndianValue;
}

方法二:

先定义一个联合体:

/*联合体中数据公用同一段内存地址*/

/*浮点数与IEEE754格式转换*/
typedef union                                        
{
   float ul_Temp;
   u8  uc_Buf[4];//小数转换成IEEE754格式的数组
   u16 us_Buf[2];//用于modbus协议小数转换的数组
}un_DtformConver; 

tPrjFloat32 Float_byte_exchange(tPrjFloat32 Data)
{     
    un_DtformConver unData;
    unData.ul_Temp = Data;
    tPrjFloat32 bigEndianValue;


    unsigned char str[4] = {0};
    str[0] = unData.uc_Buf[1];
    str[1] = unData.uc_Buf[0];
    str[2] = unData.uc_Buf[3];
    str[3] = unData.uc_Buf[2];

    bigEndianValue = *((float *)str);
    return bigEndianValue;

}

或者用两个16bit的寄存器直接存放数据:

unit16 regBuf[num] ;//保持寄存器

void Float_To_U32(float value, u16 regaddr)
{
    un_DtformConver Data;
    Data.ul_Temp = value;//获取小数值
    regBuf[regaddr] = Data.us_Buf[0];//获取低16位
    regBuf[regaddr+1] = Data.us_Buf[1];//获取高16位
}

void Float_To_U32(float value, u16 regaddr)
{
    un_DtformConver Data;
    u16 us_temp = 0;
    Data.ul_Temp = value;//获取小数值
    regBuf[regaddr] = Data.uc_Buf[0]; //获取最低8位
    us_temp = Data.uc_Buf[1];//获取8~15位
    regBuf[regaddr] |= us_temp <<8;//低16位保存到保持寄存器中
    
    regBuf[regaddr+1] = Data.uc_Buf[2];//获取16~23位
    us_temp = Data.uc_Buf[3];//获取24~31位
    regBuf[regaddr+1] |= us_temp <<8;//高16位保存到保持寄存器中
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单片机modbus通信数据处理函数是处理modbus通信协议的函数。单片机的modbus通信数据处理函数主要用于解析和处理从其他设备处接收到的modbus通信数据。 首先,单片机modbus通信数据处理函数需要接收从其他设备发送过来的modbus通信数据,包括从站地址、功能码、寄存器地址以及相关数据等。可以通过串口、I2C等通信方式接收数据。 然后,根据接收到的功能码进行相应的处理。主要包括读取寄存器值、写入寄存器值、读取线圈状态、写入线圈状态等操作。需要根据modbus通信协议规定的格式和规则进行解析和处理。 在读取寄存器值的操作中,单片机modbus通信数据处理函数需要根据寄存器地址和寄存器数量,从单片机的存储器中读取对应的数据值,并将其发送回给主设备。 在写入寄存器值的操作中,单片机modbus通信数据处理函数需要将接收到的数据值写入到单片机的对应寄存器地址中,并返回写入成功的状态给主设备。 在读取线圈状态和写入线圈状态的操作中,单片机modbus通信数据处理函数需要根据线圈地址和线圈数量,读取或者写入对应的线圈状态,并将结果返回给主设备。 需要注意的是,在处理modbus通信数据,单片机modbus通信数据处理函数需要进行错误处理和异常情况的处理,如地址错误、功能码错误、数据长度错误等。同,还需要进行数据校验,如CRC校验等,以确保通信的准确性和可靠性。 总之,单片机modbus通信数据处理函数起着非常重要的作用,它能够完成modbus通信协议的解析和处理,实现单片机与其他设备之间的数据通信

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值