Wiznet makers

ronpang

Published January 06, 2026 ©

160 UCC

90 WCC

34 VAR

0 Contests

1 Followers

0 Following

Original Link

Implement DHCP automatic IP address acquisition function based on W5500 chip

Implement DHCP automatic IP address acquisition function based on W5500 chip

COMPONENTS
PROJECT DESCRIPTION

Implement DHCP automatic IP address acquisition function based on W5500 chip

 

I. Hardware

1. Circuit connection

W5500 pinSTM32 pinFunction Description
SCLKPA5SPI clock
MOSIPA7The main one goes out, the secondary one comes in.
MISOPA6The main enters, the secondary exits
CSPA4Chip select signal
INTPA3Interrupt pin
RESETPA2Reset pin
3.3V3.3Vpower supply
GNDGNDground wire

2. Network Topology

[STM32] --SPI--> [W5500] --RJ45--> 局域网交换机
                  ↑
              DHCP服务器

II. Software Implementation Steps

1. Register initialization

// W5500复位配置
void W5500_Reset() {
    GPIO_ResetBits(GPIOA, GPIO_Pin_2);  // 拉低RESET引脚
    Delay_ms(100);
    GPIO_SetBits(GPIOA, GPIO_Pin_2);    // 释放RESET
    Delay_ms(200);
}

// SPI接口配置(STM32 HAL库)
SPI_HandleTypeDef hspi1;

void MX_SPI1_Init(void) {
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
    HAL_SPI_Init(&hspi1);
}

2. DHCP State Machine Implementation

typedef enum {
    DHCP_INIT,
    DHCP_DISCOVER,
    DHCP_OFFER,
    DHCP_REQUEST,
    DHCP_ACK,
    DHCP_TIMEOUT
} DHCP_State;

DHCP_State dhcp_state = DHCP_INIT;
uint8_t dhcp_mac[6] = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56}; // 默认MAC地址

void DHCP_Init() {
    // 设置MAC地址
    setSHAR(dhcp_mac);
    
    // 配置网络模式为DHCP
    setNETINFO(NETINFO_DHCP);
    
    // 初始化DHCP定时器
    HAL_TIM_Base_Start_IT(&htim3); // 100ms定时器
}

void DHCP_Process() {
    switch(dhcp_state) {
        case DHCP_INIT:
            send_DHCP_Discover();
            dhcp_state = DHCP_DISCOVER;
            break;
            
        case DHCP_DISCOVER:
            if(receive_DHCP_Offer()) {
                dhcp_state = DHCP_OFFER;
            }
            break;
            
        case DHCP_OFFER:
            send_DHCP_Request();
            dhcp_state = DHCP_REQUEST;
            break;
            
        case DHCP_REQUEST:
            if(receive_DHCP_ACK()) {
                dhcp_state = DHCP_ACK;
                save_network_params(); // 保存IP等参数
            }
            break;
            
        case DHCP_TIMEOUT:
            // 超时处理:重试或切换模式
            break;
    }
}

3. DHCP Message Processing

// 构造DHCP Discover报文
void send_DHCP_Discover() {
    uint8_t dhcp_pkt[576] = {0};
    
    dhcp_pkt[0] = 1;    // OP: BOOTREQUEST
    dhcp_pkt[1] = 1;    // HTYPE: ETHERNET
    dhcp_pkt[2] = 6;    // HLEN: 6字节MAC
    dhcp_pkt[3] = 0;    // HOPS: 0
    
    // 填充事务ID
    memcpy(&dhcp_pkt[4], &xid, 4);
    
    // 设置客户端MAC地址
    memcpy(&dhcp_pkt[28], dhcp_mac, 6);
    
    // 设置选项字段
    dhcp_pkt[53] = 53;  // DHCP消息类型
    dhcp_pkt[54] = 1;   // 消息类型长度
    dhcp_pkt[55] = 1;   // DHCP_DISCOVER
    
    send_udp_packet(DHCP_SERVER_PORT, dhcp_pkt, 576);
}

