小坤 发表于 2024-10-28 13:51:34

Modbus 从机读写 赚点积分 勿喷

赚点积分 勿喷{:5_313:}
/******************************************************************/
/*** 函数名称:voidReadReg(void)                                       *******/
/*** 函数说明:读读寄存器                                                             *******/
/*** 参数:none                                                                             *******/
/*** 编写: 小坤                                                               *******/
/*** 备注:2024-2-23   V1.0                                                   *******/
/******************************************************************/
voidReadReg(void)
{
        Buff_u16_u8 Buff1={0};       
        INT8U buff_n;       
        INT16U i=0;
        INT8U n=0;
       
        Modbus.Reg_Len = Modbus.buff*256+Modbus.buff;                                //寄存器长度       
       
        if((Modbus.Reg_Len<1)||(Modbus.Reg_Len>125))        return;                                //寄存器个数范围   1<=寄存器数量<=125       
        if(Modbus.Reg_addr+Modbus.Reg_Len >Reg_len)   return;                  //起始地址+寄存器长度<=总寄存器数量
               
        buff_n = GSPCCommControlComponent.address;                                                        //地址
        buff_n = Modbus.CMD;                                                        //功能码
        buff_n = Modbus.Reg_Len*2;                                         //数据长度       
        for(i=Modbus.Reg_addr; i<(Modbus.Reg_addr+Modbus.Reg_Len); i++ )                       
        {
                //Buff1.Dat = Modbus.Read_Reg;
                Buff1.Dat = Get_Read_Data(i);               
                buff_n = Buff1.Byte;
                buff_n = Buff1.Byte;                                        //数据       
        }
        Modbus.CRC_data = crc16( buff_n, n);       
        buff_n = Modbus.CRC_data>>8;
        buff_n = Modbus.CRC_data&0xFF;                                        //校验

        //putchars4_8th(buff_n, n);                                                        //串口4发送
        UART4_Send_n(buff_n, n);
}

/******************************************************************/
/*** 函数名称:void WriteReg(void)                                       *******/
/*** 函数说明:写寄存器                                                       *******/
/*** 参数:none                                                                             *******/
/*** 编写: 小坤                                                               *******/
/*** 备注:2024-2-23   V1.0                                                   *******/
/******************************************************************/
void WriteReg(void)
{
        Buff_u16_u8 Buff1;       
        INT8U buff_n;       
        INT16U i=0;
        INT8U n=0;
       
        if( Modbus.CMD == 0X06 )                //写单个寄存器
        {
                if( Modbus.Reg_addr <=         Reg_len)                //判断地址是否合规
                {
                        Buff1.Byte = Modbus.buff;
                        Buff1.Byte = Modbus.buff;        //获取数据
                        Modbus.Write_Reg = Buff1.Dat;        //寄存器赋值
                        Modbus.Write_state        = 1;               /*加入存储 */
                        goto END;
                }       
        }       
        if( Modbus.CMD == 0X10 )                //写多个寄存器
        {
                Modbus.Reg_Len = Modbus.buff*256+Modbus.buff;
                if((Modbus.Reg_Len<1)||(Modbus.Reg_Len>123))        return;                        //寄存器个数范围   1<=寄存器数量<=123
      if(Modbus.Reg_Len*2!=Modbus.buff)       return;                                //数据字节数据范围Modbus.Reg_Len*2
                if(Modbus.Reg_addr+Modbus.Reg_Len >Reg_len)   return;           //起始地址+寄存器长度<=总寄存器数量       
               
                for(i=Modbus.Reg_addr; i<(Modbus.Reg_addr+Modbus.Reg_Len); i++ )                       
                {               
                        Buff1.Byte = Modbus.buff;               
                        n++;
                        Buff1.Byte = Modbus.buff;;
                        n++;                       
                        Modbus.Write_Reg = Buff1.Dat;                        //寄存器赋值                       
                }
               
                Modbus.Write_state        = 1;               /*加入存储 */
        }
       
END:
        for(n=0; n<6; n++)
        {
                buff_n = Modbus.buff;                 //返回值
        }
        Modbus.CRC_data = crc16(buff_n, n);       
        buff_n = Modbus.CRC_data>>8;
        buff_n = Modbus.CRC_data&0xFF;                //校验       
        //putchars4_8th(buff_n, n);                                //串口4发送
        UART4_Send_n(buff_n, n);
}

       
/******************************************************************/
/*** 函数名称:void ZT_Moddus_Cail_Task(void)                         *******/
/*** 函数说明:Modbus任务处理 从机                                              *******/
/*** 参数:none                                                                             *******/
/*** 编写: 小坤                                                               *******/
/*** 备注:2024-2-23   V1.0                                                   *******/
/******************************************************************/

void Moddus_Task(void)
{
        INT8U i=0;

        for( i=0; i<Uart4.Rx_counter; i++ )
        {
                Modbus.buff = Uart4.Rx_buff;               
        }
       
        Modbus.len = Uart4.Rx_counter;       
       
        Modbus.CRC_data = crc16((INT8U*)&Modbus.buff, (Modbus.len-2));                         //计算CRC校验值
       
        Modbus.CRC_H = Modbus.CRC_data >> 8;
        Modbus.CRC_L = Modbus.CRC_data & 0xFF;                                                                                //拆分高低位       
       

        if((Modbus.buff == Modbus.CRC_H) && (Modbus.buff == Modbus.CRC_L))//判断CRC校验是否正确                       
        {       
                Modbus.address = Modbus.buff;                                                                                //地址               
       
                if((Modbus.address == GSPCCommControlComponent.address)||(Modbus.address == 255))                //判断地址               
                {
                        Modbus.CMD = Modbus.buff;                                                                                //功能码       
               
                        Modbus.Reg_addr =Modbus.buff*256+Modbus.buff;                                //寄存器地址                       
                        switch(Modbus.CMD )
                        {
                                case 0x03:        ReadReg();                                break;                                                //读寄存器
                               
                                case 0x06:       
                                case 0x10:WriteReg();                                break;                                                //写寄存器                                                      
                                //default:        Send_Err(Err_CMD);                break;                                                //异常功能码
                        }                                       
                }                                       
        }       
}

远行的鹿 发表于 2024-10-28 14:26:45

代码编辑使用“<>"展示的排版效果更好{:5_275:}

邮箱 发表于 2024-10-28 17:33:54

{:5_332:}

琪琪鸭 发表于 2024-10-28 19:35:44

{:5_284:}

小坤 发表于 2024-10-30 08:10:09

远行的鹿 发表于 2024-10-28 14:26
代码编辑使用“"展示的排版效果更好

截图看看,我也试试

远行的鹿 发表于 2024-10-30 10:40:47

小坤 发表于 2024-10-30 08:10
截图看看,我也试试

在回帖的上方有个尖括号“<>", 点击它再输入代码即可

小坤 发表于 2024-10-30 11:43:27

远行的鹿 发表于 2024-10-30 10:40
在回帖的上方有个尖括号“", 点击它再输入代码即可

了解

小坤 发表于 2024-11-2 13:02:48

{:5_332:}

angalp 发表于 2024-11-2 13:45:53

学习学习,顺便赚点积分

小坤 发表于 2024-11-12 13:25:55

{:5_332:}
页: [1] 2
查看完整版本: Modbus 从机读写 赚点积分 勿喷