STM32F407+LWIP+DP83848以太网驱动移植

这篇具有很好参考价值的文章主要介绍了STM32F407+LWIP+DP83848以太网驱动移植。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  最近有个项目上需要用到网络功能,于是开始移植网络相关代码。在移植的过程中感觉好难,网上找各种资料都没有和自己项目符合的,移植废了废了好的大劲。不过现在回头看看,其实移植很简单,主要是当时刚开始接触网络,各种新的知识和概念扑面而来,加上LWIP这个协议的相关资料,一下接触的太多,大脑已经混乱了。所以就感觉很难,当各种逻辑梳理清楚的时候,移植起来就很简单了。

  下面就将我自己的经验总结一下,由于以前没有接触过网络,所以就需要一个系统的学习和了解相关知识。我是按照正点原子的资料来学习的。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  首先了解一下LWIP的相关概念,然后需要了解一下STM32以太网架构。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  这个图就是告诉我们,在STM32芯片的内部已经集成了对外部PHY芯片的驱动,如果我们要使用PHY芯片的话,就按照STM32提供的接口方式去连线就行了。

  一般单片机和芯片连接的话有两种接口,一种是MII接口,一种是RMII接口。这两种接口看不懂也无所谓,了解一下就行了。知道这个概念就行。

  目前大多数用的都是RMII接口,因为这个接口占用的IO口少。通用的连接方式如下:

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  这个图理解不了没关系,直接看电路图。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  这个是正点原子开发板上使用的LAN8720芯片的连接图,这个第一次看的话感觉也看不懂。那就继续看下面这个引脚连接框图。这个图里面除了晶振复位信号以外其他所有的信号连接都是固定的。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  也就是说,不管你使用的是什么型号的PHY芯片,也不管不使用的是STM32的那一个型号单片机。这些引脚的连接都是固定搭配的。比如PHY芯片的TX_EN信号就必须要连接STM32单片机的ETH_TH_EN引脚。PHY芯片的TXD1引脚必须要连接STM32额ETH_TXD1引脚。

  当明白了这个端口连接都是固定的话,在回头看上面的电路图和连接框图就能理解了。也就是说不管你用的PHY芯片和我用的或者其他例程上用的芯片是不是同一个型号,都没有关系,只要你使用的连接接口是RMII方式的,那么接线方式就都是这样的。

  接下来看复位信号,PHY芯片在复位的时候必须要给复位引脚给一个高低电平,来控制芯片的复位。所以PHY的复位引脚的电平就由单片机来控制。至于选择单片机哪个口,这个没有规定。自己的哪个IO口空闲就可以用哪个IO口。单片机选择的这个复位引脚在程序中只会用到一次。

    ETHERNET_RST( 0 );                                      /* 硬件复位 */
    delay_ms( 100 );
    ETHERNET_RST( 1 );                                      /* 复位结束 */

  也就是在初始化PHY芯片的时候,控制PHY的复位引脚有个电平的变化。

  可以看看我移植的代码和正点原子代码的区别。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  左边是我自己使用DP83848芯片的引脚配置,右边是正点原子使用 YT8512C芯片的引脚配置,可以看出这两个芯片只有复位引脚的连接是不一样的,其他信号的连接都是一样的。

  最后来看一下这个晶振引脚的连接,如果要使用RMII接口,那么PHY芯片和STM32芯片,都需要外面提供一个50MHz的时钟源。那么最简单的接线方式就是,外面分别接一个50MHz的晶振。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  但是这种实际应用起来明显感觉很浪费,为啥非要都各自使用一个50MHz的晶振,难道两个芯片不能用一个晶振吗?于是就将电路修改为下面这种方式。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  于是PHY芯片和STM32的时钟信号都是从外面晶振引脚直接获取的。我使用的硬件连接就是这种方式。DP83848芯片的X1引脚和STM32F407单片机的ETH_RMII_REF_CLK引脚直接接晶振的OUT引脚。

  这样使用起来挺方便的也挺好的,但是有的PHY芯片厂商又出来搞事情了,说我的PHY芯片为了帮助你降低硬件成本,外部晶振只需要25MHz就行了,我内部可以把25MHz倍频到50MHz。那么接线图就可以改成下面这种。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  PHY芯片可以外部接25MHz的晶振,内部倍频到50MHz,但是STM32没有这个功能压呀,STM32需要的50MHz频率又要去哪里找呢,难不成外部还要再接一个50MHz的晶振?这样肯定是不行的。这时候PHY芯片厂商又发话了,为了解决你们面临的这个困难,我的PHY芯片可以把内部倍频后的50MHz时钟频率输出,这样STM32就可以使用我输出的50MHz频率。

  于是晶振连接图就变成下面这个。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  上面的那张正点原子LAN8720芯片引脚连接电路图就使用的是这种连接方式。给PHY芯片外部接25MHz的晶振,然后PHY内部倍频到50MHz之后,通过CLK_OUT引脚输出,将这个输出信号在接到STM32单片机的ETH_RMII_REF_CLK引脚上,给STM32内部提供50MHz的时钟。

  不同PHY的硬件部分区别基本就这些,下面就开始移植软件,软件的代码可以直接在正点原子的例程上修改。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
  这里我就用我移植好的例子和正点原子的例子对比来说明,要修改哪些地方。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
  首先打开 stm32f4xx_hal_conf.h头文件,在这里修改晶振的值,这个晶振不是PHY芯片使用的晶振,而是STM32单片机工作时使用的外部晶振。正点原子的开发板默认使用的都是8MHz的晶振,而我自己的板子使用的是10MHz的晶振,所以这里就需要根据自己的硬件修改晶振值。

  如果晶振值进行了修改,那么下来还需要修改main.c文件中的时钟初始化函数。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
  这里需要将sys_stm32_clock_init函数的第二个参数,修改为自己的晶振值,如果你你使用的晶振是10MHz这里就改为10,如果使用的是25MHz就修改为25,这个参数的含义就是将使用的晶振分频X,使分频后的频率值为1MHz。

  接下来在 stm32f4xx_hal_conf.h头文件中修改网络芯片地址。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
  这个芯片地址是由硬件来决定的,这个可以再芯片手册上查看。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  接下来在宏定义里面添加自己的网卡型号。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

  然后添加对应型号的PHY芯片的SR寄存器相关宏定义
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
  这里需要添加3个宏定义值

