STM32+W5500+以太网应用开发+001_Ping 新建工程,移植驱动

1 概述

1.1 硬件介绍

使用W5500模块,经转接板插在Nucleo-F407ZG上进行开发
在这里插入图片描述
在这里插入图片描述

1.2 软件介绍

  1. STM32CubeMX 6.21;
  2. STM32Cube_FW_F4_V1.26.2;
  3. Keil 5.36

2 使用STM32CubeMX新建工程

2.1 选择芯片STM32F407ZG

在这里插入图片描述

2.2 配置工程

在这里插入图片描述

2.3 配置时钟

时钟配置需要和自己的硬件电路匹配
在这里插入图片描述
注意晶振频率和倍频频率
在这里插入图片描述

2.4 配置SWD

在这里插入图片描述

2.5 配置IO引脚

W5500引脚描述
PWDN连接PB8,普通IO即可,输出,高电平有效
CS连接PD14,普通IO即可,输出,低电平有效
RST连接PB9,普通IO即可,输出,上升沿有效
INT连接PD15,普通IO即可,输入

在这里插入图片描述

2.6 配置SPI

W5500引脚描述
SCK连接PA5,SPI1_SCK
MISO连接PA6,SPI1_MISO
MOSI连接PA7,SPI1_MOSI

在这里插入图片描述
在这里插入图片描述

2.7 配置串口

打印信息需要使用到串口
在这里插入图片描述

2.8 生成代码

3 移植Wiznet最新驱动库

ioLibrary_Driver-4.0.0.zip

3.1 拷贝socket和wizchip_conf文件

在这里插入图片描述
在这里插入图片描述
wizchip_conf.h里面默认的是W5500芯片,如果使用该系列其他芯片修改定义即可
在这里插入图片描述

3.2 拷贝W5500文件夹(即w5500.c/.h文件)

在这里插入图片描述
在这里插入图片描述

3.3 新建硬件适配驱动文件w5500_spi.c/.h

w5500_spi.c

#include "w5500_spi.h"
#include "wizchip_conf.h"
#include "stdio.h"

extern SPI_HandleTypeDef hspi1;

uint8_t SPIReadWrite(uint8_t TxData)
{
  uint8_t RxData;
  HAL_SPI_TransmitReceive(&hspi1, (uint8_t *)&TxData, &RxData, 1, 100);
  return RxData;
}

void  wizchip_select(void)
{
	HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_RESET);
}

void  wizchip_deselect(void)
{
	HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_SET);
}

uint8_t wizchip_read(void)
{
	uint8_t rb;
	rb=SPIReadWrite(0x00);
	return rb;
}

void  wizchip_write(uint8_t wb)
{
	SPIReadWrite(wb);
}

void wizchip_readburst(uint8_t* pBuf, uint16_t len)
{
	for(uint16_t i=0;i<len;i++)
	{
		*pBuf=SPIReadWrite(0x00);
		pBuf++;
	}
}

void  wizchip_writeburst(uint8_t* pBuf, uint16_t len)
{
	for(uint16_t i=0;i<len;i++)
	{
		SPIReadWrite(*pBuf);
		pBuf++;
	}
}

void W5500IOInit(void)
{
  //使用STM32Cube生成的IO引脚初始化
}

void w5500_enter_critical(void)
{
	__disable_irq();
}

void w5500_exit_critical(void)
{
	__enable_irq();
}

void W5500Init()
{
	uint8_t tmp;
	uint8_t memsize[2][8] = { { 2, 2, 2, 2, 2, 2, 2, 2 }, { 2, 2, 2, 2, 2, 2, 2, 2 } };

	W5500IOInit();

	HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_SET);//CS high by default

	//Send a pulse on reset pin
	HAL_GPIO_WritePin(W5500_NRST_GPIO_Port, W5500_NRST_Pin, GPIO_PIN_RESET);
	tmp = 0xFF;
	while(tmp--);
	HAL_GPIO_WritePin(W5500_NRST_GPIO_Port, W5500_NRST_Pin, GPIO_PIN_SET);

	reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect);
	reg_wizchip_spi_cbfunc(wizchip_read, wizchip_write);
	reg_wizchip_spiburst_cbfunc(wizchip_readburst, wizchip_writeburst);
	reg_wizchip_cris_cbfunc(w5500_enter_critical, w5500_exit_critical);

	/* WIZChip Initialize*/
	if (ctlwizchip(CW_INIT_WIZCHIP, (void*) memsize) == -1) {
		printf("WIZCHIP Initialized Failed.\r\n");
		while (1);
	}
	printf("WIZCHIP Initialization Success.\r\n");

	//Check if SPI is working
	printf("Auto-detecting Ethernet Chip on SPI Port...");
	if(WIZCHIP_READ(VERSIONR)==0x04)
	{
		printf("W5500 Found on SPI\r\n");
	}
	else
	{
		printf("W5500 NOT Found on SPI\r\n");
		printf("Double Check SPI Cables\r\n");
		while(1);
	}
}


