当前位置: 首页 > news >正文

STM32CUBEMX配置LAN8720a实现UDP通信

环境

STM32CUBEMX 6.15
单片机:STM32F767VIT6

Cube配置

1/启用freertos,并新建一个udp任务。
在这里插入图片描述
2/启用ETH,选择接口为RMII,因为LAN8720a支持这个接口,注意引脚与实际硬件要一致。

在这里插入图片描述
3/配置LAN8720的复位引脚,任选一个引脚,用于复位芯片。
在这里插入图片描述
4/启用lwip,并禁用DHCP,使用手动配置一个IP地址及网关。
在这里插入图片描述
至此,芯片配置完成,可以进入到代码编辑了。

代码编辑

1/使用keil进行编辑,首先打开魔术棒,勾选微库在这里插入图片描述
2/在MX_LWIP_Init()函数里面,加入LAN8720的复位代码
在这里插入图片描述
至此,应该就可以ping通网络了(我已经把我的电脑网卡地址改为192.168.3.109了)
在这里插入图片描述

3/在freertos文件里面,包含如下头文件
在这里插入图片描述

#include "lwip/udp.h"
#include "lwip/api.h"
#include "string.h"

4/声明功能函数
在这里插入图片描述

static void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p,const ip_addr_t *addr, u16_t port);
void udp_send_data(const char *data, const char *ip_addr, uint16_t port);

5/默认任务,发送数据

6/udp任务,处理数据接收
在这里插入图片描述

void StartUdpTask(void const * argument)
{/* USER CODE BEGIN StartUdpTask *//* Infinite loop */osDelay(1000);struct udp_pcb *upcb;err_t err;// 创建UDP控制块upcb = udp_new();if (!upcb){
//      printf("Error creating PCB.\n");return;}// 绑定到本地IP和端口err = udp_bind(upcb, IP_ADDR_ANY, 1234); // 使用1234端口if (err != ERR_OK){
//      printf("Error binding to port. Error: %d\n", err);udp_remove(upcb);return;}// 设置接收回调函数udp_recv(upcb, udp_receive_callback, NULL);//  printf("UDP server started on port 1234\n");// 任务主循环for(;;){// 可以在这里添加其他处理逻辑osDelay(1000);}/* USER CODE END StartUdpTask */
}

7/在/* USER CODE BEGIN Application /和/ USER CODE END Application */之间,补充UDP的回调函数和发送函数。
在这里插入图片描述

// UDP接收回调函数
static void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{// 检查是否有数据if (p != NULL) {// 打印接收到的数据
//        printf("Received %d bytes from %s:%d\n", p->tot_len, 
//               ipaddr_ntoa(addr), port);
//        printf("Data: %s\n", (char*)p->payload);// 发送响应(可选)char response[] = "Hello from STM32!";struct pbuf *resp_pbuf = pbuf_alloc(PBUF_TRANSPORT, strlen(response), PBUF_RAM);if (resp_pbuf) {memcpy(resp_pbuf->payload, response, strlen(response));udp_sendto(pcb, resp_pbuf, addr, port);pbuf_free(resp_pbuf);}// 释放接收到的数据包pbuf_free(p);}
}void udp_send_data(const char *data, const char *ip_addr, uint16_t port)
{struct udp_pcb *upcb;err_t err;struct pbuf *p;// 创建UDP控制块upcb = udp_new();if (!upcb) {
//        printf("Error creating PCB.\n");return;}// 解析目标IP地址ip_addr_t dest_addr;IP4_ADDR(&dest_addr, (uint8_t)(ip_addr[0]), (uint8_t)(ip_addr[1]), (uint8_t)(ip_addr[2]), (uint8_t)(ip_addr[3]));// 分配缓冲区p = pbuf_alloc(PBUF_TRANSPORT, strlen(data), PBUF_RAM);if (!p) {
//        printf("Error allocating pbuf.\n");udp_remove(upcb);return;}// 复制数据到缓冲区memcpy(p->payload, data, strlen(data));// 发送数据err = udp_sendto(upcb, p, &dest_addr, port);if (err != ERR_OK) {
//        printf("Error sending data: %d\n", err);} else {
//        printf("Data sent successfully.\n");}// 清理pbuf_free(p);udp_remove(upcb);
}

测试

连接好网线,打开sscom软件,配置好参数,就可以每秒收到数据China,点击发送后,会反馈Hello from stm32!(注意发送前,先点击“连接”按键).
在这里插入图片描述

http://www.dtcms.com/a/363535.html

相关文章:

  • 【C++游记】红黑树
  • 嵌入式C语言之链表冒泡排序
  • Java基础第9天总结(可变参数、Collections、斗地主)
  • 深入浅出数据库事务:从原理到实践,解决 Spring 事务与外部进程冲突问题
  • github下载的文件内容类似文件哈希和存储路径原因
  • Kafka 分层存储(Tiered Storage)从 0 到 1 的配置、调优与避坑
  • Vue3 实现自定义指令点击空白区域关闭下拉框
  • 【51单片机】【protues仿真】 基于51单片机智能电子秤系统
  • 工业界实战之数据存储格式与精度
  • 嵌入式解谜日志-网络编程
  • 浏览器面试题及详细答案 88道(56-66)
  • MySQL查询limit 0,100和limit 10000000,100有什么区别?
  • 敏捷规模化管理工具实战指南:如何实现跨团队依赖可视化?
  • 数据库驱动改造加密姓名手机号证件号邮箱敏感信息
  • web自动化测试(selenium)
  • RK-Android15-WIFI白名单功能实现
  • 一次别开生面的Java面试
  • Servlet基础
  • Redisson分布式锁会发生死锁问题吗?怎么发生的?
  • Aurobay EDI 需求分析:OFTP2 与 EDIFACT 驱动的汽车供应链数字化
  • UniApp 实现搜索页逻辑详解
  • uniapp H5预览图片组件
  • 年轻教师开学焦虑破解:从心出发,重构健康工作生活新秩序
  • uni-app 布局之 Flex
  • 第一讲、Kafka 初识与环境搭建
  • ImageMagick命令行图片工具:批量实现格式转换与压缩,支持水印添加及GIF动态图合成
  • windows系统离线安装Ollama、创建模型(不使用docker)、coze调用
  • 51c大模型~合集177
  • Swift 解法详解:LeetCode 369《给单链表加一》
  • 研发团队缺乏统一文档模板怎么办