STM32CubeIDE1.9.0\STM32CubeMX 6.5 F429IGT6加LAN8720A,配置ETH+LWIP
前段时间配置的F107系列和F7的LWIP功能,很顺利,但是到了F4系列,选择ETH之后没有PHY地址了,查了一下,MX 6.5有大改动,整理了一下各路大神的各种方法,配出来一个可以用的,我这里以Cubeide为例
Cube配置的时候各个外设选择生成各自的.c .h 规整不少
一些通用的SYS RCC啥的就不说了,开个串口,配置好printf函数备用
1、硬件配置
这里使用原子的开发板,F429IGT6+LAN8720A,复位引脚接在PCF8574的第七个口,引脚接口:
PC1 ------> ETH_MDCPA1 ------> ETH_REF_CLKPA2 ------> ETH_MDIOPA7 ------> ETH_CRS_DVPC4 ------> ETH_RXD0PC5 ------> ETH_RXD1PB11 ------> ETH_TX_ENPG13 ------> ETH_TXD0PG14 ------> ETH_TXD1
PCF8574的IIC接口
PH4 ------> I2C2_SCLPH5 ------> I2C2_SDA
2、PCF8574程序与配置
2、1IIC配置
通讯速率应该不能太高,我试的这个速率可以
2、2 PCF8574程序
/**********************
文件名:PCF8574.c
-------------------------------------------------------------
使用说明:
1、IIC IO扩展芯片
2、使用
PCF8574_WriteBit(0, IO_Sta%2);
IO_Sta++;
3、需要初始化IIC,并使用单独文件
4、ETH:PCF8574_WriteBit(7,1);//硬件复位LAN8720HAL_Delay(50);PCF8574_WriteBit(7,0);//结束复位
------------------------------------------------------------
-------------------------------------------------------------
运行环境:
------------------------------------------------------------
版本:1.0
作者:GPY
时间:2022-Jun 8, 2022-3:24:56 PM
描述:
全局变量:无
函数:外部函数:
********************************/
#include "PCF8574.h"
#include "i2c.h" #ifdef __STM32F4xx_HAL_I2C_Hvoid PCF8574_WriteBit(uint8_t IO_Num,uint8_t IO_Sta)
{uint8_t IO_Sta_Get[2]={0};HAL_I2C_Master_Receive(&hi2c2, 0x40, IO_Sta_Get, 1, 1000);if(IO_Sta==0)//清零{IO_Sta_Get[0]=IO_Sta_Get[0]&(~(1<<IO_Num)); }else{IO_Sta_Get[0]=IO_Sta_Get[0]|(1<<IO_Num);}HAL_I2C_Master_Transmit(&hi2c2, 0x40, IO_Sta_Get, 1, 1000);
}uint8_t PCF8574_ReadBit(uint8_t IO_Num)
{uint8_t IO_Sta_Get[2]={0};HAL_I2C_Master_Receive(&hi2c2, 0x40, IO_Sta_Get, 1, 1000);return IO_Sta_Get[0];
}#endif
/**********************
文件名:PCF8574.h
-------------------------------------------------------------
使用说明:
1、IIC IO扩展芯片
2、使用
PCF8574_WriteBit(0, IO_Sta%2);
IO_Sta++;
3、需要初始化IIC,并使用单独文件
4、ETH:PCF8574_WriteBit(7,1);//硬件复位LAN8720HAL_Delay(50);PCF8574_WriteBit(7,0);//结束复位
------------------------------------------------------------
-------------------------------------------------------------
运行环境:
------------------------------------------------------------
版本:1.0
作者:GPY
时间:2022-Jun 8, 2022-3:24:44 PM
描述:
全局变量:无
函数:外部函数:
********************************/
//#include "PCF8574.h"
#ifndef PCF8574_H_
#define PCF8574_H_#include "main.h"#ifdef __STM32F4xx_HAL_I2C_Hvoid PCF8574_WriteBit(uint8_t IO_Num,uint8_t IO_Sta);
uint8_t PCF8574_ReadBit(uint8_t IO_Num);#endif#endif /* PCF8574_H_ */
2、3 PCF8574使用
ETH引脚初始化完成后加上
在ethernetif.c文件的 HAL_ETH_MspInit
/* USER CODE BEGIN ETH_MspInit 1 */PCF8574_WriteBit(7,1);//硬件复位LAN8720HAL_Delay(50);PCF8574_WriteBit(7,0);//结束复位/* USER CODE END ETH_MspInit 1 */
3、ETH配置
这里使用LAN8720A 可以直接用LAN8742 一样的寄存器描述
原本这个界面是有个PHY地址的,新版本没了,这个不影响
直接用LAN8742A,下面的不用动。
中断可以开,也可以不开,建议勾上,检查一下IO ETH_TXD0,EYH_TXD1有可能不对,像这里就是用的PG13 PG14,速度全部默认最高
4、LWIP 配置
这里讲究的比较多
很多基本是默认,这里为了防止有遗漏,我把所有界面都留一下
这个我一直不开,看他们都是这样的,没研究过
驱动直接选LAN8742
然后就是需要注意的地方,首先去掉硬件校验
只去掉下面两个使能就行,直接去掉第一个后面就跟着变了
回到上面Key options那部分,
这里默认不是这个值,原来是0x30开头的,据说的从H7移植的工程,这个地址是外部扩展的地址,直接用会提示,但是我在这里改了没啥效果,需要在main重新定义一遍
Assertion "netif is not up, old style port?" failed at line 744 in ../Middlewares/Third_Party/LwIP/src/core/ipv4/dhcp.c
配置方面应该就这些,后面一些改动的程序
PS:修改,这个问题和下面DHCP提示"netif is not up, old style port?" 只有程序刚下完的时候有,复位就没了,不知道为什么不稳定。
5、程序改动
1、重定义PHY地址
由于cube配置界面没有地址,然后他还自己给LAN8742定了一个地址 1u,如果你的不是1 可以重定义一下,LWIP_RAM_HEAP_POINTER 也可以在这里重新定义一下
int main(void)
{/* USER CODE BEGIN 1 *///重定义PHY地址
#ifdef LAN8742A_PHY_ADDRESS
#undef LAN8742A_PHY_ADDRESS
#define LAN8742A_PHY_ADDRESS 0U
#endif#ifdef LWIP_RAM_HEAP_POINTER
#undef LWIP_RAM_HEAP_POINTER
#define LWIP_RAM_HEAP_POINTER 0x2000E378
#endif uint32_t regvalue;/* USER CODE END 1 */
ethernetif.c文件里加一下LAN8720A的复位
void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(ethHandle->Instance==ETH){/* USER CODE BEGIN ETH_MspInit 0 *//* USER CODE END ETH_MspInit 0 *//* Enable Peripheral clock */__HAL_RCC_ETH_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOG_CLK_ENABLE();/**ETH GPIO ConfigurationPC1 ------> ETH_MDCPA1 ------> ETH_REF_CLKPA2 ------> ETH_MDIOPA7 ------> ETH_CRS_DVPC4 ------> ETH_RXD0PC5 ------> ETH_RXD1PB11 ------> ETH_TX_ENPG13 ------> ETH_TXD0PG14 ------> ETH_TXD1*/GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF11_ETH;HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);/* Peripheral interrupt init */HAL_NVIC_SetPriority(ETH_IRQn, 0, 0);HAL_NVIC_EnableIRQ(ETH_IRQn);/* USER CODE BEGIN ETH_MspInit 1 */PCF8574_WriteBit(7,1);//硬件复位LAN8720HAL_Delay(50);PCF8574_WriteBit(7,0);//结束复位/* USER CODE END ETH_MspInit 1 */}
}
lwipopts.h 加一下调试信息,这个很有用
/* USER CODE BEGIN 1 */
#define LWIP_DEBUG 1
#if LWIP_DEBUG
#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
/* USER CODE BEGIN 1 */
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_OFF
//#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_WARNING
//#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_SERIOUS
//#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_SEVERE#define LWIP_DBG_TYPES_ON LWIP_DBG_ON
//#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH)#define ETHARP_DEBUG LWIP_DBG_ON
#define NETIF_DEBUG LWIP_DBG_ON
#define PBUF_DEBUG LWIP_DBG_ON
#define API_LIB_DEBUG LWIP_DBG_ON
#define API_MSG_DEBUG LWIP_DBG_ON
#define SOCKETS_DEBUG LWIP_DBG_ON
#define ICMP_DEBUG LWIP_DBG_ON
#define IGMP_DEBUG LWIP_DBG_ON
#define INET_DEBUG LWIP_DBG_ON
#define IP_DEBUG LWIP_DBG_ON
#define IP_REASS_DEBUG LWIP_DBG_ON
#define RAW_DEBUG LWIP_DBG_ON
#define MEM_DEBUG LWIP_DBG_ON
#define MEMP_DEBUG LWIP_DBG_ON
#define SYS_DEBUG LWIP_DBG_ON
#define TCP_DEBUG LWIP_DBG_ON
#define TCP_INPUT_DEBUG LWIP_DBG_ON
#define TCP_FR_DEBUG LWIP_DBG_ON
#define TCP_RTO_DEBUG LWIP_DBG_ON
#define TCP_CWND_DEBUG LWIP_DBG_ON
#define TCP_WND_DEBUG LWIP_DBG_ON
#define TCP_OUTPUT_DEBUG LWIP_DBG_ON
#define TCP_RST_DEBUG LWIP_DBG_ON
#define TCP_QLEN_DEBUG LWIP_DBG_ON
#define UDP_DEBUG LWIP_DBG_ON
#define TCPIP_DEBUG LWIP_DBG_ON
#define PPP_DEBUG LWIP_DBG_ON
#define SLIP_DEBUG LWIP_DBG_ON
#define DHCP_DEBUG LWIP_DBG_ON
#define AUTOIP_DEBUG LWIP_DBG_ON
#define SNMP_MSG_DEBUG LWIP_DBG_ON
#define SNMP_MIB_DEBUG LWIP_DBG_ON
#define DNS_DEBUG LWIP_DBG_ON
#endif //LWIP_DEBUG
/* USER CODE END 1 */
main函数里加一下 MX_LWIP_Process();
while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */MX_LWIP_Process();if (TIM_N_10ms > 50){TIM_N_10ms = 0;HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);}}
基本就结束了,我这里还有个问题,使用DHCP自动获取IP的时候,如果不打印调试信息会获取不到IP,这个可能和重试时间有关系,现象和与LAN8720A通信失败一样的,后续我再研究一下。
常见的错误提示
Assertion "netif is not up, old style port?" failed at line 744 in ../Middlewares/Third_Party/LwIP/src/core/ipv4/dhcp.c
如果DHCP自动获取IP老提示你是不是旧版设备,可以先用静态IP
6、 ETH调试技巧
最近一直在搞LWIP各种移植,虽然一直失败,但是看别人的例子,只要运行环境没问题,LWIP库移植时没难度的,我也试过移植成功之后的程序只换Lwip库 也没错误。主要就是PHY接口一定要调通,也就是硬件接口,这里提供一种验证PHY硬件是否调通的方法
首先是HAL库,直接读取LAN8720A的各个寄存器,如果你没调好,所有寄存器的返回值都会使0XFFFF或者0x0000
printf("F429IG LWIP LAN8720A %s\r\n", __TIME__);printf("LAN8742A_PHY_ADDRESS %d \r\n", LAN8742A_PHY_ADDRESS);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, PHY_BCR, ®value);printf("PHY_BCR %d: %X\r\n", PHY_BCR, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, PHY_BSR, ®value);printf("PHY_BSR %d: %X\r\n", PHY_BSR, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 2, ®value);printf("PHY 1 %d: %X\r\n", 2, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 3, ®value);printf("PHY2 %d: %X\r\n", 3, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 4, ®value);printf(" %d: %X\r\n", 4, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 5, ®value);printf(" %d: %X\r\n", 5, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 6, ®value);printf(" %d: %X\r\n", 6, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 17, ®value);printf(" %d: %X\r\n", 17, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 18, ®value);printf(" %d: %X\r\n", 18, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 26, ®value);printf(" %d: %X\r\n", 26, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 27, ®value);printf(" %d: %X\r\n", 27, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 29, ®value);printf(" %d: %X\r\n", 29, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 30, ®value);printf(" %d: %X\r\n", 30, (unsigned int) regvalue);HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 31, ®value);printf(" %d: %X\r\n-------------------------------------------\r\n", 31,(unsigned int) regvalue);
旧版本的F1
printf("-------------------------------------\r\n");regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, PHY_BCR);printf("PHY_BCR %d;%X\r\n",PHY_BCR,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, PHY_BSR);printf("PHY_BSR %d;%X\r\n",PHY_BSR,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 2);printf("%d;%X\r\n",2,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 3);printf("%d;%X\r\n",3,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 4);printf("%d;%X\r\n",4,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 5);printf("%d;%X\r\n",5,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 6);printf("%d;%X\r\n",6,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 17);printf("%d;%X\r\n",17,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 18);printf("%d;%X\r\n",18,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 26);printf("%d;%X\r\n",26,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 27);printf("%d;%X\r\n",27,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 29);printf("%d;%X\r\n",29,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 30);printf("%d;%X\r\n",30,regvalue);regvalue=ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, 31);printf("%d;%X\r\n",31,regvalue);
STM32CubeIDE1.9.0\STM32CubeMX 6.5 F429IGT6加LAN8720A,配置ETH+LWIP相关推荐
- 基于iSroll 5.0实现的上拉加载和下拉刷新插件
Updownload.js 基于iSroll 5.0实现的上拉加载和下拉刷新插件 移动端效果比较好,开发者工具打开后,需要刷新下页面. [演示地址:] https://chenyk2016.githu ...
- 数仓(十)从0到1简单搭建加载数仓DWS层
数仓(一)简介数仓,OLTP和OLAP 数仓(二)关系建模和维度建模 数仓(三)简析阿里.美团.网易.恒丰银行.马蜂窝5家数仓分层架构 数仓(四)数据仓库分层 数仓 (五) 元数据管理系统解析 数仓( ...
- “存储区更新、插入或删除语句影响到以外的行数(0)。实体在加载后可能被修改或删除”如何解决
做项目的时候,我们的try... catch语句捕捉到这种异常,我们该如何解决呢? 之所以出现这样的异常,是因为我们用实体对象在接收页面的参数时,并没有接收到实体对象的主键,所以我们要在视图那里获取到 ...
- 大话PHP设计模式:类自动载入、PSR-0规范、链式操作、11种面向对象设计模式实现和使用、OOP的基本原则和自动加载配置...
一.类自动载入 SPL函数 (standard php librarys) 类自动载入,尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_registe ...
- Windows PE 第十章 加载配置信息
加载配置信息 加载配置信息最初最用在Windows NT操作系统中,作为文件头部的延伸部分,后来被用作异常处理.加载配置信息表中存放了基于结构化异常处理(SEH)技术的各项异常句柄.当程序运行发生异常 ...
- PE学习(十)第十章: 加载配置信息表
第十章:加载配置信息 加载配置信息表最初是用来存放附加信息,后来用来存放SEH各种导演句柄变成"异常处理表" 异常与中断类似,中断有点外部(键盘)发出,异常由软件,异常发生时跑到异 ...
- 【Nginx】Nginx配置文件参数/启动参数详解;启动/停止/重新加载配置命令
nginx配置文件 nginx及其模块的工作方式是由配置文件指定,默认情况下配置文件被命名为nginx.conf并且存放在/usr/local/nginx/conf或者 /etc/nginx或者 /u ...
- springboot 读取配置文件_使用 @ConfigurationProperties 在 Spring Boot 中加载配置
本文地址: 使用 @ConfigurationProperties 在 Spring Boot 中加载配置 使用 Spring Boot 加载配置文件的配置非常便利,我们只需要使用一些注解配置一下就能 ...
- Apache 2.0性能优化—MPM的选择与配置
Apache 2.0性能优化-MPM的选择与配置 谈到Apache,大多数系统管理员对其稳定版1.3印象颇深.虽然Apache 2.0的系列开发版早已由Alpha.Beta发展到现在的GA(Gener ...
最新文章
- 图像处理怎么学matlab,Matlab数字图像处理学习(1)-亮度变换
- python decode hex_在python2.7中使用b64decode()将base64转换为hex
- 如何提取SAP UI5应用的技术信息
- 第二周web作业1:简单的注册表单
- Boost学习之正则表达式--regex
- 第二届360杯全国大学生信息安全技术大赛部分解题思路(加密解密题)
- Kubernetes 竞争条件漏洞的发现过程简述
- 实体框架 6.0:异步、IQueryable操作符和特性改进
- 软考网络工程师笔记-分值分布
- 《数字图像处理 第三版》(冈萨雷斯)——第十章 图像分割
- java set方法_Set的常用方法(java)
- Vscode(arduino框架) 开发ESP32 _01_电容Touch和外部中断
- 运用计算机制作多媒体作品,计算机多媒体技术在影视后期制作中的应用
- JavaScript,setTimeout的使用案例
- 如何使用轻量应用服务器自带的Cloudreve应用镜像搭建属于自己的云网盘?
- EXCEL VBA案例教程-李立宗-专题视频课程
- SSM中监听器调用service层空指针异常
- java 枚举型 默认值,c# - 选择Enum类型的默认值而不必更改值
- node.js+uni计算机毕设项目基于微信小程序的车位共享系统LWPPT(程序+小程序+LW)
- IP地址、子网掩码、默认网关、DNS服务器是什么?
热门文章
- bluestacks安装安卓引擎时出现2502 2503错误的解决办法
- SOA标准之----JBI架构思想
- [Phonegap+Sencha Touch] 移动开发12 Sencha Touch打包发布网站的离线缓存版本
- Qt 多线程显示gif动态图
- 2006国家温室气体清单指南 中文PDF
- 考虑温度影响的自适应扩展卡尔曼滤波估计电池SOC
- AtCoder Regular Contest 题解
- Python计算两个时间序列的互相关
- 远行星号java 出错_按照教程搞了一条新船,但是出错了,求大神看看怎么回事...
- 编程随想篇(2018夏)