STM32 LWIP UDP 一对一 一对多发送
STM32 LWIP UDP通信
- 前言
- 设置 IP 地址
- UDP函数配置
- 实验结果
- 单播发送,一对一发送
- 广播发送,一对多发送
 
- 可能遇到的问题
- 总结
前言
之前没有接触过网络的通信,工作需要 UDP 接收和发送通信,在网上没有找到一对一、一对多的相关例程;于是在技术总监对我的指导,用正点原子板子给的例程是从官方的程序修改的,实现了Lwip UDP通信一对一、一对多的发送程序,可以随便指定发送ip地址、发送端口号,以及发送十六进制或是 ASCII码都可以,本人测试STM32F1系列和F4系列都没问题,十分的方便。
设置 IP 地址
- 假设设置STM32单片机IP为:192.168.1.130
	lwipx->ip[0]=192;	lwipx->ip[1]=168;lwipx->ip[2]=1;lwipx->ip[3]=130;
- 假设设置我的电脑的IP为:192.168.1.36

UDP函数配置
- STM32单片机上电不需要每次手动按键调节设置远端IP地址(ip地址、端口号)
//	udp_demo_set_remoteip();//先选择IPLCD_Clear(WHITE);	//清屏POINT_COLOR=RED; 	//红色字体LCD_ShowString(30,30,200,16,16,"WARSHIP STM32F103");LCD_ShowString(30,50,200,16,16,"UDP Test");LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");  LCD_ShowString(30,90,200,16,16,"KEY0:Send data");  LCD_ShowString(30,110,200,16,16,"KEY_UP:Quit"); LCD_ShowString(30,130,200,16,16,"KEY1:Connect");tbuf=mymalloc(SRAMIN,200);	//申请内存if(tbuf==NULL)return ;		//内存申请失败了,直接退出sprintf((char*)tbuf,"Local IP:%d.%d.%d.%d",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);//服务器IPLCD_ShowString(30,150,210,16,16,tbuf);sprintf((char*)tbuf,"Local Port:%d",UDP_DEMO_PORT);//服务器端口号LCD_ShowString(30,170,210,16,16,tbuf);
//	sprintf((char*)tbuf,"Remote IP:%d.%d.%d.%d",lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);//远端IP
//	LCD_ShowString(30,170,210,16,16,tbuf);  
//	sprintf((char*)tbuf,"Remote Port:%d",UDP_DEMO_PORT);//客户端端口号
//	LCD_ShowString(30,190,210,16,16,tbuf);POINT_COLOR=BLUE;LCD_ShowString(30,210,210,16,16,"STATUS:Disconnected"); 
- UDP客户端连接不需要指定IP地址和端口号的服务器
	udppcb=udp_new();if(udppcb)//创建成功{ IP4_ADDR(&rmtipaddr,lwipdev.remoteip[0],lwipdev.remoteip[1],lwipdev.remoteip[2],lwipdev.remoteip[3]);err=udp_bind(udppcb,IP_ADDR_ANY,UDP_DEMO_PORT);//绑定本地IP地址与端口号if(err==ERR_OK)	//绑定完成{udp_recv(udppcb,udp_demo_recv,NULL);//注册接收回调函数 LCD_ShowString(30,210,210,16,16,"STATUS:Connected   ");//标记连接上了(UDP是非可靠连接,这里仅仅表示本地UDP已经准备好)udp_demo_flag |= 1<<5;			//标记已经连接上POINT_COLOR=RED;LCD_ShowString(30,230,lcddev.width-30,lcddev.height-190,16,"Receive Data:");//提示消息		POINT_COLOR=BLUE;//蓝色字体}else res=1;	}else res=1;
- UDP回调函数
void udp_demo_recv(void *arg,struct udp_pcb *upcb,struct pbuf *p,struct ip_addr *addr,u16_t port)
{u32 data_len = 0;struct pbuf *q;if(p!=NULL)	//接收到不为空的数据时{memset(udp_demo_recvbuf,0,UDP_DEMO_RX_BUFSIZE);  //数据接收缓冲区清零for(q=p;q!=NULL;q=q->next)  //遍历完整个pbuf链表{//判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于//的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据if(q->len > (UDP_DEMO_RX_BUFSIZE-data_len)) memcpy(udp_demo_recvbuf+data_len,q->payload,(UDP_DEMO_RX_BUFSIZE-data_len));//拷贝数据else memcpy(udp_demo_recvbuf+data_len,q->payload,q->len);data_len += q->len;  	if(data_len > UDP_DEMO_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出	}upcb->remote_ip=*addr; 				//记录远程主机的IP地址upcb->remote_port=port;  			//记录远程主机的端口号lwipdev.remoteip[0]=upcb->remote_ip.addr&0xff; 		//IADDR4lwipdev.remoteip[1]=(upcb->remote_ip.addr>>8)&0xff; //IADDR3lwipdev.remoteip[2]=(upcb->remote_ip.addr>>16)&0xff;//IADDR2lwipdev.remoteip[3]=(upcb->remote_ip.addr>>24)&0xff;//IADDR1 udp_demo_flag|=1<<6;	//标记接收到数据了pbuf_free(p);//释放内存}else{udp_disconnect(upcb); LCD_Clear(WHITE);			//清屏POINT_COLOR = RED;LCD_ShowString(30,30,200,16,16,"WARSHIP STM32F103");LCD_ShowString(30,50,200,16,16,"UDP Test");LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");POINT_COLOR=BLUE;LCD_ShowString(30,90,200,16,16,"Connect break!");  LCD_ShowString(30,110,200,16,16,"KEY1:Connect");udp_demo_flag &= ~(1<<5);	//标记连接断开} 
}
实验结果
单播发送,一对一发送
	if(key == KEY0_PRES)//KEY0按下了,发送数据{u8 remote_add[4] = {192,168,1,36};	//发送对端的ip地址u8 send_str_data[] = "hello word!";	//要发送的信息Unicast_Send(remote_add,send_str_data,0,8089);//单播发送}
