Bootstrap

基于STM32L4XX、HAL库的W5500(SPI接口)驱动程序

一、概述:

        W5500是一款硬件TCP/IP芯片,通常用于嵌入式系统中实现网络连接。

二、w5500_driver.h头文件:

#ifndef W5500_DRIVER_H
#define W5500_DRIVER_H

#include "stm32l4xx_hal.h"

// W5500 寄存器定义
#define W5500_MR         0x0000  // Mode Register
#define W5500_GAR        0x0001  // Gateway Address
#define W5500_SUBR       0x0005  // Subnet Mask
#define W5500_SHAR       0x0009  // Source MAC Address
#define W5500_SIPR       0x000F  // Source IP Address
#define W5500_RTR        0x0019  // Retry Time
#define W5500_RCR        0x001B  // Retry Count

// Socket 寄存器偏移
#define W5500_SOCK_REG_BASE 0x0000  // 根据Socket不同偏移不同
#define W5500_SOCK_TX_BASE  0x0000  // Socket TX Buffer
#define W5500_SOCK_RX_BASE  0x0000  // Socket RX Buffer

// 操作模式定义
#define W5500_MR_RST    0x80    // Software Reset
#define W5500_MR_PB      0x10    // Ping Block
#define W5500_MR_AI      0x02    // Address Auto-Increment

// SPI 片选控制宏
#define W5500_CS_LOW()   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET)
#define W5500_CS_HIGH()  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET)

// 函数声明
void W5500_Init(SPI_HandleTypeDef *hspi);
void W5500_WriteReg(uint16_t reg, uint8_t data);
uint8_t W5500_ReadReg(uint16_t reg);
void W5500_WriteBuffer(uint16_t reg, uint8_t *buf, uint16_t len);
void W5500_ReadBuffer(uint16_t reg, uint8_t *buf, uint16_t len);
void W5500_SetNetwork(uint8_t *mac, uint8_t *ip, uint8_t *subnet, uint8_t *gateway);
uint8_t W5500_GetVersion(void);

#endif // W5500_DRIVER_H

三、w5500_driver.c源文件:

#include "w5500_driver.h"
#include <string.h>

static SPI_HandleTypeDef *hspi_w5500;

// W5500 SPI 读写函数
static void W5500_WriteByte(uint8_t data) {
    HAL_SPI_Transmit(hspi_w5500, &data, 1, 1000);
}

static uint8_t W5500_ReadByte(void) {
    uint8_t data = 0;
    HAL_SPI_Receive(hspi_w5500, &data, 1, 1000);
    return data;
}

// 初始化W5500
void W5500_Init(SPI_HandleTypeDef *hspi) {
    hspi_w5500 = hspi;
    
    // 硬件复位(可选)
    // HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_RESET);
    // HAL_Delay(10);
    // HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, GPIO_PIN_SET);
    // HAL_Delay(1000);
    
    // 软件复位
    W5500_WriteReg(W5500_MR, W5500_MR_RST);
    HAL_Delay(10);
    W5500_WriteReg(W5500_MR, W5500_MR_AI); // 启用地址自增模式
}

// 写寄存器
void W5500_WriteReg(uint16_t reg, uint8_t data) {
    W5500_CS_LOW();
    
    uint8_t cmd[3] = {
        (reg >> 8) & 0xFF,   // 高8位地址
        reg & 0xFF,          // 低8位地址
        0x80                 // 写操作控制码
    };
    
    HAL_SPI_Transmit(hspi_w5500, cmd, 3, 1000);
    W5500_WriteByte(data);
    
    W5500_CS_HIGH();
}

// 读寄存器
uint8_t W5500_ReadReg(uint16_t reg) {
    W5500_CS_LOW();
    
    uint8_t cmd[3] = {
        (reg >> 8) & 0xFF,   // 高8位地址
        reg & 0xFF,          // 低8位地址
        0x00                 // 读操作控制码
    };
    
    HAL_SPI_Transmit(hspi_w5500, cmd, 3, 1000);
    uint8_t data = W5500_ReadByte();
    
    W5500_CS_HIGH();
    return data;
}

// 设置网络参数
void W5500_SetNetwork(uint8_t *mac, uint8_t *ip, uint8_t *subnet, uint8_t *gateway) {
    W5500_WriteBuffer(W5500_SHAR, mac, 6);      // MAC地址
    W5500_WriteBuffer(W5500_SIPR, ip, 4);       // IP地址
    W5500_WriteBuffer(W5500_SUBR, subnet, 4);   // 子网掩码
    W5500_WriteBuffer(W5500_GAR, gateway, 4);   // 网关
}

// 读缓冲区
void W5500_ReadBuffer(uint16_t reg, uint8_t *buf, uint16_t len) {
    W5500_CS_LOW();
    
    uint8_t cmd[3] = {
        (reg >> 8) & 0xFF,
        reg & 0xFF,
        0x00  // 读操作
    };
    
    HAL_SPI_Transmit(hspi_w5500, cmd, 3, 1000);
    HAL_SPI_Receive(hspi_w5500, buf, len, 1000);
    
    W5500_CS_HIGH();
}

// 写缓冲区
void W5500_WriteBuffer(uint16_t reg, uint8_t *buf, uint16_t len) {
    W5500_CS_LOW();
    
    uint8_t cmd[3] = {
        (reg >> 8) & 0xFF,
        reg & 0xFF,
        0x80  // 写操作
    };
    
    HAL_SPI_Transmit(hspi_w5500, cmd, 3, 1000);
    HAL_SPI_Transmit(hspi_w5500, buf, len, 1000);
    
    W5500_CS_HIGH();
}

// 获取版本号(测试用)
uint8_t W5500_GetVersion(void) {
    return W5500_ReadReg(0x0039);
}

四、示例:

// 初始化
W5500_Init(&hspi1);

// 设置网络参数
uint8_t mac[6] = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56};
uint8_t ip[4] = {192, 168, 1, 100};
uint8_t subnet[4] = {255, 255, 255, 0};
uint8_t gateway[4] = {192, 168, 1, 1};
W5500_SetNetwork(mac, ip, subnet, gateway);

// 测试版本号
uint8_t version = W5500_GetVersion(); // 应返回0x04

;