有人可能会问了,PHY的初始化在哪呢?其实,调用HAL\_ETH\_Init()函数的时候, HAL库就已经对我们的PHY进行初始化了,当然,每个不一样的PHY肯定是不一样的配置,所以,这就需要我们自己对PHY参数进行配置,我们开发板使用的是LAN8720A芯片,LAN8720A 复位时需要一段延时时间,这里需要定义延时时间长度,大约 5~50ms即可,驱动代码中需要获取 PHY 的速度和工作模式, LAN8720A 的R31 是特殊控制/状态寄存器,包括指示以太网速度和工作模式的状态位,所以,我们需要在stm32f4xx\_hal\_conf.h中添加我们自己的PHY配置,具体见代码清单 3‑3。
```
1 /* ############ Ethernet peripheral configuration ################# */
2
3 /* Section 1 : Ethernet peripheral configuration */
4
5 /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
6 #define MAC_ADDR0 2U
7 #define MAC_ADDR1 0U
8 #define MAC_ADDR2 0U
9 #define MAC_ADDR3 0U
10 #define MAC_ADDR4 0U
11 #define MAC_ADDR5 0U
12
13 /* Definition of the Ethernet driver buffers size and count */
14 #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE
15 /* buffer size for receive */
16 #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE
17 /* buffer size for transmit */
18 #define ETH_RXBUFNB ((uint32_t)8U)
19 /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
20 #define ETH_TXBUFNB ((uint32_t)8U)
21 /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
22
23 /* Section 2: PHY configuration section */
24
25 /* LAN8720_PHY_ADDRESS Address*/
26 #define LAN8720_PHY_ADDRESS 0U
27 /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
28 #define PHY_RESET_DELAY ((uint32_t)0x00000005U)
29 /* PHY Configuration delay */
30 #define PHY_CONFIG_DELAY ((uint32_t)0x00000005U)
31
32 #define PHY_READ_TO ((uint32_t)0x0000FFFFU)
33 #define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
34
35 /* Section 3: Common PHY Registers */
36
37 #define PHY_BCR ((uint16_t)0x00U)
38 /*!< Transceiver Basic Control Register */
39 #define PHY_BSR ((uint16_t)0x01U)
40 /*!< Transceiver Basic Status Register */
41
42 #define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
43 #define PHY_LOOPBACK ((uint16_t)0x4000U)
44 /*!< Select loop-back mode */
45 #define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U)
46 /*!< Set the full-duplex mode at 100 Mb/s */
47 #define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U)
48 /*!< Set the half-duplex mode at 100 Mb/s */
49 #define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U)
50 /*!< Set the full-duplex mode at 10 Mb/s */
51 #define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U)
52 /*!< Set the half-duplex mode at 10 Mb/s */
53 #define PHY_AUTONEGOTIATION ((uint16_t)0x1000U)
54 /*!< Enable auto-negotiation function */
55 #define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U)
56 /*!< Restart auto-negotiation function */
57 #define PHY_POWERDOWN ((uint16_t)0x0800U)
58 /*!< Select the power down mode */
59 #define PHY_ISOLATE ((uint16_t)0x0400U)
60 /*!< Isolate PHY from MII */
61
62 #define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U)
63 /*!< Auto-Negotiation process completed */
64 #define PHY_LINKED_STATUS ((uint16_t)0x0004U)
65 /*!< Valid link established */
66 #define PHY_JABBER_DETECTION ((uint16_t)0x0002U)
67 /*!< Jabber condition detected*/
68
69 /* Section 4: Extended PHY Registers */
70 #define PHY_SR ((uint16_t)0x1FU)
71 /*!< PHY status register Offset*/
72
73 #define PHY_SPEED_STATUS ((uint16_t)0x0004U)
74 /*!< PHY Speed mask */
75 #define PHY_DUPLEX_STATUS ((uint16_t)0x0010U)
76 /*!< PHY Duplex mask*/
```
- 说明
- 第1章:网络协议简介
- 1.1:常用网络协议
- 1.2:网络协议的分层模型
- 1.3:协议层报文间的封装与拆封
- 第2章:LwIP简介
- 2.1:LwIP的优缺点
- 2.2:LwIP的文件说明
- 2.2.1:如何获取LwIP源码文件
- 2.2.2:LwIP文件说明
- 2.3:查看LwIP的说明文档
- 2.4:使用vscode查看源码
- 2.4.1:查看文件中的符号列表(函数列表)
- 2.4.2:函数定义跳转
- 2.5:LwIP源码里的example
- 2.6:LwIP的三种编程接口
- 2.6.1:RAW/Callback API
- 2.6.2:NETCONN API
- 2.6.3:SOCKET API
- 第3章:开发平台介绍
- 3.1:以太网简介
- 3.1.1:PHY层
- 3.1.2:MAC子层
- 3.2:STM32的ETH外设
- 3.3:MII 和 RMII 接口
- 3.4:PHY:LAN8720A
- 3.5:硬件设计
- 3.6:软件设计
- 3.6.1:获取STM32的裸机工程模板
- 3.6.2:添加bsp_eth.c与bsp_eth.h
- 3.6.3:修改stm32f4xx_hal_conf.h文件
- 第4章:LwIP的网络接口管理
- 4.1:netif结构体
- 4.2:netif使用
- 4.3:与netif相关的底层函数
- 4.4:ethernetif.c文件内容
- 4.4.1:ethernetif数据结构
- 4.4.2:ethernetif_init()
- 4.4.3:low_level_init()
- 第5章:LwIP的内存管理
- 5.1:几种内存分配策略
- 5.1.1:固定大小的内存块
- 5.1.2:可变长度分配
- 5.2:动态内存池(POOL)
- 5.2.1:内存池的预处理
- 5.2.2:内存池的初始化
- 5.2.3:内存分配
- 5.2.4:内存释放
- 5.3:动态内存堆
- 5.3.1:内存堆的组织结构
- 5.3.2:内存堆初始化
- 5.3.3:内存分配
- 5.3.4:内存释放
- 5.4:使用C库的malloc和free来管理内存
- 5.5:LwIP中的配置
- 第6章:网络数据包
- 6.1:TCP/IP协议的分层思想
- 6.2:LwIP的线程模型
- 6.3:pbuf结构体说明
- 6.4:pbuf的类型
- 6.4.1:PBUF_RAM类型的pbuf
- 6.4.2:PBUF_POOL类型的pbuf
- 6.4.3:PBUF_ROM和PBUF_REF类型pbuf
- 6.5:pbuf_alloc()
- 6.6:pbuf_free()
- 6.7:其它pbuf操作函数
- 6.7.1:pbuf_realloc()
- 6.7.2:pbuf_header()
- 6.7.3:pbuf_take()
- 6.8:网卡中使用的pbuf
- 6.8.1:low_level_output()
- 6.8.2:low_level_input()
- 6.8.3:ethernetif_input()
- 第7章:无操作系统移植LwIP
- 7.1:将LwIP添加到裸机工程
- 7.2:移植头文件
- 7.3:移植网卡驱动
- 7.4:LwIP时基
- 7.5:协议栈初始化
- 7.6:获取数据包
- 7.6.1:查询方式
- 7.6.2:ping命令详解
- 7.6.3:中断方式
- 第8章:有操作系统移植LwIP
- 8.1:LwIP中添加操作系统
- 8.1.1:拷贝FreeRTOS源码到工程文件夹
- 8.1.2:添加FreeRTOS源码到工程组文件夹
- 8.1.3:指定FreeRTOS头文件的路径
- 8.1.4:修改stm32f10x_it.c
- 8.2:lwipopts.h文件需要加入的配置
- 8.3:sys_arch.c/h文件的编写
- 8.4:网卡底层的编写
- 8.5:协议栈初始化
- 8.6:移植后使用ping测试基本响应
- 第9章:LwIP一探究竟
- 9.1:网卡接收数据的流程
- 9.2:内核超时处理
- 9.2.1:sys_timeo结构体与超时链表
- 9.2.2:注册超时事件
- 9.2.3:超时检查
- 9.3:tcpip_thread线程
- 9.4:LwIP中的消息
- 9.4.1:消息结构
- 9.4.2:数据包消息
- 9.4.3:API消息
- 9.5:揭开LwIP神秘的面纱
- 第10章:ARP协议
- 10.1:链路层概述
- 10.2:MAC地址的基本概念
- 10.3:初识ARP
- 10.4:以太网帧结构
- 10.5:IP地址映射为物理地址
- 10.6:ARP缓存表
- 10.7:ARP缓存表的超时处理
- 10.8:ARP报文
- 10.9:发送ARP请求包
- 10.10:数据包接收流程
- 10.10.1:以太网之数据包接收
- 10.10.2:ARP数据包处理
- 10.10.3:更新ARP缓存表
- 10.11:数据包发送流程
- 10.11.1:etharp_output()函数
- 10.11.2:etharp_output_to_arp_index()函数
- 10.11.3:etharp_query()函数
- 第11章:IP协议
- 11.1:IP地址.md
- 11.1.1:概述
- 11.1.2:IP地址编址
- 11.1.3:特殊IP地址