我按键按下KEY0_PRES按了三次发送,单播发送的端口号为8089,用 Wireshark 抓包
 
 也可以用网络调试助手查看是否收到STM32发来的数据,刚刚前面说过我设置自己的电脑ip:192.168.1.36,电脑本机端口号设置和STM32单片机发送数据端口号一致才能收到数据
 
广播发送,一对多发送
	if(key == KEY2_PRES)//KEY2按下了,发送数据{u8 send_data[8] = {0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8};	//要发送的信息Broadcast_Send(send_data,8,8080);//广播发送}
我按键按下KEY2_PRES按了两次发送,广播发送的端口号为8080,用 Wireshark 抓包
 
 也可以用网络调试助手查看是否收到STM32发来的数据,电脑本机端口号端口号设置和STM32单片机发送数据端口号一致才能收到数据,因为我刚刚设置STM32广播发送的端口号是8080,所以本地端口号8089是不会收到数据的,重新打开一个网络调试助手(端口号设置为8080),此时就可以正常收到数据了
 
 接收是正常的我就不演示了,没有 TFT显示屏 可以使用串口来查看单片机是否收到别的单片机发来的数据
		if(udp_demo_flag&1<<6)//是否收到数据?{LCD_Fill(30,250,lcddev.width-1,lcddev.height-1,WHITE);//清上一次数据LCD_ShowString(30,250,lcddev.width-30,lcddev.height-230,16,udp_demo_recvbuf);//显示接收到的数据			printf("接收到数据:%s\r\n",udp_demo_recvbuf);udp_demo_flag&=~(1<<6);//标记数据已经被处理了.} 
可能遇到的问题
- 移植不成功:不会将F1例程移植到F4板子上之类的问题
- 移植不会修改程序
- 没有设置自己的电脑ip地址
- 程序、STM32单片机、网线都没有问题,但电脑没有收到包,此时检查电脑的防火墙
- 端口号不一致也收不到包的 (这一点很重要),端口号要一致才能收发数据
- 其它等等问题
总结
本人也花了大量时间去研究,如需要源码支付30元,提供技术服务,加企鹅号:970484728,加企鹅时备注STM32 UDP,不需要源码的也不强求;记录下自己的学习过程,我只是刚入门的新手,知道有许多会的大佬,不喜勿喷!欢迎各位小伙伴一起前来讨论。
相关文章:
 
STM32 LWIP UDP 一对一 一对多发送
STM32 LWIP UDP通信 前言设置 IP 地址UDP函数配置实验结果单播发送,一对一发送广播发送,一对多发送 可能遇到的问题总结 前言 之前没有接触过网络的通信,工作需要 UDP 接收和发送通信,在网上没有找到一对一、一对多的相关例程&am…...
 
【有趣的设计模式】23 种设计模式详解和场景分析
前言 七大设计原则 1、单一原则:一个类只负责一个职责 2、开闭原则:对修改关闭,对扩展开放 3、里氏替换原则:不要破坏继承关系 4、接口隔离原则:暴露最小接口,避免接口过于臃肿 5、依赖倒置原则࿱…...
 
