单片机 :STM32F407
开发板:DMF407电机开发板
平台:keil V5.31
HSE 为8MHZ
HSI为16MHZ
一、原理图

二、文件系统



三、TCP/IP协议栈







四、主函数
void lwip_test_ui(uint8_t mode)
{
uint8_t speed;
uint8_t buf[30];
if(mode & 1<< 0)
{
lcd_show_string(6, 10, 200, 32, 32, "STM32", DARKBLUE);
lcd_show_string(6, 40, lcddev.width, 24, 24, "lwIP Ping Test", DARKBLUE);
lcd_show_string(6, 70, 200, 16, 16, "ATOM@ALIENTEK", DARKBLUE);
}
if(mode & 1 << 1)
{
lcd_show_string(6, 110, 200, 16, 16, "lwIP Init Successed", MAGENTA);
if(g_lwipdev.dhcpstatus == 2)
{
sprintf((char*)buf,"DHCP IP:%d.%d.%d.%d",g_lwipdev.ip[0],g_lwipdev.ip[1],g_lwipdev.ip[2],g_lwipdev.ip[3]); /* 显示动态IP地址 */
}
else
{
sprintf((char*)buf,"Static IP:%d.%d.%d.%d",g_lwipdev.ip[0],g_lwipdev.ip[1],g_lwipdev.ip[2],g_lwipdev.ip[3]); /* 打印静态IP地址 */
}
lcd_show_string(6, 130, 200, 16, 16, (char*)buf, MAGENTA);
speed = ethernet_chip_get_speed(); /* 得到网速 */
if(speed)
{
lcd_show_string(6, 150, 200, 16, 16, "Ethernet Speed:100M", MAGENTA);
}
else
{
lcd_show_string(6, 150, 200, 16, 16, "Ethernet Speed:10M", MAGENTA);
}
}
}
int main(void)
{
uint8_t t = 0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
usart_init(115200); /* 串口初始化为115200 */
usmart_dev.init(84); /* 初始化USMART */
led_init(); /* 初始化LED */
lcd_init(); /* 初始化LCD */
key_init(); /* 初始化按键 */
my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */
my_mem_init(SRAMCCM); /* 初始化内部SRAMCCM内存池 */
lwip_test_ui(1); /* 加载前半部分UI */
lcd_show_string(6, 110, 200, 16, 16, "lwIP Init !!", BLUE);
while (lwip_comm_init() != 0)
{
lcd_show_string(6, 110, 200, 16, 16, "lwIP Init failed!!", BLUE);
delay_ms(500);
lcd_fill(6, 50, 200 + 30, 50 + 16, WHITE);
lcd_show_string(6, 110, 200, 16, 16, "Retrying... ", BLUE);
delay_ms(500);
LED1_TOGGLE();
}
while (!ethernet_read_phy(PHY_SR)) /* 检查MCU与PHY芯片是否通信成功 */
{
printf("MCU与PHY芯片通信失败,请检查电路或者源码!!!!\r\n");
}
#if LWIP_DHCP
lcd_show_string(6, 130, 200, 16, 16, "DHCP IP configing... ", BLUE); /* 开始DHCP */
while ((g_lwipdev.dhcpstatus != 2) && (g_lwipdev.dhcpstatus != 0XFF)) /* 等待DHCP获取成功/超时溢出 */
{
lwip_periodic_handle();
}
#endif
lwip_test_ui(2); /* 加载后半部分UI */
while(1)
{
lwip_periodic_handle(); /* LWIP轮询任务 */
delay_ms(2);
t ++;
if(t >= 200)
{
t = 0;
LED0_TOGGLE();
}
}
}
uint8_t lwip_comm_init(void)
{
uint8_t retry = 0;
struct netif *netif_init_flag; /* 调用netif_add()函数时的返回值,用于判断网络初始化是否成功 */
ip_addr_t ipaddr; /* ip地址 */
ip_addr_t netmask; /* 子网掩码 */
ip_addr_t gw; /* 默认网关 */
if (ethernet_mem_malloc())return 1; /* 内存申请失败*/
lwip_comm_default_ip_set(&g_lwipdev); /* 设置默认IP等信息 */
while (ethernet_init()) /* 初始化以太网芯片,如果失败的话就重试5次 */
{
retry++;
if (retry > 5)
{
retry = 0; /* 以太网芯片初始化失败 */
return 3;
}
}
lwip_init(); /* 初始化LWIP内核 */
#if LWIP_DHCP /* 使用动态IP */
ip_addr_set_zero_ip4(&ipaddr); /* 对IP地址、子网掩码及网关清零 */
ip_addr_set_zero_ip4(&netmask);
ip_addr_set_zero_ip4(&gw);
#else /* 使用静态IP */
IP4_ADDR(&ipaddr, g_lwipdev.ip[0], g_lwipdev.ip[1], g_lwipdev.ip[2], g_lwipdev.ip[3]);
IP4_ADDR(&netmask, g_lwipdev.netmask[0], g_lwipdev.netmask[1], g_lwipdev.netmask[2], g_lwipdev.netmask[3]);
IP4_ADDR(&gw, g_lwipdev.gateway[0], g_lwipdev.gateway[1], g_lwipdev.gateway[2], g_lwipdev.gateway[3]);
printf("网卡en的MAC地址为:................%d.%d.%d.%d.%d.%d\r\n", g_lwipdev.mac[0], g_lwipdev.mac[1], g_lwipdev.mac[2], g_lwipdev.mac[3], g_lwipdev.mac[4], g_lwipdev.mac[5]);
printf("静态IP地址........................%d.%d.%d.%d\r\n", g_lwipdev.ip[0], g_lwipdev.ip[1], g_lwipdev.ip[2], g_lwipdev.ip[3]);
printf("子网掩码..........................%d.%d.%d.%d\r\n", g_lwipdev.netmask[0], g_lwipdev.netmask[1], g_lwipdev.netmask[2], g_lwipdev.netmask[3]);
printf("默认网关..........................%d.%d.%d.%d\r\n", g_lwipdev.gateway[0], g_lwipdev.gateway[1], g_lwipdev.gateway[2], g_lwipdev.gateway[3]);
#endif /* 向网卡列表中添加一个网口 */
netif_init_flag = netif_add(&g_lwip_netif, (const ip_addr_t *)&ipaddr, (const ip_addr_t *)&netmask, (const ip_addr_t *)&gw, NULL, ðernetif_init, ðernet_input);
if (netif_init_flag == NULL)
{
return 2; /* 网卡添加失败 */
}
else /* 网口添加成功后,设置netif为默认值,并且打开netif网口 */
{
netif_set_default(&g_lwip_netif); /* 设置netif为默认网口 */
if (netif_is_link_up(&g_lwip_netif))
{
netif_set_up(&g_lwip_netif); /* 打开netif网口 */
}
else
{
netif_set_down(&g_lwip_netif);
}
lwip_link_status_updated(&g_lwip_netif); /* DHCP链接状态更新函数 */
netif_set_link_callback(&g_lwip_netif, lwip_link_status_updated);
}
#if LWIP_DHCP /* 如果使用DHCP的话 */
g_lwipdev.dhcpstatus = 0; /* DHCP标记为0 */
#endif
return 0; /* 操作OK. */
}
uint8_t ethernet_init(void)
{
uint8_t macaddress[6];
macaddress[0] = g_lwipdev.mac[0];
macaddress[1] = g_lwipdev.mac[1];
macaddress[2] = g_lwipdev.mac[2];
macaddress[3] = g_lwipdev.mac[3];
macaddress[4] = g_lwipdev.mac[4];
macaddress[5] = g_lwipdev.mac[5];
g_eth_handler.Instance = ETH;
g_eth_handler.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; /* 使能自协商模式 */
g_eth_handler.Init.Speed = ETH_SPEED_100M; /* 速度100M,如果开启了自协商模式,此配置就无效 */
g_eth_handler.Init.DuplexMode = ETH_MODE_FULLDUPLEX; /* 全双工模式,如果开启了自协商模式,此配置就无效 */
g_eth_handler.Init.PhyAddress = ETHERNET_PHY_ADDRESS; /* 以太网芯片的地址 */
g_eth_handler.Init.MACAddr = macaddress; /* MAC地址 */
g_eth_handler.Init.RxMode = ETH_RXINTERRUPT_MODE; /* 中断接收模式 */
g_eth_handler.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; /* 硬件帧校验 */
g_eth_handler.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; /* RMII接口 */
if (HAL_ETH_Init(&g_eth_handler) == HAL_OK)
{
return 0; /* 成功 */
}
else
{
return 1; /* 失败 */
}
}
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
{
GPIO_InitTypeDef gpio_init_struct;
ETH_CLK_GPIO_CLK_ENABLE(); /* 开启ETH_CLK时钟 */
ETH_MDIO_GPIO_CLK_ENABLE(); /* 开启ETH_MDIO时钟 */
ETH_CRS_GPIO_CLK_ENABLE(); /* 开启ETH_CRS时钟 */
ETH_MDC_GPIO_CLK_ENABLE(); /* 开启ETH_MDC时钟 */
ETH_RXD0_GPIO_CLK_ENABLE(); /* 开启ETH_RXD0时钟 */
ETH_RXD1_GPIO_CLK_ENABLE(); /* 开启ETH_RXD1时钟 */
ETH_TX_EN_GPIO_CLK_ENABLE(); /* 开启ETH_TX_EN时钟 */
ETH_TXD0_GPIO_CLK_ENABLE(); /* 开启ETH_TXD0时钟 */
ETH_TXD1_GPIO_CLK_ENABLE(); /* 开启ETH_TXD1时钟 */
ETH_RESET_GPIO_CLK_ENABLE(); /* 开启ETH_RESET时钟 */
__HAL_RCC_ETH_CLK_ENABLE(); /* 开启ETH时钟 */
/* 网络引脚设置 RMII接口
* ETH_MDIO -------------------------> PA2
* ETH_MDC --------------------------> PC1
* ETH_RMII_REF_CLK------------------> PA1
* ETH_RMII_CRS_DV ------------------> PA7
* ETH_RMII_RXD0 --------------------> PC4
* ETH_RMII_RXD1 --------------------> PC5
* ETH_RMII_TX_EN -------------------> PG11
* ETH_RMII_TXD0 --------------------> PG13
* ETH_RMII_TXD1 --------------------> PG14
* ETH_RESET-------------------------> PI8
*/
/* PA1,2,7 */
gpio_init_struct.Pin = ETH_CLK_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 推挽复用 */
gpio_init_struct.Pull = GPIO_NOPULL; /* 不带上下拉 */
gpio_init_struct.Speed = GPIO_SPEED_HIGH; /* 高速 */
gpio_init_struct.Alternate = GPIO_AF11_ETH; /* 复用为ETH功能 */
HAL_GPIO_Init(ETH_CLK_GPIO_PORT, &gpio_init_struct); /* ETH_CLK引脚模式设置 */
gpio_init_struct.Pin = ETH_MDIO_GPIO_PIN;
HAL_GPIO_Init(ETH_MDIO_GPIO_PORT, &gpio_init_struct); /* ETH_MDIO引脚模式设置 */
gpio_init_struct.Pin = ETH_CRS_GPIO_PIN;
HAL_GPIO_Init(ETH_CRS_GPIO_PORT, &gpio_init_struct); /* ETH_CRS引脚模式设置 */
/* PC1 */
gpio_init_struct.Pin = ETH_MDC_GPIO_PIN;
HAL_GPIO_Init(ETH_MDC_GPIO_PORT, &gpio_init_struct); /* ETH_MDC初始化 */
/* PC4 */
gpio_init_struct.Pin = ETH_RXD0_GPIO_PIN;
HAL_GPIO_Init(ETH_RXD0_GPIO_PORT, &gpio_init_struct); /* ETH_RXD0初始化 */
/* PC5 */
gpio_init_struct.Pin = ETH_RXD1_GPIO_PIN;
HAL_GPIO_Init(ETH_RXD1_GPIO_PORT, &gpio_init_struct); /* ETH_RXD1初始化 */
/* PG11,13,14 */
gpio_init_struct.Pin = ETH_TX_EN_GPIO_PIN;
HAL_GPIO_Init(ETH_TX_EN_GPIO_PORT, &gpio_init_struct); /* ETH_TX_EN初始化 */
gpio_init_struct.Pin = ETH_TXD0_GPIO_PIN;
HAL_GPIO_Init(ETH_TXD0_GPIO_PORT, &gpio_init_struct); /* ETH_TXD0初始化 */
gpio_init_struct.Pin = ETH_TXD1_GPIO_PIN;
HAL_GPIO_Init(ETH_TXD1_GPIO_PORT, &gpio_init_struct); /* ETH_TXD1初始化 */
/* 复位引脚 */
gpio_init_struct.Pin = ETH_RESET_GPIO_PIN; /* ETH_RESET初始化 */
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
gpio_init_struct.Pull = GPIO_NOPULL; /* 无上下拉 */
gpio_init_struct.Speed = GPIO_SPEED_HIGH; /* 高速 */
HAL_GPIO_Init(ETH_RESET_GPIO_PORT, &gpio_init_struct);
ETHERNET_RST(0); /* 硬件复位 */
delay_ms(50);
ETHERNET_RST(1); /* 复位结束 */
HAL_NVIC_SetPriority(ETH_IRQn, 1, 0); /* 网络中断优先级应该高一点 */
HAL_NVIC_EnableIRQ(ETH_IRQn);
}
五、测试结果
