STM32+W5500以太网芯片配置并实现Ping功能
摘要:本文介绍了基于STM32和W5500以太网芯片的硬件配置与软件实现方法。硬件部分概述了以太网芯片选择,软件部分详细说明了CUBEMX的时钟、SPI接口等配置,以及W5500官方库的移植步骤。重点讲解了通过SPI接口实现数据传输的关键函数,包括中断控制、CS引脚操作、单字节和批量数据传输等。最后展示了网络参数配置、物理层状态检查以及Ping测试结果,成功实现了网络通信功能。实验结果表明SPI接
目录
一、硬件概述
以太网芯片区分可看这篇文章。
二、软件配置
此方式可以运用在cubemx支持的任意芯片。
2.1 CUBEMX配置
2.1.1 时钟配置
根据电路选择晶振

配置RCC时钟

2.1.2 配置烧录口
我选择SWD

2.1.3 SPI配置
选择电路连接的SPI引脚进行配置,此处我使用SPI1,且为软件CS引脚。

2.1.4 IO配置

2.1.5 生成代码

2.2 W5500移植
2.2.1 下载官方库
2.2.2 添加所需文件
进入官方库先择5个文件复制到自己的文件夹中


2.2.3 keil添加文件
keil中添加移植的文件,以及头文件路径。


