STM32F103单片机modbus通信示例_modbus stm32f103

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

u8  j = 0;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

delay_init();       //延时函数初始化
LED_Init();         //初始化与LED连接的硬件接口
uart2_init(9600);
while(1)
{
  
    if( receiveOK_flag )				//一帧数据接收完成后开始处理数据
    {
        receiveOK_flag = 0;
        DisposeReceive();				//处理modbus通信
    }
		
    j++;
    if(j > 50)
    {
        j = 0;
        LED = !LED;
    }
    delay_ms(10);
}

}


最后是Modbus的协议解析



void DisposeReceive( void )
{
u16 CRC16 = 0, CRC16Temp = 0;
if( data_backup[0] == SlaveID ) //地址等于本机地址 地址范围:1 - 32
{
CRC16 = App_Tab_Get_CRC16( data_backup, dataLen_backup - 2 ); //CRC校验 低字节在前 高字节在后 高字节为报文最后一个字节
CRC16Temp = ( ( u16 )( data_backup[dataLen_backup - 1] << 8 ) | data_backup[dataLen_backup - 2] );
if( CRC16 != CRC16Temp )
{
err = 4; //CRC校验错误
}
StartRegAddr = ( u16 )( data_backup[2] << 8 ) | data_backup[3];
if( StartRegAddr > (HoldRegStartAddr + HoldRegCount - 1) )
{
err = 2; //起始地址不在规定范围内 00 - 07 1 - 8号通道
}
if( err == 0 )
{
switch( data_backup[1] ) //功能码
{
case 3: //读多个寄存器
{
Modbus_03_Slave();
break;
}
case 6: //写单个寄存器
{
Modbus_06_Slave();
break;
}
case 16: //写多个寄存器
{
Modbus_16_Slave();
break;
}
default:
{
err = 1; //不支持该功能码
break;
}
}
}
if( err > 0 )
{
SendBuf[0] = data_backup[0];
SendBuf[1] = data_backup[1] | 0x80;
SendBuf[2] = err; //发送错误代码
CRC16Temp = App_Tab_Get_CRC16( SendBuf, 3 ); //计算CRC校验值
SendBuf[3] = CRC16Temp & 0xFF; //CRC低位
SendBuf[4] = ( CRC16Temp >> 8 ); //CRC高位
uart2_Send( SendBuf, 5 );
err = 0; //发送完数据后清除错误标志
}
}
}

/*
函数功能:读保持寄存器 03
主站请求报文: 0x01 0x03 0x0000 0x0001 0x840A 读从0开始的1个保持寄存器
从站正常响应报文: 0x01 0x03 0x02 0x09C4 0xBF87 读到的2字节数据为 0x09C4
/
void Modbus_03_Slave( void )
{
u16 RegNum = 0;
u16 CRC16Temp = 0;
u8 i = 0;
RegNum = ( u16 )( data_backup[4] << 8 ) | data_backup[5]; //获取寄存器数量
if( ( StartRegAddr + RegNum ) <= (HoldRegStartAddr + HoldRegCount) ) //寄存器地址+寄存器数量 在规定范围内 <=8
{
SendBuf[0] = data_backup[0]; //地址
SendBuf[1] = data_backup[1]; //功能码
SendBuf[2] = RegNum * 2; //返回字节数量
for( i = 0; i < RegNum; i++ ) //循环读取保持寄存器内的值
{
SendBuf[3 + i * 2] = HoldReg[StartRegAddr * 2 + i * 2];
SendBuf[4 + i * 2] = HoldReg[StartRegAddr * 2 + i * 2 + 1];
}
CRC16Temp = App_Tab_Get_CRC16( SendBuf,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值