#define PHY_SR                           ((uint16_t)0x10)                       /*!< tranceiver status register */
#define PHY_SPEED_STATUS                 ((uint16_t)0x0002)                     /*!< configured information of speed: 100Mbit/s */
#define PHY_DUPLEX_STATUS                ((uint16_t)0x0004)    

   PHY_SR 设置PHY芯片中SR寄存器的地址,这个地址值直接在芯片手册中看。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

   这里要顺便说一下,PHY 是由 IEEE 802.3 定义的,一般通过 SMI 对 PHY 进行管理和控制,也就是读写 PHY内部寄存器。PHY 寄存器的地址空间为 5 位,可以定义 0~31 共 32 个寄存器。IEEE 802.3定义了 0~15这 16个寄存器的功能,而 16~31寄存器由芯片制造商自由定义的。
   也就是说每个PHY芯片内部的 0号寄存器到15号寄存器的内容都是一样的,只有16号寄存器到31号寄存器的内容是厂家自己设置的。

   所以在程序移植时,代码中使用的0到15号寄存器都是一样的,我们不用管,自己需要设置的就是厂家自己定义的PHY状态寄存器的地址。

   我使用额定DP83848芯片状态寄存器的地址是0x10,所以这里宏定义就设置为0x10.

   接下来要设置PHY_SPEED_STATUS 速度状态这个值,这个值的含义就是网口的速度值读取位置。这个位置指的是在PHY_SR寄存器里面的位置。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
   这个需要在芯片手册里面去找SR寄存器的详细介绍,通过查看SR寄存器可以看出,速度状态是通过SPEED STATUS这一位读出来的,当值为1时,表示网口速度为10M,当值为0时,代表网卡速度为100M。这一位在SR寄存器中的第1位,所以值就是 0x0002,也就是在程序中读取SR寄存器的值,然后与0x0002做与运算,就能计算出SPEED STATUS位的值是0还是1,通过这个结果就能知道当前网卡的速度是多少。

   第三个需要设置的是PHY_DUPLEX_STATUS双工状态的偏移值,这个值在寄存器中第2位。

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

   当这个为1时,为全双工状态,当这个位为0时,为半双工状态。由于这个在第2位,所以值就是0x0004,从SR寄存器中读取的值和0x0004进行相与,得出的结果就能判断出当前网卡是全双工还是办双工。

   宏定义修改在这里就完了,下面开始修改代码。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

   打开 ethernet.c文件,修改ethernet_chip_get_speed()函数,这个函数的作用就是通过刚才设置的宏定义值读取网卡的速度信息。

/**
 * @breif       获得网络芯片的速度模式
 * @param       无
 * @retval      1:获取100M成功
                0:失败
 */