【数据结构与算法】TypeScript 实现图结构
class Grapg<T> {// 用于存储所有的顶点verteces: T[] [];// 用于存储所有的边 采用邻接表的形式adjList: Map<T, T[]> new Map();// 添加顶点addVertex(v: T) {this.verteces.push(v);// 初始化顶点的邻接表this.adjList.set(v, []);}// 添加边addEdge(v: T, w:…...
 
《golang设计模式》第一部分·创建型模式-04-抽象工厂模式(Abstract Factory)
文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 1.1 角色 AbstractFactory(抽象工厂):它声明了一组用于创建产品的方法,每一个方法对应一种产品。ConcreteFactory(具体工厂…...
 
改进粒子群算法优化BP神经网络---回归+分类两种案例
今天采用改进的粒子群算法(LPSO)优化算法优化BP神经网络。本文选用的LPSO算法是之前作者写过的一篇文章:基于改进莱维飞行和混沌映射(10种混沌映射随意切换)的粒子群优化算法,附matlab代码 文章一次性讲解两种案例,回归…...
 
VSCode和QT联合开发
提示:本文为学习记录,若有错误,请联系作者,谦虚受教。 文章目录 前言一、VSCODE下载二、使用步骤1.下载扩展 二、新建工程1.新建文件夹2.新建工程3.UI界面文件操作4.效果 总结 前言 一、VSCODE下载 下载地址 二、使用步骤 1.下…...
YOLO5-1 使用YOLO5检测 水面漂浮物记录
一 数据集 robflow 漂浮物数据集:buoy Computer Vision Dataset by ai 二 YOLO5管网 yolo5 :https://github.com/ultralytics/yolov5 克隆代码: git clone https://github.com/ultralytics/yolov5 # clone cd yolov5 pip install -r requirements.…...
MongoDB教程-7
正如在MongoDB关系的最后一章中所看到的,为了在MongoDB中实现规范化的数据库结构,我们使用了引用关系的概念,也被称为手动引用,在这个概念中,我们手动将被引用文档的id存储在其他文档中。然而,在一个文档包…...
Redisson提供优秀的并发控制机制
1. JDK集合类 对于JDK的集合类,forEach方法其实并不能完全避免并发修改异常。 forEach本质上还是一个循环遍历,如果在循环体内直接对集合进行修改,仍然会产生ConcurrentModificationException。 例如: List<String> lis…...
 
Linux: 设置qmake的Qt版本
Qt开发,qmake会对应一个Qt版本,有时候需要切换这个版本,例如把qmake从Qt5.12切换到Qt5.9, 怎么操作呢? 案例如下: 银河麒麟V10系统,下载安装了Qt5.9.8,但是检查qmake发现它使用的是5.12.8&…...
使用LLM插件从命令行访问Llama 2
大家好,最近的一个大新闻是Meta AI推出了新的开源授权的大型语言模型Llama 2,这是一项非常重要的进展。Facebook最初的LLaMA模型于今年2月发布,掀起了开源LLM领域的创新浪潮——从微调变体到从零开始的再创造。 如果在Llama 2版本发布之日&a…...
 
gateway过滤器没生效,特殊原因
看这边文章的前提,你要会gateway,知道过滤器怎么配置? 直接来看过滤器,局部过滤器 再来看配置 请求路径 http://127.0.0.1:8080/appframework/services/catalog/catalogSpecials.json?pageindex1&pagesize10&pkidd98…...
 
长相思追剧小游戏
看效果图 Vue长相思 刚学Vue,正好在追剧,看到这个小案例觉得挺好玩的,第一天学,代码太简陋了 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name&qu…...
leetcode做题笔记51
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 每一种…...
 
Windows同时安装两个版本的JDK并随时切换,以JDK6和JDK8为例,并解决相关存在的问题(亲测有效)
Windows同时安装两个版本的JDK并随时切换,以JDK6和JDK8为例,并解决相关存在的问题(亲测有效) 1.下载不同版本JDK 这里给出JDK6和JDK的百度网盘地址,具体安装过程,傻瓜式安装即可。 链接:http…...
 
【ChatGPT辅助学Rust | 基础系列 | Cargo工具】Cargo介绍及使用
文章目录 前言一,Cargo介绍1,Cargo安装2,创建Rust项目2,编译项目:3,运行项目:4,测试项目:5,更新项目的依赖:6,生成项目的文档…...
 
全面了解CPU Profiler:解读CPU性能分析工具的核心功能与用法
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、使用3.1 通过调用系统API3.2 通过Android Stu…...
rust format!如何转义{},输出{}?
在Rust中,如果你想要在字符串中包含花括号 {} ,你需要使用双花括号 {{}} 来进行转义。这是因为单个花括号 {} 在字符串中表示占位符,用于格式化字符串。 以下是一个示例: fn main() {let text "这是一个示例: {…...
 
真人AI写真的制作方法-文生图换脸
AI写真最近火起来了,特别是某款现象级相机的出现,只需要上传自己的照片,就能生成漂亮的写真照,这一产品再次带火了AI绘画。今天我就来分享一个使用Stable Diffusion WebUI制作真人AI写真的方法,不用训练,快…...
 
vscode如何包含第三方库
方法1:使用C Extension 在include 的 rapidjson的头文件时,vscode会提示找不到的问题 悬停,点击黄色提示 Edit "includePath" setting Include Path,输入rapidjson的include路径 /Users/xxx/workspaces/rapidjson-1.1.…...
 
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
 
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
 
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
 
Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...
 
在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...
