STM32单片机示例:ETH_DP83848_DHCP_NonOS_Poll_F407

2024-03-03 01:52

本文主要是介绍STM32单片机示例:ETH_DP83848_DHCP_NonOS_Poll_F407,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 目的
  • 基础说明
  • 主要配置
  • 关键代码
  • 示例演示
  • 示例链接
  • 关于中断
  • 总结

目的

以太网是比较常用到的功能,这篇文章讲演示在STM32F407上启用以太网功能,使之能够加入网络中,通过DHCP获得IP地址,可以被Ping通。

基础说明

STM32F407是一个自带以太网控制器(ETH MAC)的单片机,只要外接以太网收发器(ETH PHY)就可以进行以太网通讯了。

不过通常来说以太网是一个相对复杂的东西,除了 MAC 和 PHY 外还需要很多软件上的协议支撑,才能方便的进行应用程序的开发,通常嵌入式设备中比较常用的是 LwIP 。

DHCP是一种可以让接入网络的设备可以动态获取IP地址的服务。通常作为一个可以联网工作的设备而言,通过DHCP自动获取IP地址是比较常用的方式。

使用 STM32CubeMX 可以方便的配置芯片自带的 ETH MAC ,可以配置 LwIP ,在 LwIP 中还可以选择一些 ETH PHY 芯片(比如本文的DP83848)。

在早期的版本中默认配置生成的代码在使用DHCP时,如果设备启动时没有插入网线,那么程序会一直卡在DHCP启动这里,目前版本中已经修复了这个问题。本文编写时使用的版本如下:

STM32CubeF4 Firmware Package V1.28.0 / 01-November-2023
Current version of LwIP supported by CubeMx: 2.1.2

主要配置

启用的外设与中间件:
在这里插入图片描述
时钟:
在这里插入图片描述
以太网:
在这里插入图片描述
LwIP:
在这里插入图片描述
堆栈:
在这里插入图片描述

关键代码

main.c 中一些手动添加的代码:

#include "main.h"
#include "lwip.h"UART_HandleTypeDef huart6;/* With GCC, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) // 实现__io_putchar函数
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(&huart6, (uint8_t *)&ch, 1, 0xFFFF); // for printf()return ch;
}int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_LWIP_Init(); // 初始化网络功能MX_USART6_UART_Init();while (1){MX_LWIP_Process(); // 处理网络相关事务static uint32_t previous = 0;if((HAL_GetTick() - previous)>=1000){previous = HAL_GetTick();extern struct netif gnetif; // 网卡对象,在lwip.c文件中定义// 打印时间和IP地址printf("%ld - loop: ip addr %s\n", HAL_GetTick(), ip4addr_ntoa(netif_ip_addr4(&gnetif)));}}
}

lwip.c 中一些手动添加的代码:

/*** @brief  Notify the User about the network interface config status* @param  netif: the network interface*/
static void ethernet_link_status_updated(struct netif *netif)
{if (netif_is_up(netif)){printf("%ld - link status callback: netif_is_up!\n", HAL_GetTick());}else /* netif is down */{printf("%ld - link status callback: netif_is_down!\n", HAL_GetTick());}
}

示例演示

连续Ping半个小时:
在这里插入图片描述

插拔网线测试:
在这里插入图片描述

示例链接

仓库地址: https://github.com/NaisuXu/STM32_MCU_Examples

本文中的示例位于仓库中 ETH_DP83848_DHCP_NonOS_Poll_F407

关于中断

以太网也是带中断的,以太网中断主要在接收、发送完成和错误等时候触发。

理论上来说可以在中断中接收数据,不过通常不应该在中断中处理耗时操作,所以更多的时候在中断中只是进行下标记,然后在主循环中处理。

未使用操作系统的情况下其实用中断和不用中断区别不是很大。官方也只在用了操作系统的情况下启用以太网中断,主要就是下面即可例程:

LwIP_HTTP_Server_Netconn_RTOS
LwIP_HTTP_Server_Socket_RTOS
LwIP_UDPTCP_Echo_Server_Netconn_RTOS

例程中首先是中断回调函数:

void ETH_IRQHandler(void)
{HAL_ETH_IRQHandler(&EthHandle);
}

回调函数中调用了HAL库对以太网中断的处理函数:

void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
{if (/* Packet received */){HAL_ETH_RxCpltCallback(heth);}if (/* Packet transmitted */){HAL_ETH_TxCpltCallback(heth);}if ( /* ETH DMA Error */){HAL_ETH_ErrorCallback(heth);}
}

例程中各个中断的处理都是给了个信号量:

void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
{osSemaphoreRelease(RxPktSemaphore);
}void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
{osSemaphoreRelease(TxPktSemaphore);
}void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
{osSemaphoreRelease(RxPktSemaphore);
}

总结

到此为止网络部分已经可以正常工作了,接下来就可以开发网络应用了,主要是使用LwIP提供的一些接口进行数据交互,这方面内容可以参考官方例程和文档:
《UM1713 使用 LwIP TCP/IP 栈,在 STM32Cube 上开发应用》

这篇关于STM32单片机示例:ETH_DP83848_DHCP_NonOS_Poll_F407的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/768089

相关文章

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

Mysql用户授权(GRANT)语法及示例解读

《Mysql用户授权(GRANT)语法及示例解读》:本文主要介绍Mysql用户授权(GRANT)语法及示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql用户授权(GRANT)语法授予用户权限语法GRANT语句中的<权限类型>的使用WITH GRANT

Java中Scanner的用法示例小结

《Java中Scanner的用法示例小结》有时候我们在编写代码的时候可能会使用输入和输出,那Java也有自己的输入和输出,今天我们来探究一下,对JavaScanner用法相关知识感兴趣的朋友一起看看吧... 目录前言一 输出二 输入Scanner的使用多组输入三 综合练习:猜数字游戏猜数字前言有时候我们在

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

前端CSS Grid 布局示例详解

《前端CSSGrid布局示例详解》CSSGrid是一种二维布局系统,可以同时控制行和列,相比Flex(一维布局),更适合用在整体页面布局或复杂模块结构中,:本文主要介绍前端CSSGri... 目录css Grid 布局详解(通俗易懂版)一、概述二、基础概念三、创建 Grid 容器四、定义网格行和列五、设置行

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/