三、 程序实现
并新建 w5500_spi.c 和 w5500_spi.h 文件
需要实现的功能如下:
- 中断的开关
-
CS的开关
-
1Byte数据的发送
-
大量数据的发送
-
将以上函数注册到回调函数
-
初始化芯片配置
-
网络层配置
-
PHY层配置
-
PC 进行ping实验
w5500_spi.c文件源码如下:
#include "w5500_spi.h"
// 配置网络参数
wiz_NetInfo w5500net = {
.mac = {0x00,0x08,0xDC,0x11,0x22,0x33},
.ip = {192,168,1,101},
.sn = {255,255,255,0},
.gw = {192,168,1,1},
.dns = {8,8,8,8},
.dhcp = NETINFO_STATIC
};
wiz_PhyConf w5500phy = {
.by = PHY_CONFBY_SW,
.mode = PHY_MODE_AUTONEGO,
.speed = PHY_SPEED_10,
.duplex = PHY_DUPLEX_FULL,
};
extern SPI_HandleTypeDef hspi1;
uint8_t SPI_Read_Write(uint8_t tdata)
{
uint8_t rdata;
HAL_SPI_TransmitReceive(&hspi1, &tdata, &rdata, 1, 100);
return rdata;
}
// critical section
void wiz_cris_en(void)
{
__disable_irq();
}
void wiz_cris_exit(void)
{
__enable_irq();
}
// cs
void wiz_cs_select(void)
{
HAL_GPIO_WritePin(W5500_SCS_GPIO_Port, W5500_SCS_Pin, GPIO_PIN_RESET);
}
void wiz_cs_deselect(void)
{
HAL_GPIO_WritePin(W5500_SCS_GPIO_Port, W5500_SCS_Pin, GPIO_PIN_SET);
}
// 读写
uint8_t wiz_read_byte(void)
{
uint8_t result;
result = SPI_Read_Write(NOP);
return result;
}
void wiz_write_byte(uint8_t wb)
{
SPI_Read_Write(wb);
}
// 发送大量数据
void wiz_read_burst(uint8_t* pBuf, uint16_t len)
{
for(uint16_t i = 0; i < len; i++)
{
*pBuf++ = SPI_Read_Write(NOP); // 先赋值,地址再++地址
}
}
void wiz_write_burst(uint8_t* pBuf, uint16_t len)
{
for(uint16_t i = 0;i < len;i++) // 先发送,地址再++
{
SPI_Read_Write(*pBuf++);
}
}
void IO_init(void)
{
// 使用cubemx初始化IO
/*
cs 需要默认上拉(外部或内部)
nrst 需要默认上拉(外部或内部)
int 需要默认上拉(外部或内部)
*/
}
void w5500_hard_reset(void)
{
HAL_GPIO_WritePin(W5500__RESET_GPIO_Port, W5500__RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(W5500__RESET_GPIO_Port, W5500__RESET_Pin, GPIO_PIN_SET);
HAL_Delay(200);
}
// 检查物理链路状态
void w5500_check_link(void)
{
uint8_t phystatus = getPHYCFGR();
printf("=== W5500 PHY Status ===\r\n");
printf("PHYCFGR: 0x%02X\r\n", phystatus);
if(phystatus & PHYCFGR_LNK_ON)
{
printf("Link: UP\r\n");
if(phystatus & PHYCFGR_SPD_100)
printf("Speed: 100Mbps\r\n");
else
printf("Speed: 10Mbps\r\n");
if(phystatus & PHYCFGR_DPX_FULL)
printf("Duplex: FULL\r\n");
else
printf("Duplex: HALF\r\n");
}
else
{
printf("Link: DOWN !\r\n");
}
printf("=======================\r\n");
}
// 网络信息初始化
void w5500_net_init(void)
{
// 网络层配置
ctlnetwork(CN_SET_NETINFO, (void*)&w5500net);
// 物理层配置
ctlwizchip(CW_SET_PHYCONF,(void*)&w5500phy);
}
void w5500_ping_init(void) // ICMP 协议
{
socket(SOCKET_PING, Sn_MR_MACRAW, 0, 0);
}
void w5500_init(void)
{
// 1. 初始化IO
IO_init();
w5500_hard_reset();
wiz_cs_deselect();
// 注册回调函数
reg_wizchip_cris_cbfunc(wiz_cris_en, wiz_cris_exit);
reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect);
reg_wizchip_spi_cbfunc(wiz_read_byte, wiz_write_byte);
reg_wizchip_spiburst_cbfunc(wiz_read_burst, wiz_write_burst);
// 总共16KB 内存,8个socket,每个socket 2KB内存
uint8_t memsize[2][8] = {
{2,2,2,2,2,2,2,2}, // TX
{2,2,2,2,2,2,2,2} // RX
};
// 3. 初始化
if(ctlwizchip(CW_INIT_WIZCHIP, (void *)memsize) == -1)
{
printf("WIZCHIP init failed\r\n");
}
else
{
printf("WIZCHIP init success\r\n");
}
printf("version: %d\r\n",WIZCHIP_READ(VERSIONR));
// 4. 检测SPI连接
if(WIZCHIP_READ(VERSIONR) == 0x04)
{
printf("SPI connection success\r\n");
}
else
{
printf("SPI connection failed\r\n");
}
// 5. 初始化net 、 phy 信息
w5500_net_init();
HAL_Delay(2000); // 配置物理和网络参数后需延时等待
w5500_check_link();
}
w5500_spi.h文件如下:
/*
* w5500_spi.h
*
* Created on: Oct 20, 2025
* Author: JZ
*/
#ifndef SRC_W5500_W5500_SPI_H_
#define SRC_W5500_W5500_SPI_H_
#include "main.h"
#include "wizchip_conf.h"
#include "socket.h"
#define NOP 0xFF
#define LISTEN_PORT 8000
#define SOCKET_PING 0
void w5500_init(void);
// 临界资源
void wiz_cris_en(void);
void wiz_cris_exit(void);
// cs
void wiz_cs_select(void);
void wiz_cs_deselect(void);
// 读写
uint8_t wiz_read_byte(void);
void wiz_write_byte(uint8_t wb);
// 发送大量数据
void wiz_read_burst(uint8_t* pBuf, uint16_t len);
void wiz_write_burst(uint8_t* pBuf, uint16_t len);
#endif /* SRC_W5500_W5500_SPI_H_ */
四、实验结果
如果想要串口输出,可自行实现串口重定向,本文不过多赘述。下方是输出结果,表明SPI、w5500均已配置成功。

使用网线将开发板连接到电脑,需要保证PC的IP地址和开发板配置的地址在同一网段,若不在同一网段需要手动配置修改。


最终实验效果:ping通,实验成功!

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)