w5500_spi.h

/*
 * w5500_spi.h
 *
 *  Created on: Sep 29, 2021
 *      Author: Avinash
 */

#ifndef SRC_W5500_W5500_SPI_H_
#define SRC_W5500_W5500_SPI_H_

#include "main.h"

void W5500Init(void);

void  wizchip_select(void);
void  wizchip_deselect(void);

uint8_t wizchip_read(void);
void  wizchip_write(uint8_t wb);

void wizchip_readburst(uint8_t* pBuf, uint16_t len);
void  wizchip_writeburst(uint8_t* pBuf, uint16_t len);

#endif /* SRC_W5500_W5500_SPI_H_ */

3.4 添加文件到工程

在这里插入图片描述

3.5 添加头文件路径

在这里插入图片描述

4 main.c文件代码修改

4.1 头文件包含

/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "w5500_spi.h"
#include "wizchip_conf.h"
#include "socket.h"
/* USER CODE END Includes */

4.2 变量定义和函数声明

#define LISTEN_PORT 5000
#define RECEIVE_BUFF_SIZE 128

wiz_NetInfo gWIZNETINFO = {
  .mac = { 0x80, 0x80, 0x80,0x80,0x80,0x80 },//MSB - LSB
  .ip  = { 192, 168, 1, 10 },
  .sn  = { 255, 255, 255, 0 },
  .gw  = { 192, 168, 1, 1 },
  .dns  = { 8, 8, 8, 8 },
  .dhcp = NETINFO_STATIC };
uint8_t receive_buff[RECEIVE_BUFF_SIZE];
  
static void PHYStatusCheck(void);
static void PrintPHYConf(void);

4.3 main函数修改

int main(void)
{
  //其他省略
  /* USER CODE BEGIN 2 */
  printf("A simple Ping Application using W5500!\r\n");
  W5500Init();
  //配置网络参数
  ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);
  //配置PHY参数
  wiz_PhyConf phyconf;
  phyconf.by = PHY_CONFBY_SW;
  phyconf.duplex = PHY_DUPLEX_FULL;
  phyconf.speed = PHY_SPEED_10;
  phyconf.mode = PHY_MODE_AUTONEGO;
  ctlwizchip(CW_SET_PHYCONF, (void*)&phyconf); //PHY Configuration Command
  PHYStatusCheck();
  PrintPHYConf();
  printf("Simple Ping Application\r\n");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4.4 串口打印支持函数

#if (defined(__GNUC__) && !defined(__CC_ARM))
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(void)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif /* __GNUC__ */

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART2 and Loop until the end of transmission */
  while (HAL_OK != HAL_UART_Transmit(&huart3, (uint8_t *) &ch, 1, 30000))
  {
    ;
  }
  return ch;
}

/**
  * @brief  Retargets the C library scanf function to the USART.
  * @param  None
  * @retval None
  */
GETCHAR_PROTOTYPE
{
  /* Place your implementation of fgetc here */
  /* e.g. read a character on USART and loop until the end of read */
  uint8_t ch = 0;
  while (HAL_OK != HAL_UART_Receive(&huart3, (uint8_t *)&ch, 1, 30000))
  {
    ;
  }
  return ch;
}

4.5 以太网状态打印函数

void PHYStatusCheck(void)
{
	uint8_t tmp;

	do
	{
		printf("\r\nChecking Ethernet Cable Presence ...");
		ctlwizchip(CW_GET_PHYLINK, (void*) &tmp);

		if(tmp == PHY_LINK_OFF)
		{
			printf("NO Cable Connected!");
			HAL_Delay(1500);
		}
	}while(tmp == PHY_LINK_OFF);

	printf("Good! Cable got connected!");

}

void PrintPHYConf(void)
{
	wiz_PhyConf phyconf;

	ctlwizchip(CW_GET_PHYCONF, (void*) &phyconf);

	if(phyconf.by==PHY_CONFBY_HW)
	{
		printf("\r\nPHY Configured by Hardware Pins");
	}
	else
	{
		printf("\r\nPHY Configured by Registers");
	}

	if(phyconf.mode==PHY_MODE_AUTONEGO)
	{
		printf("\r\nAutonegotiation Enabled");
	}
	else
	{
		printf("\r\nAutonegotiation NOT Enabled");
	}

	if(phyconf.duplex==PHY_DUPLEX_FULL)
	{
		printf("\r\nDuplex Mode: Full");
	}
	else
	{
		printf("\r\nDuplex Mode: Half");
	}

	if(phyconf.speed==PHY_SPEED_10)
	{
		printf("\r\nSpeed: 10Mbps");
	}
	else
	{
		printf("\r\nSpeed: 100Mbps");
	}
}

5 测试

5.1 打印信息

串口终端使用的MobaXterm,可以高亮显示log信息
在这里插入图片描述

5.2 Ping命令

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米兰的无线电

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值