uint8_t ethernet_chip_get_speed( void )
{
    uint8_t speed;
#if(PHY_TYPE == LAN8720)
    speed = ~( ( ethernet_read_phy( PHY_SR ) & PHY_SPEED_STATUS ) );   /* 从LAN8720的31号寄存器中读取网络速度和双工模式 */
#elif(PHY_TYPE == SR8201F)
    speed = ( ( ethernet_read_phy( PHY_SR ) & PHY_SPEED_STATUS ) >> 13 ); /* 从SR8201F的0号寄存器中读取网络速度和双工模式 */
#elif(PHY_TYPE == YT8512C)
    speed = ( ( ethernet_read_phy( PHY_SR ) & PHY_SPEED_STATUS ) >> 14 ); /* 从YT8512C的17号寄存器中读取网络速度和双工模式 */
#elif(PHY_TYPE == RTL8201)
    speed = ( ( ethernet_read_phy( PHY_SR ) & PHY_SPEED_STATUS ) >> 1 ); /* 从RTL8201的16号寄存器中读取网络速度和双工模式 */
#elif(PHY_TYPE == DP83848)
    speed = ( ( ethernet_read_phy( PHY_SR ) & PHY_SPEED_STATUS ) >> 1 ); /* 从DP83848的16号寄存器中读取网络速度和双工模式 */
	
#endif

    return speed;
}

   在这个函数里面添加自己的PHY芯片信息,由于PHY_SPEED_STATUS这个在寄存器中第1位,所以将SR寄存器读取到的值和 PHY_SPEED_STATUS相与,然后右移一位,将结果存放在第0位。通过判断第0位的值是0还是1就可以知道网卡的速度了。PHY_DUPLEX_STATUS这个宏定义在程序中未用到。

   接下来就剩最后一步了,就是复位引脚的修改。打开 ethernet.h头文件
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
   正点原子的复位引脚用的是PD3,将这个引脚修改为自己的硬件电路实际连接引脚。我用的是PA1引脚,所以这里将复位引脚改为PA1.

stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网
   到此DP83848芯片的移植就完成了,下载程序到单片机,然后在电脑上使用ping命令测试网络是否联通。
stm32f407_dp83848_lwip移植方法,STM32学习笔记,软件技巧,FreeRTOS学习笔记,stm32,PHY,DP83848,LWIP,以太网

   最后统一总结一下移植的步骤

1.stm32f4xx_hal_conf.h 头文件 修改外部晶振大小 由8M修改为 10M
 #define HSE_VALUE    (8000000U) --->  #define HSE_VALUE    (10000000U)
 
2.main.c 修改时钟初始化函数
 sys_stm32_clock_init(336, 8, 2, 7); --->  sys_stm32_clock_init(336, 10, 2, 7);
 
3.stm32f4xx_hal_conf.h 头文件 修改网络芯片地址
 ETHERNET_PHY_ADDRESS 值由0x00 改为0x01

4.stm32f4xx_hal_conf.h 头文件增加宏定义相关代码	
#define DP83848                          4
#define PHY_TYPE                         DP83848

#elif(PHY_TYPE == DP83848) 
#define PHY_SR                           ((uint16_t)0x10)            /*!< tranceiver status register */
#define PHY_SPEED_STATUS                 ((uint16_t)0x0002)          /*!< configured information of speed: 100Mbit/s */
#define PHY_DUPLEX_STATUS                ((uint16_t)0x0004)          /*!< configured information of duplex: full-duplex */	


5. ethernet.c文件中增加网络状态判断代码
#elif(PHY_TYPE == DP83848)
    speed = ( ( ethernet_read_phy( PHY_SR ) & PHY_SPEED_STATUS ) >> 1 ); /* 从DP83848的16号寄存器中读取网络速度和双工模式 */

6.ethernet.h 头文件中修改PHY复位引脚 将PD3 改为 PA3

#define ETH_RESET_GPIO_PORT             GPIOA
#define ETH_RESET_GPIO_PIN              GPIO_PIN_3
#define ETH_RESET_GPIO_CLK_ENABLE()     do{ __HAL_RCC_GPIOI_CLK_ENABLE();}while(0)                  /* 所在IO口时钟使能 */

/* ETH端口定义 */
#define ETHERNET_RST(x)  do{ x ? \
                            HAL_GPIO_WritePin(ETH_RESET_GPIO_PORT, ETH_RESET_GPIO_PIN, GPIO_PIN_SET) : \
                            HAL_GPIO_WritePin(ETH_RESET_GPIO_PORT, ETH_RESET_GPIO_PIN, GPIO_PIN_RESET); \
                        }while(0)

   DP83848移植工程完整下载连接: DP83848网络驱动芯片在STM32F407单片机上的移植文章来源地址https://www.toymoban.com/news/detail-522192.html

