踩了好几个大坑终于出来了!!!
目录
写在前边几个重要的点
reset引脚问题
如果你也用的最新版阿波罗429,那很有可能你的以太网芯片是YT8512C,而不是LAN8720A,这两者之间在代码层面最大的不同可能就是RESET的高低电平顺序不一样。
某点原子官方HAL_ETH_MspInit()初始化代码:
旧板卡(LAN8720A)引脚复位:
pcf8574_write_bit(ETH_RESET_IO,1); /* 硬件复位 */
delay_ms(100);
pcf8574_write_bit(ETH_RESET_IO,0); /* 复位结束 */
delay_ms(100);
新板卡(YT8512C)引脚复位:
pcf8574_write_bit(ETH_RESET_IO,0); /* 硬件复位 */
delay_ms(100);
pcf8574_write_bit(ETH_RESET_IO,1); /* 复位结束 */
delay_ms(100);
可以看到正好是反过来的。如果你反复实验ping不通,那很有可能就是这的问题
cubemx新旧版不同问题:
cubumx 6.4的ETH模块有Advanced选项,但是目前最新版取消了这个选项,不过不用担心,不需要回退cubemx版本,直接使用cubeide最新版也可以配置成功!
未配置lwip选项中的Platform Settings
平台设置要选择LAN8742,LAN8720和YT8512C都可以使用
电脑与开发板都需要禁用DHCP,并处于统一网段
比如电脑的IP地址为192.168.0.131,那么开发板的IP则可以配置为192.168.1.132,192.168.1.133等等,如果没有ping通请检查是否是这一环节出问题了。
更改ip请参考:
Win 11系统j将默认IP地址修改为静态IP,并成功连接上网 - 七月安生里 - 博客园 (cnblogs.com)
CubeIDE新建工程与配置
新建工程
RCC与SYS配置
时钟配置
USART配置
I2C配置
I2C是给ETH_REST用的,F429使用PCF8574来控制以太网复位引脚,所以要配置I2C,根据原理图,SDA是PH5,SCAL是PH4。
更改I2C参数
ETH配置
更改ETH_TXD0和ETH_TXD01引脚
根据原理图,ETH_TXD0对应PG13,ETH_TXD1对应PG14
LWIP配置
配置平台
关闭DHCP以及设置IP地址
首先要根据自己的电脑IP来设置开发版IP
win+R输入CMD打开CMD,然后输入
ipconfig /all
内容会很多,你只需要关注你用的就行,如果你使用以太网上网就关注以太网那块,WLAN就关注WLAN
然后更改开发板IP
大功告成,Ctrl+S保存退出。
配置代码
向工程里添加PCF8574.c和PCF8574.h。
添加PCF8574.c
将PCF8574.c自动生成的注释删掉添加如下代码
/**********************
文件名:PCF8574.c
-------------------------------------------------------------
使用说明:
1、IIC IO扩展芯片
2、使用
PCF8574_WriteBit(0, IO_Sta%2);
IO_Sta++;
3、需要初始化IIC,并使用单独文件
4、ETH:
PCF8574_WriteBit(7,1);//硬件复位LAN8720
HAL_Delay(50);
PCF8574_WriteBit(7,0);//结束复位
------------------------------------------------------------
-------------------------------------------------------------
运行环境:
------------------------------------------------------------
版本:1.0
作者:GPY
时间:2022-Jun 8, 2022-3:24:56 PM
描述:
全局变量:无
函数:
外部函数:
********************************/
#include "PCF8574.h"
//#include "main.h"
#include "stm32f4xx_hal_i2c.h"
#ifdef __STM32F4xx_HAL_I2C_H
extern I2C_HandleTypeDef hi2c2;
void 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
将PCF8574.h自动生成的注释删掉添加如下代码
/**********************
文件名:PCF8574.h
-------------------------------------------------------------
使用说明:
1、IIC IO扩展芯片
2、使用
PCF8574_WriteBit(0, IO_Sta%2);
IO_Sta++;
3、需要初始化IIC,并使用单独文件
4、ETH:
PCF8574_WriteBit(7,1);//硬件复位LAN8720
HAL_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_H
void PCF8574_WriteBit(uint8_t IO_Num,uint8_t IO_Sta);
uint8_t PCF8574_ReadBit(uint8_t IO_Num);
#endif
#endif /* PCF8574_H_ */
此时编译不会报错
向ethernetif.c里添以太网复位代码
1.添加头文件
/* USER CODE BEGIN 0 */
#include "PCF8574.h"
/* USER CODE END 0 */
2.找到void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
3.在代码保护区加入复位代码
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 Configuration
PC1 ------> ETH_MDC
PA1 ------> ETH_REF_CLK
PA2 ------> ETH_MDIO
PA7 ------> ETH_CRS_DV
PC4 ------> ETH_RXD0
PC5 ------> ETH_RXD1
PB11 ------> ETH_TX_EN
PG13 ------> ETH_TXD0
PG14 ------> 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);
/* USER CODE BEGIN ETH_MspInit 1 */
uint32_t regval;
HAL_ETH_ReadPHYRegister(&heth, 0, 2, ®val);
if (regval && 0xFFF == 0xFFF) /* 旧板卡(LAN8720A)引脚复�? */
{
PCF8574_WriteBit(7,1); /* 硬件复位 */
HAL_Delay(100);
PCF8574_WriteBit(7,0); /* 复位结束 */
HAL_Delay(100);
}
else /* 新板卡(YT8512C)引脚复�? */
{
PCF8574_WriteBit(7,0); /* 硬件复位 */
HAL_Delay(100);
PCF8574_WriteBit(7,1); /* 复位结束 */
HAL_Delay(100);
}
/* USER CODE END ETH_MspInit 1 */
}
}
main.c添加MX_LWIP_Process
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
MX_LWIP_Process();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
然后编译下载,cmd使用ping命令
更进一步
这时候如果ping通说明成功。但是不会有任何其他现象证明我们配置的是否成功,这时候需要加一些打印信息来验证我们我们是否配置成功
添加串口重定向函数
main函数前添加串口重定向函数,这时候就可以用printf打印信息了
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#ifdef __GNUC__ // 串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 0 */
main.c添加头文件
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "PCF8574.h"
/* USER CODE END Includes */
main函数里添加一些宏定义
int main(void)
{
/* USER CODE BEGIN 1 */
#ifdef LAN8742A_PHY_ADDRESS
#undef LAN8742A_PHY_ADDRESS
#define LAN8742A_PHY_ADDRESS 0U
#endif
uint32_t regvalue;
/* USER CODE END 1 */
main函数添加打印信息
/* USER CODE BEGIN 2 */
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);
/* USER CODE END 2 */
配置正确打印信息
如果配置有问题,你将会看到很多FFFF
结束
文章到此结束,如果对你有帮助请不要忘了点赞收藏
参考文章Win 11系统j将默认IP地址修改为静态IP,并成功连接上网 - 七月安生里 - 博客园 (cnblogs.com)
STM32CubeIDE1.9.0\STM32CubeMX 6.5 F429IGT6加LAN8720A,配置ETH+LWIP_在stm32ide上配置h563的eth-CSDN博客