OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4325|回复: 1

STM32F767加DP83848调试LWIP出现有时候能连有时候又连不上问题

[复制链接]

3

主题

5

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2017-2-13
在线时间
6 小时
发表于 2017-9-21 15:40:09 | 显示全部楼层 |阅读模式
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, &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才能连上,不知道什么原因,请大神们帮忙看看!

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2017-9-22 01:21:27 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 22:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表