到了这里,关于STM32F407+LWIP+DP83848以太网驱动移植的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于STM32F4和GD32F4以太网,LAN8720+lwip+freemodbus,实现modbus tcp

    关于STM32F4和GD32F4以太网,LAN8720+lwip+freemodbus 这里使用了大佬 小灰灰搞电子 的代码,文章看 STM32F407+LAN8720移植Lwip和freeModbus实现MODBUS TCP 代码看 STM32F407+LAN8720+LWIP移植freemodbus TCP.zip 他的代码是基于正点原子F407的板子开发的,如果是别的板子,需要修改引脚 小灰灰的代码里,没

    2024年02月14日
    浏览(30)
  • STM32H723 + DP83848 + LWIP + RT-Thread(FreeRTOS) + STM32CubeMX + Keil MDK 超详细

    MCU:STM32H723ZGT ETH PHY :DP83848 RT-Thread:RT-Thread nano 3.1.5 Software Pack:STM32CubeH7 Firmware Package V1.10.0 / 11-February-2022 STM32H723配置以太网+Freertos注意事项 STM32H723+Lwip+ETH+CUBE 完整配置(排了巨多坑!) Cube配置STM32H743+DP83848以太网工程 STM32H743+CubeMX-梳理MPU的设置 首先使用 CubeMX配置相关外

    2024年02月13日
    浏览(33)
  • STM32的以太网外设+PHY(LAN8720)使用详解(6):以太网数据接收及发送

    1.1.1 检查是否接收到一帧完整报文 使用轮询的方式接收以太网数据是一种简单但是效率低下的方法,为了保证及时处理以太网数据我们需要在主循环内高频轮询是否接收到了以太网数据。轮询的函数为ETH_CheckFrameReceived,内容如下: 当以太网帧大于我们设置的DMA描述符buffer大

    2024年01月23日
    浏览(44)
  • STM32+W5500实现以太网通信

    STM32系列32位微控制器基于Arm® Cortex®-M处理器,旨在为MCU用户提供新的开发自由度。它包括一系列产品,集高性能、实时功能、数字信号处理、低功耗/低电压操作、连接性等特性于一身,同时还保持了集成度高和易于开发的特点。本例采用STM32作为MCU。 W5500是一款全硬件TCP/

    2023年04月22日
    浏览(37)
  • STM32以太网接口的配置和使用方法详解

    STM32 微控制器提供了多种系列和型号,不同型号的芯片可能有不同的以太网接口,包括MAC(媒体访问控制器)和PHY(物理层接口)等组件。 在这里,我们以STM32F4系列为例来详细介绍以太网接口的配置和使用方法。 ✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

    2024年04月26日
    浏览(33)
  • STM32H723配置以太网+Freertos注意事项

    由于STM32H743涨价到300元以上,项目换用了Pin2Pin替换的STM32H723,看上去cpu运行速度快了20%达到550Mhz。 但是内存布局存在很大不一样,而且ST官方代码库升级迭代快,要手动修改地方每个版本不一样,在有H743的经验下,花了2天时间搞好了记录一下。很多信息来源于英文ST支持论

    2023年04月18日
    浏览(32)
  • 【STM32F1】以太网通信之UDP/TCP实验

    在本实验中,开发板主控芯片通过 SPI 接口与 CH395Q 以太网芯片进行通讯,从而完成对 CH395Q 以太网芯片的功能配置、数据接收等功能,同时将 CH395Q 以太网芯片的 Socket0 配 置为 UDP 模式,并可通过按键发送 UDP 广播数据至其他的 UDP 客户端,也能够接收其他 UDP 客户端广播的数

    2024年02月07日
    浏览(42)
  • STM32的以太网外设+PHY(LAN8720)使用详解(2):硬件设计

    在LAN8720上电或复位时会读取一些特定引脚的电平,根据电平来进行硬件配置。LAN8720的引脚分布如下: 注意,LAN8720有些引脚内部自带上/下拉,定义如下: LAN8720的PHYAD[0]用来配置PHY地址的bit0,当接入了多个PHY时可以用来区分不同的PHY。该引脚自带内部下拉,同时我们也只用到

    2024年04月14日
    浏览(57)
  • STM32+RTThread配置以太网无法ping通,无法获取动态ip的问题

    记录一个非常蠢的问题,今天在移植rtthread的以太网驱动的时候出现无法获取动态ip的问题,问题如下: 设置为动态ip时不管是连接路由器还是电脑主机都无法ping通,也无法获取dns地址。 设置为静态ip时无法ping通主机。 使用wireshark抓包,源码debug以及各种方法尝试半天后依然

    2024年02月10日
    浏览(39)
  • LwIP系列(3):以太网帧、IP、TCP、UDP、IGMP、ICMP帧格式详解

    TCP/IP 本质上是软件协议,而LwIP也是对软件协议进行解析处理,所以我们有必要了解下以太网帧、IP、TCP、UDP、IGMP、ICMP帧格式,这样在代码中,才能有的放矢。 以太网帧是最底层的原始数据,帧框架如下图所示: 其中【前同步码】和【以太网尾部】我们在抓包的时候,并不

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包