LAN9252 从机模式寄存器配置代码示例
LAN9252 是 Microchip 推出的工业级 EtherCAT 控制器,从机模式(Slave Mode)是其核心应用场景之一。以下代码基于STM32 单片机(主流工控平台),采用 SPI 通信方式(LAN9252 与主控的常用通信接口),实现从机模式核心寄存器的配置,代码具备可移植性,适配大部分 MCU 平台。
一、核心配置思路
- 初始化 SPI 通信(LAN9252 与主控的通信链路);
- 复位 LAN9252 并等待硬件就绪;
- 配置核心寄存器:从机模式使能、通信参数(波特率 / 帧格式)、中断使能、状态寄存器等;
- 验证配置结果,确保从机模式生效。
二、完整代码示例
#include "stm32f4xx_hal.h"
// ************************** 硬件宏定义 **************************
// LAN9252 片选引脚(根据实际硬件修改)
#define LAN9252_CS_PIN GPIO_PIN_0
#define LAN9252_CS_PORT GPIOA
// LAN9252 核心寄存器地址(参考 LAN9252 数据手册)
#define LAN9252_REG_CTRL 0x0000 // 控制寄存器
#define LAN9252_REG_MODE 0x0004 // 模式寄存器
#define LAN9252_REG_BAUDRATE 0x0008 // 波特率配置寄存器
#define LAN9252_REG_INT_EN 0x000C // 中断使能寄存器
#define LAN9252_REG_STATUS 0x0010 // 状态寄存器
#define LAN9252_REG_SLAVE_CFG 0x0014 // 从机模式配置寄存器
// SPI 句柄(需在外部初始化,如 main.c 中)
extern SPI_HandleTypeDef hspi1;
// ************************** 基础函数 **************************
/**
* @brief LAN9252 片选使能
*/
static void LAN9252_CS_Enable(void)
{
HAL_GPIO_WritePin(LAN9252_CS_PORT, LAN9252_CS_PIN, GPIO_PIN_RESET);
}
/**
* @brief LAN9252 片选失能
*/
static void LAN9252_CS_Disable(void)
{
HAL_GPIO_WritePin(LAN9252_CS_PORT, LAN9252_CS_PIN, GPIO_PIN_SET);
}
/**
* @brief 向 LAN9252 寄存器写入数据
* @param reg_addr: 寄存器地址(16位)
* @param data: 写入的数据(32位,LAN9252 寄存器为32位宽)
* @retval HAL_StatusTypeDef: 通信状态
*/
HAL_StatusTypeDef LAN9252_WriteReg(uint16_t reg_addr, uint32_t data)
{
HAL_StatusTypeDef ret;
uint8_t tx_buf[6];
// 帧格式:[写命令(0x00)][地址高8位][地址低8位][数据高8位][数据中8位][数据低8位]
tx_buf[0] = 0x00;
tx_buf[1] = (reg_addr >> 8) & 0xFF;
tx_buf[2] = reg_addr & 0xFF;
tx_buf[3] = (data >> 16) & 0xFF;
tx_buf[4] = (data >> 8) & 0xFF;
tx_buf[5] = data & 0xFF;
LAN9252_CS_Enable();
ret = HAL_SPI_Transmit(&hspi1, tx_buf, 6, 100); // 超时100ms
LAN9252_CS_Disable();
return ret;
}
/**
* @brief 从 LAN9252 寄存器读取数据
* @param reg_addr: 寄存器地址(16位)
* @param p_data: 读取的数据缓冲区(32位)
* @retval HAL_StatusTypeDef: 通信状态
*/
HAL_StatusTypeDef LAN9252_ReadReg(uint16_t reg_addr, uint32_t *p_data)
{
HAL_StatusTypeDef ret;
uint8_t tx_buf[3];
uint8_t rx_buf[3];
if (p_data == NULL) return HAL_ERROR;
// 帧格式:[读命令(0x01)][地址高8位][地址低8位]
tx_buf[0] = 0x01;
tx_buf[1] = (reg_addr >> 8) & 0xFF;
tx_buf[2] = reg_addr & 0xFF;
LAN9252_CS_Enable();
// 发送读命令和地址
ret = HAL_SPI_Transmit(&hspi1, tx_buf, 3, 100);
if (ret != HAL_OK)
{
LAN9252_CS_Disable();
return ret;
}
// 接收32位数据(分3字节读取,高位在前)
ret = HAL_SPI_Receive(&hspi1, rx_buf, 3, 100);
LAN9252_CS_Disable();
if (ret == HAL_OK)
{
*p_data = ((uint32_t)rx_buf[0] << 16) | ((uint32_t)rx_buf[1] << 8) | rx_buf[2];
}
return ret;
}
// ************************** 从机模式配置核心函数 **************************
/**
* @brief LAN9252 从机模式初始化配置
* @retval uint8_t: 0-成功,1-失败
*/
uint8_t LAN9252_SlaveMode_Init(void)
{
uint32_t reg_data;
HAL_StatusTypeDef ret;
// 步骤1:复位 LAN9252(写控制寄存器,置位复位位)
ret = LAN9252_WriteReg(LAN9252_REG_CTRL, 0x00000001);
if (ret != HAL_OK) return 1;
// 等待复位完成(状态寄存器复位位清零,最多等待100ms)
uint32_t timeout = 100;
do {
ret = LAN9252_ReadReg(LAN9252_REG_STATUS, ®_data);
if (ret != HAL_OK) return 1;
HAL_Delay(1);
timeout--;
} while ((reg_data & 0x00000001) && timeout > 0);
if (timeout == 0) return 1; // 复位超时
// 步骤2:配置模式寄存器(从机模式使能)
// 位定义(参考手册):
// bit0: 模式选择(0-主机,1-从机)
// bit1: 帧格式(0-标准帧,1-扩展帧)
// bit2: 校验使能(0-禁用,1-使能)
reg_data = 0x00000005; // 从机模式 + 标准帧 + 校验使能
ret = LAN9252_WriteReg(LAN9252_REG_MODE, reg_data);
if (ret != HAL_OK) return 1;
// 步骤3:配置波特率(根据实际需求,示例为 1Mbps)
// 波特率计算公式:BAUDRATE = (系统时钟 / 目标波特率) - 1
// 假设 LAN9252 系统时钟为 16MHz,1Mbps 对应值为 15
reg_data = 0x0000000F;
ret = LAN9252_WriteReg(LAN9252_REG_BAUDRATE, reg_data);
if (ret != HAL_OK) return 1;
// 步骤4:配置从机模式专用参数
// bit0: 从机地址使能(1-使能)
// bit1-7: 从机地址(示例为 0x01)
// bit8: 自动应答使能(1-使能)
reg_data = 0x00000101; // 从机地址0x01 + 地址使能 + 自动应答使能
ret = LAN9252_WriteReg(LAN9252_REG_SLAVE_CFG, reg_data);
if (ret != HAL_OK) return 1;
// 步骤5:使能中断(接收完成/发送完成/错误中断)
reg_data = 0x00000007; // 使能接收完成 + 发送完成 + 错误中断
ret = LAN9252_WriteReg(LAN9252_REG_INT_EN, reg_data);
if (ret != HAL_OK) return 1;
// 步骤6:验证配置(读取模式寄存器,确认从机模式生效)
ret = LAN9252_ReadReg(LAN9252_REG_MODE, ®_data);
if (ret != HAL_OK || (reg_data & 0x01) != 0x01)
{
return 1;
}
return 0; // 配置成功
}
// ************************** 调用示例(main.c) **************************
/*
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init(); // 初始化 SPI1(需配置为 CPOL=0, CPHA=0,匹配 LAN9252 时序)
// 初始化 LAN9252 从机模式
if (LAN9252_SlaveMode_Init() == 0)
{
// 配置成功,后续可处理数据收发
}
else
{
// 配置失败,需排查硬件/通信问题
}
while (1)
{
// 业务逻辑
}
}
*/
三、代码关键说明
- 通信接口:示例采用 SPI 通信,需确保 SPI 时序与 LAN9252 匹配(默认 CPOL=0、CPHA=0),片选引脚需根据硬件原理图修改;
- 寄存器地址:需严格参考 LAN9252 官方数据手册,不同版本手册寄存器地址可能略有差异;
- 波特率配置:计算公式需结合 LAN9252 实际系统时钟(常见为 16MHz/24MHz),示例中 16MHz 时钟对应 1Mbps 波特率;
- 复位等待:必须等待复位完成后再配置寄存器,避免配置失效;
- 配置验证:读取关键寄存器(如模式寄存器)确认配置生效,是工业级应用的必要步骤。
四、前置条件
- 硬件:STM32 与 LAN9252 正确接线(SPI_SCK/SPI_MOSI/SPI_MISO/CS/ 复位 / 中断);
- 软件:已初始化 STM32 的 SPI 外设、GPIO 外设(片选引脚);
- 依赖:需包含 STM32 HAL 库(或其他 MCU 对应的底层库)。
总结
- LAN9252 从机模式配置核心是模式寄存器(0x0004)置位从机位,并配套配置波特率、从机地址、中断等参数;
- SPI 通信需严格遵循 LAN9252 的帧格式(写命令 0x00、读命令 0x01,地址 + 数据分段传输);
- 配置后必须验证关键寄存器值,确保从机模式生效,避免硬件异常导致配置失效。