一、Modbus/TCP协议
1.功能码
2.查询报文和相应报文
查询报文:
00 6D 00 00 00 06 01 03 00 00 00 01 00 6D 查询编号 00 00 协议 00 06 数据包长度 01 设备编号 03 功能码 00 00 起始地址 00 01 查询寄存器个数
响应报文:
00 6D 00 00 00 05 01 03 02 00 17 00 6D 查询编号 00 00 协议 00 05 数据包长度 01 设备地址 03 功能码 02 数据长度 00 17 数据值
二.从机代码
1.初始化从机网络
void Load_Net_Parameters(void)
{
Gateway_IP[0] = 192;//加载网关参数
Gateway_IP[1] = 168;
Gateway_IP[2] = 1;
Gateway_IP[3] = 1;
Sub_Mask[0]=255;//加载子网掩码
Sub_Mask[1]=255;
Sub_Mask[2]=255;
Sub_Mask[3]=0;
Phy_Addr[0]=0x0c;//加载物理地址
Phy_Addr[1]=0x29;
Phy_Addr[2]=0xab;
Phy_Addr[3]=0x7c;
Phy_Addr[4]=0x00;
Phy_Addr[5]=0x01;
IP_Addr[0]=192;//加载本机IP地址
IP_Addr[1]=168;
IP_Addr[2]=1;
IP_Addr[3]=199;
S0_Port[0] = 0x13;//加载端口0的端口号5000
S0_Port[1] = 0x88;
S0_Mode=TCP_SERVER;//加载端口0的工作模式,TCP服务端模式
}
2.简单响应函数
void Process_Socket_Data(SOCKET s)
{
int len;
unsigned char msg[11]={0x00,0x00,0x00 ,0x00, 0x00, 0x05, 0x01, 0x03, 0x02, 0x00, 0x70};
len=sizeof(msg);
unsigned short size;
size=Read_SOCK_Data_Buffer(s, Rx_Buffer);
memcpy(Tx_Buffer, Rx_Buffer, size);
for (int j=0;j<size;j++){
printf("0x%02X ",Tx_Buffer[j]);
}
msg[0]=Tx_Buffer[0];
msg[1]=Tx_Buffer[1];
msg[2]=0x00;
msg[3]=0x00;
msg[4]=0x00;
msg[5]=0x05;
msg[6]=Tx_Buffer[6];
msg[7]=Tx_Buffer[7];
msg[8]=0x02;
msg[10]=data&0XFF;
msg[9]=data>>8;
memcpy(Tx_Buffer, msg, len);
Write_SOCK_Data_Buffer(0, Tx_Buffer, len);
data++;
}
3.main函数循环等待连接
while (1)
{
W5500_Socket_Set();//W5500端口初始化配置
W5500_Interrupt_Process();//W5500中断处理程序框架
if((S0_Data & S_RECEIVE) == S_RECEIVE)//如果Socket0接收到数据
{
S0_Data&=~S_RECEIVE;
Process_Socket_Data(0);//W5500接收并发送接收到的数据
}
//从机状态标志
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
}
三.结果
1.使用modbus poll建立连接 设置id、地址、读取位数 2.使用TCP/IP建立连接,设置地址、端口。
3.效果 可以看到可以成功读取到data的值
四.总结
此次实验我们简单的读取了一个寄存器的值,同样方式在多个寄存器同样适用。
五.参考文献
https://blog.csdn.net/qq_47281915/article/details/121927294?spm=1001.2014.3001.5501.
|