使用硬件及cubeMX配置
关于LWIP的PHY搭建,采用的PHY芯片为LAN8720A,RMII模式。
主控芯片为stm32f407
CubeMX配置如下
需要注意的点:
默认选项里没有LAN8720A 我们选user PHY
- PHY Address
PHY Address需要是由PHYAD0引脚决定的,拉高就配置1,拉低/浮空就配置0,我这里是接了3.3v 所以配置1
-
DHCP
如果接路由进行测试就使能DHCP 如果没有就disable,并配置静态的ip地址 -
Freertos
freertos的tick时钟与stm32f4库中的初始化时钟有矛盾,所以在配置系统时钟时需要修改
我这里使用tim6作为系统时钟 -
生成工程选项
其他地方默认选项就可以了
生成工程中需要修改的地方
咱们先来看下工程的目录, 主要修改main 函数里的 MX_FREERTOS_Init();
LWIP协议栈在这里面进行初始化,并创建任务
如果是静态连接修改 MX_LWIP_Init(); 中的内容就可以了
/* USER CODE BEGIN 0 */
#define DEST_IP_ADDR0 192
#define DEST_IP_ADDR1 168
#define DEST_IP_ADDR2 1
#define DEST_IP_ADDR3 111
#define DEST_PORT 5001
#define UDP_SERVER_PORT 5002 /* define the UDP local connection port */
#define UDP_CLIENT_PORT 5002 /* define the UDP remote connection port */
#define LOCAL_PORT 5001
/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 122
/*NETMASK*/
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
/*Gateway Address*/
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
/* USER CODE END 0 */
/**
* LwIP initialization function
*/
void MX_LWIP_Init(void)
{
/* Initilialize the LwIP stack with RTOS */
tcpip_init( NULL, NULL );
/* IP addresses initialization with DHCP (IPv4) */
#if LWIP_DHCP
ipaddr.addr = 0;
netmask.addr = 0;
gw.addr = 0;
#else
IP4_ADDR(&ipaddr,IP_ADDR0,IP_ADDR1,IP_ADDR2,IP_ADDR3);
IP4_ADDR(&netmask,NETMASK_ADDR0,NETMASK_ADDR1,NETMASK_ADDR2,NETMASK_ADDR3);
IP4_ADDR(&gw,GW_ADDR0,GW_ADDR1,GW_ADDR2,GW_ADDR3);
#endif /* USE_DHCP */
/* add the network interface (IPv4/IPv6) with RTOS */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_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);
}
/* Set the link callback function, this function is called on change of link status*/
netif_set_link_callback(&gnetif, ethernetif_update_config);
/* create a binary semaphore used for informing ethernetif of frame reception */
osSemaphoreDef(Netif_SEM);
Netif_LinkSemaphore = osSemaphoreCreate(osSemaphore(Netif_SEM) , 1 );
link_arg.netif = &gnetif;
link_arg.semaphore = Netif_LinkSemaphore;
/* Create the Ethernet link handler thread */
osThreadDef(LinkThr, ethernetif_set_link, osPriorityNormal, 0, configMINIMAL_STACK_SIZE * 2);
osThreadCreate (osThread(LinkThr), &link_arg);
/* Start DHCP negotiation for a network interface (IPv4) */
dhcp_start(&gnetif);
/* USER CODE BEGIN 3 */
#if LWIP_DHCP //若使用了DHCP
int err;
/* Start DHCP negotiation for a network interface (IPv4) */
if(netif_is_up(&gnetif))
{
Lwip_printf("starting dhcp...\n");
err = dhcp_start(&gnetif);
}
if(err == ERR_OK)
{
Lwip_printf("starting dhcp success!\n");
}
else{
Lwip_printf("starting dhcp fail!\n");
}
while(ip_addr_cmp(&(gnetif.ip_addr),&ipaddr)) //等待dhcp分配的ip有效
{
vTaskDelay(2);
}
#endif
Lwip_printf("Local IP :%d.%d.%d.%d\n\n", \
((gnetif.ip_addr.addr)&0x000000ff), \
(((gnetif.ip_addr.addr)&0x0000ff00)>>8), \
(((gnetif.ip_addr.addr)&0x00ff0000)>>16), \
((gnetif.ip_addr.addr)&0xff000000)>>24);
/* USER CODE END 3 */
}
在上面配置电脑的 ip 和板子的ip,直接与电脑网线相连则,电脑的本地连接ip也需要修改,我这里用了RTT打印 将dbg_msg宏定义成了Lwip_printf, 自己用的时候改成自己方便的方式进行打印
实验测试
将程序烧写上电,看到我们已经获取到了ip
之后我们ping一下板子,大功告成