This article will teach you how to drive the W5500 module using the SPI method on the STM32F723 Discovery Kit development board to achieve network ping.
I. Hardware Circuit
The test interface uses PMOD's SPI2. When using this interface, you need to use PMOD_SEL_0 and PMOD_SEL_1 to switch the interface function.
Hardware Connection Diagram
II. Program
Partial Driver Programs
2.1 spi.c
This article will teach you how to drive the W5500 module using the SPI method on the STM32F723 Discovery Kit development board to achieve network ping.
I. Hardware Circuit
The test interface uses PMOD's SPI2. When using this interface, you need to use PMOD_SEL_0 and PMOD_SEL_1 to switch the interface function.
Hardware Connection Diagram
II. Program
Partial Driver Programs
2.1 spi.c
#include "main.h"
#include "spi/spi.h"
SPI_HandleTypeDef hspi2;
void init_spi(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/**SPI1 GPIO Configuration
PI3 ------> SPI2_MOSI
PI2 ------> SPI2_MISO
PI1 ------> SPI2_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
//PH15 ----> PMOD_SEL_0
//PI10 ----> PMOD_SEL_1
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_15, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_10, GPIO_PIN_RESET);
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
}
}
2.2 w5500_conf.c
The W5500 module driver part; the main modifications are in this file.
/**
******************************************************************************
* [url=home.php?mod=space&uid=1307177]@File[/url] w5500_conf.c
* [url=home.php?mod=space&uid=252314]@version[/url] V1.2
* [url=home.php?mod=space&uid=311857]@date[/url] 2017-11-01
* [url=home.php?mod=space&uid=159083]@brief[/url] ÓÃ3.5.0°æ±¾¿â½¨µÄ¹¤³ÌÄ£°å
* [url=home.php?mod=space&uid=1020061]@attention[/url] ÅäÖÃMCU£¬ÒÆÖ²w5500³ÌÐòÐèÒªÐ޸ĵÄÎļþ£¬ÅäÖÃw5500µÄMACºÍIPµØÖ·
******************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include "w5500_conf.h"
//#include "bsp_spi_flash.h"
#include "utility.h"
#include "w5500.h"
#include "dhcp.h"
//#include "bsp_TiMbase.h"
extern SPI_HandleTypeDef hspi2;
CONFIG_MSG ConfigMsg; /*ÅäÖýṹÌå*/
EEPROM_MSG_STR EEPROM_MSG; /*EEPROM´æ´¢ÐÅÏ¢½á¹¹Ìå*/
/*MACµØÖ·Ê××Ö½Ú±ØÐëΪżÊý*/
/*Èç¹û¶à¿éW5500ÍøÂçÊÊÅä°åÔÚͬһÏÖ³¡¹¤×÷£¬ÇëʹÓò»Í¬µÄMACµØÖ·*/
uint8 mac[6]={0x00,0x08,0xdc,0x11,0x11,0x11};
/*¶¨ÒåĬÈÏIPÐÅÏ¢*/
uint8 local_ip[4]={192,168,1,25}; /*¶¨ÒåW5500ĬÈÏIPµØÖ·*/
uint8 subnet[4]={255,255,255,0}; /*¶¨ÒåW5500ĬÈÏ×ÓÍøÑÚÂë*/
uint8 gateway[4]={192,168,1,1}; /*¶¨ÒåW5500ĬÈÏÍø¹Ø*/
uint8 dns_server[4]={114,114,114,114}; /*¶¨ÒåW5500ĬÈÏDNS*/
uint16 local_port=8080; /*¶¨Òå±¾µØ¶Ë¿Ú*/
/*¶¨ÒåÔ¶¶ËIPÐÅÏ¢*/
uint8 remote_ip[4]={192,168,1,160}; /*Ô¶¶ËIPµØÖ·*/
uint16 remote_port=8080; /*Ô¶¶Ë¶Ë¿ÚºÅ*/
/*IPÅäÖ÷½·¨Ñ¡Ôñ£¬Çë×ÔÐÐÑ¡Ôñ*/
uint8 ip_from=IP_FROM_DEFINE;
uint8 dhcp_ok=0; /*dhcp³É¹¦»ñÈ¡IP*/
uint32 ms=0; /*ºÁÃë¼ÆÊý*/
uint32 dhcp_time= 0; /*DHCPÔËÐмÆÊý*/
vu8 ntptimer = 0; /*NPTÃë¼ÆÊý*/
/**
*@brief ÅäÖÃW5500µÄIPµØÖ·
*@param ÎÞ
*[url=home.php?mod=space&uid=784970]@return[/url] ÎÞ
*/
void set_w5500_ip(void)
{
/*¸´Öƶ¨ÒåµÄÅäÖÃÐÅÏ¢µ½ÅäÖýṹÌå*/
memcpy(ConfigMsg.mac, mac, 6);
memcpy(ConfigMsg.lip,local_ip,4);
memcpy(ConfigMsg.sub,subnet,4);
memcpy(ConfigMsg.gw,gateway,4);
memcpy(ConfigMsg.dns,dns_server,4);
if(ip_from==IP_FROM_DEFINE)
printf(" ʹÓö¨ÒåµÄIPÐÅÏ¢ÅäÖÃW5500:\r\n");
/*ʹÓÃEEPROM´æ´¢µÄIP²ÎÊý*/
if(ip_from==IP_FROM_EEPROM)
{
/*´ÓEEPROMÖжÁÈ¡IPÅäÖÃÐÅÏ¢*/
//read_config_from_eeprom();
/*Èç¹û¶ÁÈ¡EEPROMÖÐMACÐÅÏ¢,Èç¹ûÒÑÅäÖã¬Ôò¿ÉʹÓÃ*/
if( *(EEPROM_MSG.mac)==0x00&& *(EEPROM_MSG.mac+1)==0x08&&*(EEPROM_MSG.mac+2)==0xdc)
{
printf(" IP from EEPROM\r\n");
/*¸´ÖÆEEPROMÅäÖÃÐÅÏ¢µ½ÅäÖõĽṹÌå±äÁ¿*/
memcpy(ConfigMsg.lip,EEPROM_MSG.lip, 4);
memcpy(ConfigMsg.sub,EEPROM_MSG.sub, 4);
memcpy(ConfigMsg.gw, EEPROM_MSG.gw, 4);
}
else
{
printf(" EEPROMδÅäÖÃ,ʹÓö¨ÒåµÄIPÐÅÏ¢ÅäÖÃW5500,²¢Ð´ÈëEEPROM\r\n");
//write_config_to_eeprom(); /*ʹÓÃĬÈϵÄIPÐÅÏ¢£¬²¢³õʼ»¯EEPROMÖÐÊý¾Ý*/
}
}
/*ʹÓÃDHCP»ñÈ¡IP²ÎÊý£¬Ðèµ÷ÓÃDHCP×Óº¯Êý*/
if(ip_from==IP_FROM_DHCP)
{
/*¸´ÖÆDHCP»ñÈ¡µÄÅäÖÃÐÅÏ¢µ½ÅäÖýṹÌå*/
if(dhcp_ok==1)
{
printf(" IP from DHCP\r\n");
memcpy(ConfigMsg.lip,DHCP_GET.lip, 4);
memcpy(ConfigMsg.sub,DHCP_GET.sub, 4);
memcpy(ConfigMsg.gw,DHCP_GET.gw, 4);
memcpy(ConfigMsg.dns,DHCP_GET.dns,4);
}
else
{
printf(" DHCP×Ó³ÌÐòδÔËÐÐ,»òÕß²»³É¹¦\r\n");
printf(" ʹÓö¨ÒåµÄIPÐÅÏ¢ÅäÖÃW5500\r\n");
}
}
/*ÒÔÏÂÅäÖÃÐÅÏ¢£¬¸ù¾ÝÐèҪѡÓÃ*/
ConfigMsg.sw_ver[0]=FW_VER_HIGH;
ConfigMsg.sw_ver[1]=FW_VER_LOW;
/*½«IPÅäÖÃÐÅϢдÈëW5500ÏàÓ¦¼Ä´æÆ÷*/
setSUBR(ConfigMsg.sub);
setGAR(ConfigMsg.gw);
setSIPR(ConfigMsg.lip);
getSIPR (local_ip);
printf(" W5500 IPµØÖ· : %d.%d.%d.%d\r\n", local_ip[0],local_ip[1],local_ip[2],local_ip[3]);
getSUBR(subnet);
printf(" W5500 ×ÓÍøÑÚÂë : %d.%d.%d.%d\r\n", subnet[0],subnet[1],subnet[2],subnet[3]);
getGAR(gateway);
printf(" W5500 Íø¹Ø : %d.%d.%d.%d\r\n", gateway[0],gateway[1],gateway[2],gateway[3]);
}
/**
*@brief ÅäÖÃW5500µÄMACµØÖ·
*@param ÎÞ
*@return ÎÞ
*/
void set_w5500_mac(void)
{
memcpy(ConfigMsg.mac, mac, 6);
setSHAR(ConfigMsg.mac); /**/
memcpy(DHCP_GET.mac, mac, 6);
}
/**
*@brief ÅäÖÃW5500µÄGPIO½Ó¿Ú
*@param ÎÞ
*@return ÎÞ
*/
void gpio_for_w5500_config(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
//PI0 ----> ETH_CS
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
//PF11 ----> ETH_RST
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
//PB11 ----> ETH_INT
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_11, GPIO_PIN_SET);
}
/**
*@brief W5500ƬѡÐźÅÉèÖú¯Êý
*@param val: Ϊ¡°0¡±±íʾƬѡ¶Ë¿ÚΪµÍ£¬Îª¡°1¡±±íʾƬѡ¶Ë¿ÚΪ¸ß
*@return ÎÞ
*/
void wiz_cs(uint8_t val)
{
#ifdef STM32_SPI1
if (val == LOW)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
}
else if (val == HIGH)
{
GPIO_SetBits(GPIOA, GPIO_Pin_4);
}
#endif
#ifdef STM32_SPI2
if (val == LOW)
{
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);
}
else if (val == HIGH)
{
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);
}
#endif
}
/**
*@brief ÉèÖÃW5500µÄƬѡ¶Ë¿ÚSCSnΪµÍ
*@param ÎÞ
*@return ÎÞ
*/
void iinchip_csoff(void)
{
wiz_cs(LOW);
}
/**
*@brief ÉèÖÃW5500µÄƬѡ¶Ë¿ÚSCSnΪ¸ß
*@param ÎÞ
*@return ÎÞ
*/
void iinchip_cson(void)
{
wiz_cs(HIGH);
}
/**
*@brief W5500¸´Î»ÉèÖú¯Êý
*@param ÎÞ
*@return ÎÞ
*/
void reset_w5500(void)
{
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_11, GPIO_PIN_RESET);
delay_us(50);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_11, GPIO_PIN_SET);
delay_us(50);
}
uint8_t SPI_FLASH_SendByte(uint8_t byte)
{
u8 temp = 0;
HAL_SPI_TransmitReceive(&hspi2,&byte,&temp,1,1000);
return temp;
}
/**
*@brief STM32 SPI1¶Áд8λÊý¾Ý
*@param dat£ºÐ´ÈëµÄ8λÊý¾Ý
*@return ÎÞ
*/
uint8 IINCHIP_SpiSendData(uint8 dat)
{
return(SPI_FLASH_SendByte(dat));
}
/**
*@brief дÈëÒ»¸ö8λÊý¾Ýµ½W5500
*@param addrbsb: дÈëÊý¾ÝµÄµØÖ·
*@param data£ºÐ´ÈëµÄ8λÊý¾Ý
*@return ÎÞ
*/
void IINCHIP_WRITE( uint32 addrbsb, uint8 data)
{
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8) + 4);
IINCHIP_SpiSendData(data);
iinchip_cson();
}
/**
*@brief ´ÓW5500¶Á³öÒ»¸ö8λÊý¾Ý
*@param addrbsb: дÈëÊý¾ÝµÄµØÖ·
*@param data£º´ÓдÈëµÄµØÖ·´¦¶ÁÈ¡µ½µÄ8λÊý¾Ý
*@return ÎÞ
*/
uint8 IINCHIP_READ(uint32 addrbsb)
{
uint8 data = 0;
//printf(" addrbsb=%x\r\n",addrbsb);
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8)) ;
data = IINCHIP_SpiSendData(0x00);
iinchip_cson();
return data;
}
/**
*@brief ÏòW5500дÈëlen×Ö½ÚÊý¾Ý
*@param addrbsb: дÈëÊý¾ÝµÄµØÖ·
*@param buf£ºÐ´Èë×Ö·û´®
*@param len£º×Ö·û´®³¤¶È
*@return len£º·µ»Ø×Ö·û´®³¤¶È
*/
uint16 wiz_write_buf(uint32 addrbsb,uint8* buf,uint16 len)
{
uint16 idx = 0;
if(len == 0) printf(" Unexpected2 length 0\r\n");
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8) + 4);
for(idx = 0; idx < len; idx++)
{
IINCHIP_SpiSendData(buf[idx]);
}
iinchip_cson();
return len;
}
/**
*@brief ´ÓW5500¶Á³ölen×Ö½ÚÊý¾Ý
*@param addrbsb: ¶ÁÈ¡Êý¾ÝµÄµØÖ·
*@param buf£º´æ·Å¶ÁÈ¡Êý¾Ý
*@param len£º×Ö·û´®³¤¶È
*@return len£º·µ»Ø×Ö·û´®³¤¶È
*/
uint16 wiz_read_buf(uint32 addrbsb, uint8* buf,uint16 len)
{
uint16 idx = 0;
if(len == 0)
{
printf(" Unexpected2 length 0\r\n");
}
iinchip_csoff();
IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);
IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);
IINCHIP_SpiSendData( (addrbsb & 0x000000F8));
for(idx = 0; idx < len; idx++)
{
buf[idx] = IINCHIP_SpiSendData(0x00);
}
iinchip_cson();
return len;
}
/**
*@brief дÅäÖÃÐÅÏ¢µ½EEPROM
*@param ÎÞ
*@return ÎÞ
*/
void write_config_to_eeprom(void)
{
//uint16 dAddr=0;
//ee_WriteBytes(ConfigMsg.mac,dAddr,(uint8)EEPROM_MSG_LEN);
//delay_ms(10);
}
/**
*@brief ´ÓEEPROM¶ÁÅäÖÃÐÅÏ¢
*@param ÎÞ
*@return ÎÞ
*/
void read_config_from_eeprom(void)
{
//ee_ReadBytes(EEPROM_MSG.mac,0,EEPROM_MSG_LEN);
//delay_us(10);
}
/**
*@brief STM32¶¨Ê±Æ÷2³õʼ»¯
*@param ÎÞ
*@return ÎÞ
*/
void timer2_init(void)
{
// TIM2_Configuration(); /* TIM2 ¶¨Ê±ÅäÖà */
// TIM2_NVIC_Configuration(); /* ¶¨Ê±Æ÷µÄÖжÏÓÅÏȼ¶ */
// RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); /* TIM2 ÖØÐ¿ªÊ±ÖÓ£¬¿ªÊ¼¼ÆÊ± */
}
/**
*@brief dhcpÓõ½µÄ¶¨Ê±Æ÷³õʼ»¯
*@param ÎÞ
*@return ÎÞ
*/
void dhcp_timer_init(void)
{
//timer2_init();
init_tim();
}
/**
*@brief ntpÓõ½µÄ¶¨Ê±Æ÷³õʼ»¯
*@param ÎÞ
*@return ÎÞ
*/
void ntp_timer_init(void)
{
//timer2_init();
init_tim();
}
/**
*@brief ¶¨Ê±Æ÷2ÖжϺ¯Êý
*@param ÎÞ
*@return ÎÞ
*/
//void timer2_isr(void)
void timer2_hdl(void)
{
ms++;
if(ms>=1000)
{
ms=0;
dhcp_time++; /*DHCP¶¨Ê±¼Ó1S*/
#ifndef __NTP_H__
ntptimer++; /*NTPÖØÊÔʱ¼ä¼Ó1S*/
#endif
}
}
/**
*@brief STM32ϵͳÈí¸´Î»º¯Êý
*@param ÎÞ
*@return ÎÞ
*/
void reboot(void)
{
// pFunction Jump_To_Application;
// uint32 JumpAddress;
printf(" ÏµÍ³ÖØÆôÖÐ......\r\n");
// JumpAddress = *(vu32*) (0x00000004);
// Jump_To_Application = (pFunction) JumpAddress;
// Jump_To_Application();
}
2.3 main.c
#include "main.h"
#include "led/led.h"
#include "delay/delay.h"
#include "key/key.h"
#include "usart/usart.h"
#include "sram/sram.h"
#include "STM32F723E-Discovery/stm32f723e_discovery_lcd.h"
#include "STM32F723E-Discovery/stm32f723e_discovery_qspi.h"
#include "i2c/i2c.h"
#include "spi/spi.h"
#include "tim/tim.h"
#include "w5500_conf.h"
#include "w5500.h"
#include "ping.h"
static void MPU_Config(void);
static void SystemClock_Config(void);
static void CPU_CACHE_Enable(void);
int main(void)
{
uint16_t i=0;
uint8_t txbuf[10];
uint8_t rxbuf[10];
HAL_Init();
MPU_Config(); /* Configure the MPU attributes */
CPU_CACHE_Enable(); /* Enable the CPU Cache */
SystemClock_Config(); /* Configure the system clock to 216 MHz */
delay_init(216);
led_init();
usart_init(115200);
init_spi();
BSP_LCD_Init();
gpio_for_w5500_config();
reset_w5500();
PHY_check();
set_w5500_mac();
set_w5500_ip();
socket_buf_init(txsize, rxsize);
printf(" 应用程序执行中......\r\n");
LED5(0);
LED6(1);
BSP_LCD_Clear(LCD_COLOR_RED);
while (1)
{
do_ping();
if(req>=4)
{
close(SOCK_PING);
break;
}
}
}
III. Program Execution
3.1 Pinging the Network
3.2 Serial Port Output During Operation