ST意法半导体
直播中

王波

8年用户 1488经验值
私信 关注
[问答]

使用stm32F407连接PHY芯片进行以太网通讯,一插网线就会进入错误中断怎么解决?

使用STM32F407连接PHY芯片进行以太网通讯,一插网线就会进入错误中断。
/**  * @brief  Ethernet DMA transfer error callback  * @param  handlerEth: ETH handler  * @retval None  */void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *handlerEth){  net_test[2]++;  if((HAL_ETH_GetDMAError(handlerEth) & ETH_DMASR_RBUS) == ETH_DMASR_RBUS)  {设备上电插入网线,这个错误中断进入好几十次上百次,然后就网络工作正常,然后再拔掉网线,再插上,又进入这个中断,有时产生这个错误后,以太网就会彻底没法接收数据,接收中断回调都不进入了,发送正常的。我抓包发现一查网线,电脑又很多数据包会发给单片机,等一会就不发了,不知道是不是这个原因。想请教一下,这个错误回调怎么处理才能避免这个情况

回帖(1)

康辅佑

2025-6-18 17:52:05

针对STM32F407连接PHY芯片插网线触发错误中断(特别是ETH_DMASR_RBUS错误)的问题,请按以下步骤排查和解决:




1. 检查RBUS错误原因


错误 ETH_DMASR_RBUS 表示接收缓冲区不可用,通常由以下原因导致:



  • DMA描述符链表未正确配置

  • 数据缓冲区地址未对齐

  • 内存访问冲突(如DMA访问非法内存)

  • PHY芯片初始化时序不稳定




2. 核心解决步骤


(1) 确保缓冲区地址对齐


STM32的ETH DMA要求缓冲区地址 4字节对齐。在描述符配置中强制对齐:


// 定义发送/接收缓冲区(确保4字节对齐)
__attribute__((aligned(4))) uint8_t Rx_Buff[ETH_RX_BUF_SIZE * ETH_RXBUFNB];
__attribute__((aligned(4))) uint8_t Tx_Buff[ETH_TX_BUF_SIZE * ETH_TXBUFNB];

(2) 检查DMA描述符链表


在ETH初始化代码中,确保描述符链表完全初始化后再启动DMA:


// 示例:HAL库中的描述符初始化(关键步骤)
heth.Init.RxDesc = &DMARxDscrTab[0]; // DMA接收描述符数组
heth.Init.TxDesc = &DMATxDscrTab[0]; // DMA发送描述符数组
HAL_ETH_Init(&heth);

// 显式配置所有描述符状态为OWNED_BY_DMA
for (int i = 0; i < ETH_RXBUFNB; i++) {
  DMARxDscrTab[i].Status = ETH_DMARXDESC_OWN;
}
HAL_ETH_Start(&heth); // 最后启动ETH

(3) 优化PHY初始化时序


在ETH初始化增加PHY软复位和延时,确保PHY稳定再插网线:


// PHY软复位(使用正确的PHY地址)
HAL_ETH_WritePHYRegister(&heth, PHY_ADDRESS, PHY_BCR, PHY_RESET);
HAL_Delay(1000); // 等待1秒复位完成

// 重启自协商
HAL_ETH_WritePHYRegister(&heth, PHY_ADDRESS, PHY_BCR, PHY_AUTONEGOTIATION);
HAL_Delay(50); // 等待自协商

// 检查PHY连接状态(可选)
uint32_t phyStatus;
HAL_ETH_ReadPHYRegister(&heth, PHY_ADDRESS, PHY_BSR, &phyStatus);
if (!(phyStatus & PHY_LINKED_STATUS)) {
  // 处理链接失败
}

(4) 错误中断处理改进


在错误回调函数中重置DMA并重建描述符,避免中断风暴:


void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) {
  if (HAL_ETH_GetDMAError(heth) & ETH_DMASR_RBUS) {
    HAL_ETH_Stop(heth);          // 停止ETH
    HAL_ETH_DMAStop(heth);        // 停止DMA
    ETH_DMAClearError(heth);      // 清除错误标志

    // 重置描述符链表(重建OWN标志)
    for (int i = 0; i < ETH_RXBUFNB; i++) {
      heth->RxDescList[i]->Status = ETH_DMARXDESC_OWN;
    }

    HAL_ETH_Start(heth);          // 重新启动ETH
  }
}



3. 硬件检查



  • 时钟配置:确保PHY的参考时钟(50MHz)由STM32或外部晶振稳定提供。

  • 复位电路:检查PHY复位引脚(RST)在上电时是否有稳定低电平脉冲。

  • 布线质量:缩短RMII接口走线长度(TX/RX/CK等),避免干扰。

  • 匹配电阻:RMII接口的TX/RX线是否串联22Ω电阻匹配阻抗。




4. 其他建议



  1. 启用PHY中断检测
    配置PHY的链接变化中断,替代轮询:
    HAL_ETH_WritePHYRegister(&heth, PHY_ADDRESS, PHY_INTERRUPT_ENABLE, PHY_LINK_CHANGE_INT);

  2. 内存管理
    如果使用动态内存,确保描述符和缓冲区位于 DTCM/SRAM1(0x20000000起始),避免DMA访问的Bank冲突。

  3. 电源噪声
    在PHY的模拟电源引脚(如AVDDH)并联10μF+0.1μF电容滤除噪声。




5. 调试流程



  1. 先断开网线,上电后检查PHY寄存器(如PHY_ID)是否能正确读写。

  2. 插入网线后,用逻辑分析仪捕捉RMII_REF_CLK和MDIO波形,确认PHY自协商是否成功。

  3. 在错误中断触发时,读取 ETH->DMASR 寄存器,检查是否有其他错误标志(如ETS、TUS)。


按照以上步骤调整后,RBUS错误应显著减少。问题通常源于DMA描述符初始化时序或PHY稳定性,请优先验证硬件复位和软件初始化流程的可靠性。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分