liqing666 发表于 2017-9-20 16:04:08

STM32F7加DP83848移植LWIP后有时候能连上网有时候又连不上

我是用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 ;
heth.Instance = ETH;
heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
heth.Init.PhyAddress = 1;//LAN8742A_PHY_ADDRESS;
MACAddr = 0x00;
MACAddr = 0x80;
MACAddr = 0xE1;
MACAddr = 0x00;
MACAddr = 0x00;
MACAddr = 0x00;
heth.Init.MACAddr = &MACAddr;
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, ETH_TXBUFNB);

/* Initialize Rx Descriptors list: Chain Mode*/
HAL_ETH_DMARxDescListInit(&heth, DMARxDscrTab, &Rx_Buff, ETH_RXBUFNB);

#if LWIP_ARP || LWIP_ETHERNET

/* set MAC hardware address length */
netif->hwaddr_len = ETH_HWADDR_LEN;

/* set MAC hardware address */
netif->hwaddr =heth.Init.MACAddr;
netif->hwaddr =heth.Init.MACAddr;
netif->hwaddr =heth.Init.MACAddr;
netif->hwaddr =heth.Init.MACAddr;
netif->hwaddr =heth.Init.MACAddr;
netif->hwaddr =heth.Init.MACAddr;

/* 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, &regvalue);
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 , &regvalue);
regvalue |= PHY_MISR_LINK_INT_EN;
HAL_ETH_WritePHYRegister(&heth, PHY_MISR, regvalue);
}


整个程序跑的流程如下:
第一步初始化LWIP:
void MX_LWIP_Init(void)
{
IP_ADDRESS1 = 192;
IP_ADDRESS1 = 168;
IP_ADDRESS1 = 4;
IP_ADDRESS1 = 161;
NETMASK_ADDRESS = 255;
NETMASK_ADDRESS = 255;
NETMASK_ADDRESS = 255;
NETMASK_ADDRESS = 0;

GATEWAY_ADDRESS = 192;
GATEWAY_ADDRESS = 168;
GATEWAY_ADDRESS = 4;
GATEWAY_ADDRESS = 1;
/* Initilialize the LwIP stack without RTOS */
lwip_init();

IP4_ADDR(&ipaddr, IP_ADDRESS1, IP_ADDRESS1, IP_ADDRESS1, IP_ADDRESS1);
IP4_ADDR(&netmask, NETMASK_ADDRESS, NETMASK_ADDRESS , NETMASK_ADDRESS, NETMASK_ADDRESS);
IP4_ADDR(&gw, GATEWAY_ADDRESS, GATEWAY_ADDRESS, GATEWAY_ADDRESS, GATEWAY_ADDRESS);

/* add the network interface (IPv4/IPv6) without RTOS */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_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才能连上,不知道什么原因,请大神们帮忙看看!

无薪税绵 发表于 2018-1-17 10:25:09

首选,使用 ping 192.168.4.161
要确定,你板子上的IP,是否已经设置成功。
当板子连接成功后,再确认 服务器端口 是否开启了。

morphlings2014 发表于 2018-1-17 11:45:00

DP和LAN的寄存器还是有区别的,我建议你可以参考下STM32F756G-EVAL的网络例程,用的也是DP83848,复制那几个配置文件,差不多只需要修改IO管脚就能简单的测试下。

tongvus 发表于 2018-1-17 18:57:52

我也遇到了同样的问题,使用stm32f429是没问题的,但是换成stm32f767就不行了,楼主解决没有?
页: [1]
查看完整版本: STM32F7加DP83848移植LWIP后有时候能连上网有时候又连不上