// 解析DHCP Offer报文
void parse_dhcp_offer(uint8_t *pkt) {
    // 提取服务器IP
    server_ip[0] = pkt[16];
    server_ip[1] = pkt[17];
    server_ip[2] = pkt[18];
    server_ip[3] = pkt[19];
    
    // 提取分配IP
    assigned_ip[0] = pkt[16+2+16]; // yiaddr字段
    assigned_ip[1] = pkt[16+2+17];
    assigned_ip[2] = pkt[16+2+18];
    assigned_ip[3] = pkt[16+2+19];
}

III. Configuration Parameters

1. DHCP timeout settings

#define DHCP_TIMEOUT_MS  10000  // 总超时时间
#define DHCP_RETRY_INTERVAL 2000 // 重试间隔

volatile uint32_t dhcp_timer = 0;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if(htim->Instance == TIM3) {
        dhcp_timer += 100;
        if(dhcp_timer >= DHCP_TIMEOUT_MS) {
            dhcp_state = DHCP_TIMEOUT;
            dhcp_timer = 0;
        }
    }
}

2. Saving network parameters

uint8_t assigned_ip[4] = {0};
uint8_t subnet_mask[4] = {255,255,255,0};
uint8_t gateway_ip[4] = {192,168,1,1};

void save_network_params() {
    // 从DHCP ACK报文提取参数
    memcpy(assigned_ip, &ack_pkt[16+2+16], 4);  // yiaddr
    memcpy(subnet_mask, &ack_pkt[16+2+1], 4);   // subnet_mask
    memcpy(gateway_ip, &ack_pkt[16+2+2], 4);    // routers
}

IV. Debugging and Verification

1. Packet capture example using a logic analyzer

Time    | 操作类型      | 关键字段
---------------------------------------
0.00s   | DHCP Discover | MAC:00:08:DC:12:34:56
0.52s   | DHCP Offer    | ServerIP:192.168.1.254
0.85s   | DHCP Request  | RequestIP:192.168.1.100
1.20s   | DHCP ACK      | LeaseTime:86400s

2. Troubleshooting Common Problems

PhenomenonSolution
No DHCP responseCheck MAC address uniqueness to confirm network connectivity.
IP address conflictRestart the device or contact your network administrator.
Lease duration abnormalCheck DHCP server configuration

V. Implementation of Extended Functions

1. Static IP Switching

void set_static_ip() {
    setNETINFO(NETINFO_STATIC);
    setIPADDR(192,168,1,100);    // 设置静态IP
    setGATEWAY(192,168,1,1);     // 设置网关
    setSUBNET(255,255,255,0);    // 设置子网掩码
}

2. Supports multiple network cards

// 配置多个W5500芯片
void multi_w5500_init() {
    for(int i=0; i<MAX_W5500_NUM; i++) {
        W5500_Reset(i);          // 复位不同片选
        setSHAR(mac_addr[i]);    // 设置不同MAC
        setNETINFO(NETINFO_DHCP);// 启动DHCP
    }
}

VI. Performance Optimization

DMA Transfer : Enable SPI DMA mode to improve throughput

hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; // 10MHz
hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE; // 保持IO状态
HAL_SPI_Init(&hspi1);

Low power mode :

// 进入睡眠模式前关闭网络
WIZCHIP_CS_HIGH();
HAL_GPIO_WritePin(GPIOA, GPIO_Pin_4, GPIO_PIN_SET);
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
 

Refer to the W5500 code to implement DHCP automatic IP address acquisition function: www.youwenfan.com/contentcnk/71379.html

VII. Complete Code Structure

├── Drivers/
│   ├── W5500/
│   │   ├── w5500.c       # 底层驱动
│   │   └── w5500.h       # 寄存器定义
│   └── STM32/
│       ├── spi.c         # SPI接口实现
│       └── tim.c         # 定时器配置
├── Middlewares/
│   └── DHCP_Client/      # DHCP协议栈
│       ├── dhcp.c
│       └── dhcp.h
└── Applications/
    └── main.c            # 主程序入口
Documents
Comments Write