目录

一、硬件概述

二、软件配置

2.1 CUBEMX配置

2.1.1 时钟配置

2.1.2 配置烧录口

2.1.3 SPI配置

2.1.4 IO配置

2.2 W5500移植

2.2.1 下载官方库

2.2.2 添加所需文件

2.2.3 keil添加文件

三、 程序实现

四、实验结果


一、硬件概述

以太网芯片区分可看这篇文章。

文章地址:

二、软件配置

此方式可以运用在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 下载官方库

下载地址:GitHub - Wiznet/ioLibrary_Driver: ioLibrary_Driver can be used for the application design of WIZnet TCP/IP chips as W5500, W5300, W5200, W5100, W5100S, W6100, W6300.

2.2.2 添加所需文件

进入官方库先择5个文件复制到自己的文件夹中

2.2.3 keil添加文件

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

三、 程序实现

并新建 w5500_spi.c 和 w5500_spi.h 文件

需要实现的功能如下:

  1. 中断的开关
  2. CS的开关

  3. 1Byte数据的发送

  4. 大量数据的发送

  5. 将以上函数注册到回调函数

  6. 初始化芯片配置

  7. 网络层配置

  8. PHY层配置

  9. 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通,实验成功!

Logo

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

更多推荐