STM32F103基于W5500实现Modbus简单TCP通信

一、Modbus/TCP协议

功能码作用
01读取线圈状态
02读取输入状态
03读取保持寄存器
04读取输入寄存器
05强置单线圈
06预置单寄存器
07读取异常状态
08回送诊断校验
09编程(只用于484)
0A控询
0B读取事件计数
0C读取通信事件记录
0D编程(184/384/484/584等)
0E探寻
0F强置多线圈
10预置多线圈
11报告多寄存器
12可使主机模拟编程功能
13重置通信链路
14读取通用参数
15写入通用参数
16屏蔽写寄存器
17读/写多个寄存器

1.查询报文

00 6D 00 00 00 06 01 03 00 00 00 01
00 6D 查询编号
00 00 协议
00 06 数据包长度
01 设备编号
03 功能码
00 00 起始地址
00 01 查询寄存器个数

2.响应报文

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.简单响应函数

返回一个全局变量data,并且每次响应后自增1。

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);

  }

三、效果

使用modbus poll建立连接
设置id、地址、读取位数
在这里插入图片描述
使用TCP/IP建立连接,设置地址、端口。
在这里插入图片描述
效果
可以看到可以成功读取到data的值
在这里插入图片描述

四、总结

这次实验只是简单的读取了一个寄存器的值,多个寄存器思路类似。

五、源码

https://github.com/TangtangSix/Modbus_TCP

  • 12
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值