用485总线,modbus协议通讯,移植完了不会用,网上看的程序也糊里糊涂的

2019-07-14 20:31发布

大家好,本人用的板子是STM32vet6,用到modbus通讯,但是初次接触modbus,modbus的文档也看了不少,但是程序里不知道怎么写来实现modbus的强大功能,目前我想先用modbus先实现接受和发送数据,但是不知道代码是怎样的,求大家能指导一下,或者大家有做过modbus这一块的,希望可以分享一下经验或者资料,感激不尽,帮助小白我,谢谢谢谢
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
17条回答
jianfeii
1楼-- · 2019-07-16 11:15
曾小z 发表于 2016-8-16 21:17
我从网上下了好多modbus的代码,有些有crc校验,有些没有,有点无助了,代码都不一样,函数是自己定义的,还是modbus协议里自带的呢,本来想用来传输ds18B20的温度的,但是测试代码都不会啊大哥

你也想太多了,modbus只是一个协议,所有的代码实现都要你自己写的,哪里有什么协议自带,你要根据协议写代码!
meimengxing2014
2楼-- · 2019-07-16 15:31
static void MBRTU_Fun10(uint8_t *RcvDataBuf)
{
    uint8_t  k;
    uint16_t ReadAdr;
    uint16_t Register_Num;                                                      //接收到数据第1个字节为从机地址,第2个字节为功能码0x10
    ReadAdr = (uint16_t)RcvDataBuf[2] * 256 + RcvDataBuf[3];                    // 接收到数据的3、4两个字节存放的起始地址      
    Register_Num = (uint16_t)RcvDataBuf[4] * 256 + RcvDataBuf[5];               //5、6两个字节存放的是寄存器数量
    uint32_t index = 0;
   
    if (!(((ReadAdr >= MUL_REG_REGION1_BGEIN) && (ReadAdr <= MUL_REG_REGION1_END))
            && ((ReadAdr + Register_Num) <= (MUL_REG_REGION1_END + 1))
            && ((0 != Register_Num) && (Register_Num * 2 == RcvDataBuf[6]))))   //第7个字节存放的字节计数=寄存器数量*2
    {
        MBRTU_SendErr(RcvDataBuf, MB_EX_ILLEGAL_DATA_ADDRESS);
        return;
    }
    for (k = 0; k < Register_Num; ReadAdr++, k++)
    {
        switch (ReadAdr)                                                       //第8、9两个字节存放的是寄存器值
        {
        case 0x0030:                                                                //PWM频率
            PWMPara.PWM_Frequency = (uint16_t)RcvDataBuf[7+index] * 256 + RcvDataBuf[8+index];
            index += 2;
            break;
            
        case 0x0031:                                                                //PWM占空比
            PWMPara.Duty = (uint16_t)RcvDataBuf[7+index] * 256 + RcvDataBuf[8+index];
            index += 2;
            break;
            
        case 0x0032:                                                                //PWM的脉冲个数
            PWMPara.PulseCount = (uint16_t)RcvDataBuf[7+index] * 256 + RcvDataBuf[8+index];
            index += 2;
            break;
            
        default:
            break;
        }
    }
    MBRTU_SendMsg(RcvDataBuf, 6);
}
meimengxing2014
3楼-- · 2019-07-16 19:07
/***********************************************************
函数名称:MBRTU_Fun03
函数功能: ModBus功能03协议(读多个寄存器)
输    入:RcvDataBuf            接收数据的指针
输    出:无      
返    回:无
*************************************************************/
static void MBRTU_Fun03(uint8_t *RcvDataBuf)                                           
{
    uint8_t SendBuf[64];                                                        //存储从机响应消息帧
    uint8_t SendLen = 0;
    uint8_t i,k;
    uint32_t Data_Buf;
    uint16_t ReadAdr = (uint16_t)RcvDataBuf[2] * 256 + RcvDataBuf[3];
    uint16_t Register_Num = (uint16_t)RcvDataBuf[4] * 256 + RcvDataBuf[5];
   
    SendBuf[SendLen++] = (MBRTU_GetSlaveAddr(RcvDataBuf)) ? ComAddr : 0x00;
    SendBuf[SendLen++] = MB_FUNC_READ_HOLDING_REGISTER;                                //功能码
    SendBuf[SendLen++] = Register_Num * 2;                                        //数据长度                  

    if (!(((ReadAdr >= HOLDING_REG_REGION1_BGEIN) && (ReadAdr <= HOLDING_REG_REGION1_END)
            && (ReadAdr + Register_Num <= (HOLDING_REG_REGION1_END + 1))) && (0 != Register_Num)))
    {
        MBRTU_SendErr(RcvDataBuf, MB_EX_ILLEGAL_DATA_ADDRESS);
        return;
    }

    for (k = 0; k < Register_Num; ReadAdr++, k++)
    {
        switch (ReadAdr)
        {
            case 0x0030:
                Data_Buf = PWMPara.PWM_Frequency;                                //PWM频率
                break;

            case 0x0031:
                Data_Buf = PWMPara.Duty;                                        //PWM占空比
                break;

            case 0x0032:
                Data_Buf = PWMPara.PulseCount;                                        //PWM脉冲个数
                break;
               
            default:
                Data_Buf = 0;
                break;
        }

        for (i = 2; i > 0; i--)
        {
            SendBuf[SendLen++] = (uint8_t)(Data_Buf >> ((i - 1) * 8));          //把数据分成两个字节
        }
    }
    MBRTU_SendMsg(SendBuf, SendLen);
}
meimengxing2014
4楼-- · 2019-07-16 23:24
上面是0x10和0x03以及和上位机通讯的函数,你先看看,肯定比你那个清楚,其他比方CRC校验、发送错误码等函数自己补充下就好
meimengxing2014
5楼-- · 2019-07-17 03:36
 精彩回答 2  元偷偷看……

一周热门 更多>