STM32CubeIDE1.9.0\STM32CubeMX 6.5 F429IGT6加LAN8720A,配置ETH+LWIP

STM32CubeIDE1.9.0\STM32CubeMX 6.5 F429IGT6加LAN8720A,配置ETH+LWIPSTM32CubeIDE1.9.0\STM32CubeMX6.5F429IGT6加LAN8720A,配置ETH+LWIP,解决目前已知的STM32CubeMX6.5问题

大家好,欢迎来到IT知识分享网。

前段时间配置的F107系列和F7的LWIP功能,很顺利,但是到了F4系列,选择ETH之后没有PHY地址了,查了一下,MX 6.5有大改动,整理了一下各路大神的各种方法,配出来一个可以用的,我这里以Cubeide为例

Cube配置的时候各个外设选择生成各自的.c .h 规整不少

一些通用的SYS RCC啥的就不说了,开个串口,配置好printf函数备用

1、硬件配置

这里使用原子的开发板,F429IGT6+LAN8720A,复位引脚接在PCF8574的第七个口,引脚接口:

    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

PCF8574的IIC接口

    PH4     ------> I2C2_SCL
    PH5     ------> 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);//硬件复位LAN8720 HAL_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_H

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 ------------------------------------------------------------- 使用说明: 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_ */

2、3 PCF8574使用

ETH引脚初始化完成后加上
在ethernetif.c文件的 HAL_ETH_MspInit

  /* USER CODE BEGIN ETH_MspInit 1 */
	PCF8574_WriteBit(7,1);//硬件复位LAN8720
 	HAL_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 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);

    /* 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);//硬件复位LAN8720
 	HAL_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, &regvalue);
	printf("PHY_BCR %d: %X\r\n", PHY_BCR, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, PHY_BSR, &regvalue);
	printf("PHY_BSR %d: %X\r\n", PHY_BSR, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 2, &regvalue);
	printf("PHY 1 %d: %X\r\n", 2, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 3, &regvalue);
	printf("PHY2 %d: %X\r\n", 3, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 4, &regvalue);
	printf(" %d: %X\r\n", 4, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 5, &regvalue);
	printf(" %d: %X\r\n", 5, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 6, &regvalue);
	printf(" %d: %X\r\n", 6, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 17, &regvalue);
	printf(" %d: %X\r\n", 17, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 18, &regvalue);
	printf(" %d: %X\r\n", 18, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 26, &regvalue);
	printf(" %d: %X\r\n", 26, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 27, &regvalue);
	printf(" %d: %X\r\n", 27, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 29, &regvalue);
	printf(" %d: %X\r\n", 29, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 30, &regvalue);
	printf(" %d: %X\r\n", 30, (unsigned int) regvalue);
	HAL_ETH_ReadPHYRegister(&heth, LAN8742A_PHY_ADDRESS, 31, &regvalue);
	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);

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/10218.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信