STM32 W5500
W5500会帮我封装数据,我发给W5500的是数据,W5500发出去的是协议帧。
使用W5500的前置知识点:
W5500使用前需要先进行复位,也就是将RST输入引脚拉低10ms以上,然后再拉高50ms。
W5500的版号寄存器地址是0X0039,当读取这个寄存器返回值是0X04,就证明通信通了
W5500需要配置四个参数:

这四个参数都是配置给W5500的。
关于MAC地址:一共是6个字节,第一个字节只能是偶数。

关于IP地址:分为网段+自己的地址,同网段的设备可以连接在同一个局域网中
关于子网掩码:掩码二进制左边连续 1 的个数 = 网段位数,所以常见的255,255,255,0的意思就是24个连续的1的掩码,从左往右24位是网段

关于网关(路由器地址):同网段的设备算是在一个村子里,网关相当于村口大门,村子里的设备想要与外界沟通必须经过大门


关于路由器:只走网段,不管具体的网址

简化版

一个实际的例子

Socket是什么
可以这样说,Socket就是一个通讯通道,在W5500中这是一个实际的通道,它有专门的目的地,也就是端口号,有通道深度,
也就是数据缓存空间的大小,还可以配置通道的类型,比如配置成TCP/UDP/...(可能还对应了特定的规则,比如帧的格式?还没学那么深入)

W5500的INT是上拉开漏输出
下面是驱动的流程






使用W5500官方库+HAL的实践。
我自己尝试了使用官方库,失败了,然后参考了很多gitee上的代码,终于理解了使用官方库的方法。
void UDPinit(void){
// 1. 硬件复位
W5500_RESET();
//2.将MCU的驱动CS SPI 中断开关 的函数注册到W5500官方库当中
reg_wizchip_cris_cbfunc(w5500_cris_enter, w5500_cris_exit);
reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect);
reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte);
//3配置W5500的信息:MAC IP 掩码 网关 DNS 静态DHCP
ctlnetwork(CN_SET_NETINFO, (void*)&gSetNetInfo);
// 4. 初始化WIZCHIP
uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2}, {2,2,2,2,2,2,2,2}}; // 每个Socket的收发缓冲区大小(KB),共8个Socket
if(ctlwizchip(CW_INIT_WIZCHIP, (void)memsize)) {
// 初始化失败,通常意味着硬件通讯有问题
printf("WIZCHIP Initialization Failed!\r\n");
while(1);
}
// 5. 等待PHY链接建立
uint8_t phy_link=PHY_LINK_OFF;
do {
if(ctlwizchip(CW_GET_PHYLINK, (void)&phy_link) == -1){
printf("Read PHY link failed, retry...\r\n");
HAL_Delay(100);
continue; // 跳过本次循环剩余部分,重新尝试
}
}
while(phy_link == PHY_LINK_OFF);
printf("PHY Link is OK!\r\n");
// wiz_phy_link_check();
// 6. 设置网络信息,比如TCP或者UDP
close(SOCK_UDPS);
uint8_t sta = getSn_SR(SOCK_UDPS);
if(sta == SOCK_CLOSED)
{
socket(SOCK_UDPS, Sn_MR_UDP, 5001, 0);
}
HAL_Delay(100);
}
如果是在配置成TCP模式,那么第六步需要改一下,还得加上第七步
// 6. 设置网络信息
close(SOCK_TCPC);
uint8_t sta = getSn_SR(SOCK_TCPC);
if(sta == SOCK_CLOSED)
{
socket(SOCK_TCPC, Sn_MR_TCP, 60001, 0);
}
//如果前面已经做了物理层联通校验,这个延时可以不需要
HAL_Delay(1000);
//7.尝试连接到TCP服务器
connect(SOCK_TCPC,tcpIP,tcpPort);
// 等待状态变为 SOCK_ESTABLISHED
uint32_t start = HAL_GetTick();
while (getSn_SR(SOCK_TCPC) != SOCK_ESTABLISHED) {
if (HAL_GetTick() - start > 5000) { // 5 秒超时
printf("Connect timeout\r\n");
close(SOCK_TCPC);
return;
}
HAL_Delay(10);
}
printf("Connected to server\r\n");
//8.发个数据测试看看
send(SOCK_TCPC,tcpBuff,sizeof(tcpBuff));
OSI( Open Systems Interconnection )七层模型

TCP/IP 4层模型

需要简要提一下的是,计算机网络的7层模型中,最底层的是物理层,再往上是链路层,网络层。为了代码的健壮性,最好先等待检测物理层的链接完成建立之后,
再进行链路层或者其他层的通讯。这个检测可以是延时等待,也可以是通过函数不断判断物理层的状态。我先前之所以TCP通讯不上,就是因为等待的时间不够,
直接就调用connect()函数尝试与TCP服务器进行连接,然后由于物理层没有准备好,连接失败了;还有就是当调用connect这个函数的时候,起作用的只有下面
的四层,因为与TCP服务器与TCP客户端建立连接只需要这些操作,所以说,TCP/IP是网络传输的基础。还有就是先前配置mac地址,配置W5500自身通道之类的,由于
都是自身的配置,不涉及到与其他设备的交互,所以先后顺序按理说应该是不重要的,需要注意的只有一点,在与其他设备进行交互时,自身的配置一定得齐全,该有的都得有。
这七层模型只有在数据传输的时候才起作用,至于响应几层,就看传输的数据了,比如请求建立TCP链接的只会影响4层。
浙公网安备 33010602011771号