2026/2/12 4:46:34
网站建设
项目流程
网站打包成app软件,access做网站,有哪些做汽车变速箱的门户网站,微信公众号开通商城STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848这一个以太网芯片#xff0c;本人发现其配置起来比较麻烦#xff0c;所以整理了一份STM32F107单片机驱动Dp83848的程序代码例程#xff0c;方便大家学习相关代码的配置
最近在项目里折腾STM32F107和DP83848…STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848这一个以太网芯片本人发现其配置起来比较麻烦所以整理了一份STM32F107单片机驱动Dp83848的程序代码例程方便大家学习相关代码的配置最近在项目里折腾STM32F107和DP83848这对搭档这PHY芯片配置起来真是让人头大。特别是当硬件同事把原理图甩过来的时候看到那一堆MDIO/MDC信号线就预感到要掉头发。好在最后摸清了套路这里把关键代码和踩坑经验分享给大家。先说硬件接法DP83848的PHYAD0引脚决定了PHY地址。咱们板子上这个引脚接地所以PHY地址是0x00。这个地址后面配置MAC的时候要特别注意很多兄弟在这里栽跟头。STM32F107单片机驱动Dp83848以太网芯片程序 项目开发用到了Dp83848这一个以太网芯片本人发现其配置起来比较麻烦所以整理了一份STM32F107单片机驱动Dp83848的程序代码例程方便大家学习相关代码的配置上电第一步得先伺候好时钟。STM32的AHB总线时钟要开启别忘了MAC用的DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx | RCC_AHBPeriph_ETH_MAC_Rx, ENABLE);接下来是GPIO配置。以RMII接口为例注意CR寄存器要配置成50MHz模式GPIO_InitStructure.GPIO_Pin GPIO_Pin_11 | GPIO_Pin_12; // RMII_TXD0/TXD1 GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_Init(GPIOB, GPIO_InitStructure);PHY初始化这块最磨人。建议先用软件复位打个招呼uint16_t phy_status; ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_REG_BMCR, PHY_Reset); do { phy_status ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_REG_BMCR); } while (phy_status PHY_Reset); // 等复位完成然后开启自动协商这里有个坑——DP83848的自动协商完成标志位有点迟钝实测要加个延时ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_REG_BMCR, PHY_AutoNegotiation); HAL_Delay(1500); // 不睡够时间直接读状态会扑街 do { phy_status ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_REG_BMSR); } while (!(phy_status PHY_AutoNego_Complete));链路状态检测建议用中断方式。配置PHY的中断引脚接到STM32的某个EXTI// 开启链接状态变化中断 ETH_WritePHYRegister(DP83848_PHY_ADDRESS, PHY_REG_MISR, PHY_Link_Status_Interrupt); // 配置EXTI中断回调 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin PHY_INT_PIN) { uint16_t status ETH_ReadPHYRegister(DP83848_PHY_ADDRESS, PHY_REG_MISR); if(status PHY_Link_Status_Interrupt) { // 处理链接状态变化 handle_network_event(); } } }MAC层的DMA描述符配置是个精细活这里给个发送描述符的初始化示例ETH_DMADESCTypeDef *dma_tx_desc; dma_tx_desc ETH_GetDMATxDesc(); for(int i0; iTX_DESC_COUNT; i) { dma_tx_desc-Status ETH_DMATXDESC_OWN; // 告诉DMA可以接管 dma_tx_desc-Buffer1Addr (uint32_t)tx_buffer[i][0]; if(i TX_DESC_COUNT-1) { dma_tx_desc-Status | ETH_DMATXDESC_RER; // 环回配置 } dma_tx_desc (ETH_DMADESCTypeDef*)(dma_tx_desc-Buffer2NextDescAddr); }最后上主程序骨架。建议先做个链路检测再启动协议栈int main(void) { hardware_init(); phy_init(); while(1) { if(ETH_CheckLink() ETH_LINK_UP) { // 亮个绿灯表示联网成功 LED_Set(GREEN_LED, ON); // 这里跑LwIP的定时检查 ethernetif_input(gnetif); } else { LED_Toggle(RED_LED); HAL_Delay(500); } } }调试时最实用的技巧用示波器抓MDIO波形。曾经遇到读取PHYID始终为0xFFFF的问题最后发现是MAC的MDC时钟分频系数不对。STM32的ETHMACMIIAR寄存器中CR位需要根据系统时钟频率配置72MHz主频时建议设为0x1C即28分频。完整工程里还有个关键点——中断优先级配置。接收中断要设为最高优先级不然在高流量时容易丢包。这里给出NVIC配置参考HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); HAL_NVIC_EnableIRQ(ETH_IRQn);最后提醒各位DP83848的硬件复位信号至少要保持10ms低电平。曾经有兄弟偷懒用RC电路做复位结果每次上电初始化都失败改成MCU控制复位脚后才正常。