新手上路
积分 32
金钱 32
注册时间 2017-2-13
在线时间 6 小时
2 金钱
我是用CUBE生成的工程,因为CUBE默认用的PHY是LAN8742,需要把LAN8742改成DP83848,网上看了很多帖子,将stm32f7xx_hal_conf.h头文件里面关于外部PHY寄存器的定义修改为如下:
/* Section 4: Extended PHY Registers */
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
#define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */
#define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */
#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
//#define PHY_ISFR ((uint16_t)0x000BU) /*!< PHY Interrupt Source Flag register Offset */
//#define PHY_ISFR_INT4 ((uint16_t)0x000BU) /*!< PHY Link down inturrupt */
#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */
#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */
#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */
#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */
红色部分注释掉的是cube生成的LAN8742的寄存器定义
然后ethernetif.c文件中的底层初始化函数:
static void low_level_init(struct netif *netif)
{
uint32_t regvalue = 0;
HAL_StatusTypeDef hal_eth_init_status;
/* Init ETH */
uint8_t MACAddr[6] ;
heth.Instance = ETH;
heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
heth.Init.PhyAddress = 1;//LAN8742A_PHY_ADDRESS;
MACAddr[0] = 0x00;
MACAddr[1] = 0x80;
MACAddr[2] = 0xE1;
MACAddr[3] = 0x00;
MACAddr[4] = 0x00;
MACAddr[5] = 0x00;
heth.Init.MACAddr = &MACAddr[0];
heth.Init.RxMode = ETH_RXPOLLING_MODE;
heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
hal_eth_init_status = HAL_ETH_Init(&heth);
if (hal_eth_init_status == HAL_OK)
{
/* Set netif link flag */
netif->flags |= NETIF_FLAG_LINK_UP;
}
/* Initialize Tx Descriptors list: Chain Mode */
HAL_ETH_DMATxDescListInit(&heth, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
/* Initialize Rx Descriptors list: Chain Mode */
HAL_ETH_DMARxDescListInit(&heth, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
#if LWIP_ARP || LWIP_ETHERNET
/* set MAC hardware address length */
netif->hwaddr_len = ETH_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = heth.Init.MACAddr[0];
netif->hwaddr[1] = heth.Init.MACAddr[1];
netif->hwaddr[2] = heth.Init.MACAddr[2];
netif->hwaddr[3] = heth.Init.MACAddr[3];
netif->hwaddr[4] = heth.Init.MACAddr[4];
netif->hwaddr[5] = heth.Init.MACAddr[5];
/* maximum transfer unit */
netif->mtu = 1500;
/* Accept broadcast address and ARP traffic */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
#if LWIP_ARP
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
#else
netif->flags |= NETIF_FLAG_BROADCAST;
#endif /* LWIP_ARP */
/* Enable MAC and DMA transmission and reception */
HAL_ETH_Start(&heth);
/* Read Register Configuration */
HAL_ETH_ReadPHYRegister(&heth, PHY_MICR, ®value);
regvalue |= (PHY_MICR_INT_EN | PHY_MICR_INT_OE);
/* Enable Interrupt on change of link status */
HAL_ETH_WritePHYRegister(&heth, PHY_MICR , regvalue );
HAL_ETH_ReadPHYRegister(&heth, PHY_MISR , ®value);
regvalue |= PHY_MISR_LINK_INT_EN;
HAL_ETH_WritePHYRegister(&heth, PHY_MISR, regvalue);
}
整个程序跑的流程如下:
第一步初始化LWIP:
void MX_LWIP_Init(void)
{
IP_ADDRESS1[0] = 192;
IP_ADDRESS1[1] = 168;
IP_ADDRESS1[2] = 4;
IP_ADDRESS1[3] = 161;
NETMASK_ADDRESS[0] = 255;
NETMASK_ADDRESS[1] = 255;
NETMASK_ADDRESS[2] = 255;
NETMASK_ADDRESS[3] = 0;
GATEWAY_ADDRESS[0] = 192;
GATEWAY_ADDRESS[1] = 168;
GATEWAY_ADDRESS[2] = 4;
GATEWAY_ADDRESS[3] = 1;
/* Initilialize the LwIP stack without RTOS */
lwip_init();
IP4_ADDR(&ipaddr, IP_ADDRESS1[0], IP_ADDRESS1[1], IP_ADDRESS1[2], IP_ADDRESS1[3]);
IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);
/* add the network interface (IPv4/IPv6) without RTOS */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
/* Registers the default network interface */
netif_set_default(&gnetif);
if (netif_is_link_up(&gnetif))
{
/* When the netif is fully configured this function must be called */
netif_set_up(&gnetif);
}
else
{
/* When the netif link is down this function must be called */
netif_set_down(&gnetif);
}
}
第二步连接服务器:
void tcp_echoclient_connect(void)
{
ip_addr_t DestIPaddr;
DEST_IP_ADDR0 = unWinSkyRecSetDat.strSetDat.DestHostNet.IP_Address.ip1; //112;
DEST_IP_ADDR1 = unWinSkyRecSetDat.strSetDat.DestHostNet.IP_Address.ip2; //74;
DEST_IP_ADDR2 = unWinSkyRecSetDat.strSetDat.DestHostNet.IP_Address.ip3; //210;
DEST_IP_ADDR3 = unWinSkyRecSetDat.strSetDat.DestHostNet.IP_Address.ip4; //81;
DEST_PORT = unWinSkyRecSetDat.strSetDat.DestHostNet.NetPortNumber; //8056;
/* create new tcp pcb */
echoclient_pcb = tcp_new();
if (echoclient_pcb != NULL)
{
IP4_ADDR( &DestIPaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 );
/* connect to destination address/port */
tcp_connect(echoclient_pcb,&DestIPaddr,DEST_PORT,tcp_echoclient_connected);
}
}
第三步while(1)里面:
循环读数据
void MX_LWIP_Process(void)
{
ethernetif_input(&gnetif);
sys_check_timeouts();
}
一秒钟一次检测连接状态,如果断开则一直尝试连接服务器
void ConnectToDest(void)//练接服务器
{
static int ConnectCase=0;
switch(ConnectCase)
{
case 0:
ethernetif_set_link(&gnetif);
ConnectCase=1;
break;
case 1:
tcp_echoclient_connect();
ConnectCase=0;
break;
default:
break;
}
大致过程就是这样,下载到板子上之后一直连不上,RESET也不行,只有DEBUG的时候一直RESET才能连上,不知道什么原因,请大神们帮忙看看!
我来回答