文章目录[隐藏]
一、W5500以太网模块介绍
Niren_W5500模块是一款基于WIZnet W5500芯片的以太网模块,是泥人电子继 Niren_W5100模块后设计的一块性能更好、性价比更高的以太网模块。模块集成硬件化TCP/IP协议:内部32K字节存储器作TX/RX
缓存:支持10/100Mbps的传输速率;支持8个独立端口同时运行;同时模块还支持3.3V或5V电源供电,5V供电时还可以输出3.3V电源,方便用户在不同的单片机系统中使用;模块与单片机系统的通讯方式是简单、方便的SPI通信。
二、modbus通信
- 当设备设置为使用ASCII(美国信息交换标准代码)模式在MODBUS串行线上进行通信时,消息中的每个8位字节将作为两个ASCII4位字符发送。当物理通信链路或设备的功能不允许符合RTU计时器管理要求时,使用此模式。
所以此模式的效率不如RTU,因为每个字节需要两个字符。示例:字节0x7D编码为两个字符:0x35和0x42(在ASCII表中为0x37=‘7’,而0x44 =‘D’)。 - Modbus RTU是一种紧凑的,采用二进制表示数据的方式;因为使用二进制编码和CRC错误检查的结合使得Modbus RTU适用于工业应用,因为它比ASCII字符的替代方案更有效地传输。 在Modbus RTU与ASCII之间进行选择时,如果考虑性能,则RTU是首选。
- Modbus TCP 是在TCP/IP网络上运行的Modbus的实现,旨在允许Modbus ASCII / RTU协议在基于TCP /IP的网络上传输。Modbus / TCP将Modbus消息嵌入TCP /IP帧内。尽管实现起来非常简单,但是与网络相关的特性增加了一些挑战。例如,由于Modbus主机期望并要求在一定时间范围内对其轮询做出响应,因此必须考虑TCP/ IP网络的不确定性(和其他方面)。 Modbus ASCII和Modbus TCP之间的主要区别在于,Modbus ASCII所需的LRC错误检查由IP层执行。
三、从机代码
void Load_Net_Parameters(void)
{
Gateway_IP[0] = 192;//加载网关参数
Gateway_IP[1] = 168;
Gateway_IP[2] = 0;
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]=0;
IP_Addr[3]=199;
S0_Port[0] = 0x13;//加载端口0的端口号5000
S0_Port[1] = 0x88;
S0_Mode=TCP_SERVER;//加载端口0的工作模式,TCP服务端模式
}
- 简单响应函数,这里需要在开始定义一个全局变量data,每次调用都会使data++,而返回的数据就是把data置于数据位,值通过tcp回传回去,能在modbus poll里看到这个值
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++;
}
- 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读取设置
-
读取效果
四、总结
有的人天生就是主角,只能说,大佬确实强啊
参考链接
https://blog.csdn.net/junseven164/article/details/122148326
https://blog.csdn.net/qq_45659777/article/details/121952778
版权声明:本文为CSDN博主「羚漆」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zero_zero_seven/article/details/122203016
暂无评论