你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
liqing666 提问时间:2017-9-20 16:04 /
我是用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, &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[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, &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才能连上,不知道什么原因,请大神们帮忙看看!

收藏 3 评论3 发布时间:2017-9-20 16:04

举报

3个回答
无薪税绵 回答时间:2018-1-17 10:25:09
首选,使用 ping 192.168.4.161
要确定,你板子上的IP,是否已经设置成功。
当板子连接成功后,再确认 服务器端口 是否开启了。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

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

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

tongvus 回答时间:2018-1-17 18:57:52
我也遇到了同样的问题,使用stm32f429是没问题的,但是换成stm32f767就不行了,楼主解决没有?
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版