单片机(STM32)与上位机传输浮点数
目录
- 单片机(STM32)与上位机传输数据的方法
- 1. 传输整形数据
- 2. 传输浮点数据
- 3. 如何打包与解包
单片机(STM32)与上位机传输数据的方法
在进行单片机程序的开发时,常常需要与其他设备进行通信。一种情况是与其他电路板通信,比如STM32主机与STM32从机通信,STM32从机与树莓派主机通信。一种情况是与上位机通信,上位机软件进行人机交互。这个时候需要进行数据传输,传输数据有两种方式,传输整形数据与直接传输浮点数据。
1. 传输整形数据
一种方法是传输整形数据,工业中常用的Modbus就是这种方式。这里以传输16位整形数据为例,一个数据就占用两个字节,可以是正数和负数。
测试代码:
int main()
{uint16_t me, you;uint8_t data[100];me = 120;data[0] = me >> 8;data[1] = me;you = (uint16_t)data[0] << 8 | (uint16_t)data[1];printf("you = %d", you);return 0;
}
出来的结果是一样的120
那么负数怎么办呢?其实是一样的。不管是uint16_t还是int16_t,在内存中的存储都是一样的,区别不在于写,而在于怎么读。
int main()
{uint16_t me, you;uint8_t data[100];int16_t para;me = -120;data[0] = me >> 8;data[1] = me;you = ((uint16_t)data[0] << 8 | (uint16_t)data[1]);para = (int16_t)((uint16_t)data[0] << 8 | (uint16_t)data[1]);printf("me = %d\n", me);printf("me = %d\n", (int16_t)me);printf("you = %d\n", (int16_t)you);printf("para = %d", para);return 0;
}
结果:
上面me是一个uint16_t
类型,怎么能直接让它等于-120呢?当然是可以的,只不过调用me
的时候,是按照uint16_t
类型读取的,结果就是65416,如果按照int16_t
类型读取,结果就是-120。
同理,you
也是一个uint16_t
类型,you = ((uint16_t)data[0] << 8 | (uint16_t)data[1])
是按照移位拷贝的方式将me
的值赋给了you
,只要按照int16_t
类型读取出来,结果就是正确的负数。
理解了这种思想,在进行单片机与其他设备通信的时候,就可以定义一个数组,uint16_t register1[1000]
,数组的索引就是数据地址,一个萝卜一个坑。第二个设备(其他单片机或电脑)同样定义一个数组,uint16_t registe2[1000]
,按照上面的方法一个数据一个数据传输就行了。
再次注意:直接定义无符号数组即可,传输负数时直接赋值,只要另一端收到数据后按照int16_t
类型读取,结果就是正确的负数。
2. 传输浮点数据
传输整形方法的缺点是:(1)不能直接传输浮点数,传输浮点数时需要进行倍数处理。例如0.12,将其乘100变成整形的12,上位机收到后除100变成浮点型的0.12。这种方法较麻烦,哪些地址的数据需要进行倍数,需要下位机和上位机同时定义清楚。(2)有符号和无符号类型数据区分。uint16类型数据较简单,直接传输,直接解析,没问题。int16上位机解析时,就需要进行类型转换了。哪些地址的数据要进行(int16_t)类型转换,也要定义清楚。(3)表示的数据范围有限,16位整形无符号数只能到65535,有符号数除2减半。如果是浮点数,乘掉了倍数,表示范围直接缩水。如果是翻100倍,只能表示到655。
所以,最方便的就是直接传输浮点数,省去很多麻烦。当然浮点数的缺点就是,一个数据要占用4个字节。因此效率是传输整形数据的一半。
传输浮点数,需要定义一个联合体:
union float_data
{float f_data;uint8_t byte[4];
};
f_data
和byte[4]
共用4个字节的内存单元,成员f_data
是实际使用的数据,成员byte[4]
是通信时用的数据,各司其职。
使用方法:
#include <stdio.h>
#include <stdint.h>union float_data
{float f_data;uint8_t byte[4];
};int main()
{union float_data me, you;me.f_data = 0.12;you.byte[3] = me.byte[3];you.byte[2] = me.byte[2];you.byte[1] = me.byte[1];you.byte[0] = me.byte[0];printf("you = %f", you.f_data);return 0;
}
出来的结果是一样的,0.12。聪明的读者可以发现,me
和you
对应两个设备。只要按照这种方式进行传输,就可以传输浮点数。传输多个浮点数,me
和you
就可以定义为一个数组,例如me[100]
, you[100]
。
3. 如何打包与解包
知道了数据如何传输,第二步就是思考如何进行数据打包和解包了,因为一个数据帧当然是要传输多个数据的。需要两个设备定义好通信协议,才能正确的解析数据。
数据打包也有两种方式,一种按照功能字,一种按照地址——数据对。
(1)按照功能字
这种方法用一个数据位表示功能字,对方设备收到这一帧数据,根据这个功能字就能判断你这一帧数据是什么,然后进行解析。例如一款陀螺仪的数据上传协议为:
它用第一个字节表示帧头,0x55,第二个字节表示功能字,0x52是角速度输出,0x53是角度输出,单片机读陀螺仪的数据时,按照它给定的这个协议,依次把数据读出来就可以了。
如果是自己定义通信协议,也可以模仿,这种方式每一帧数据都要进行定义,优点是物理意义明确,缺点是一旦确定了,如果想要修改,两端的设备要同时修改。
(2)按照地址数据对
这种方法模拟计算计的存储方式,为每一个数据安排一个地址,请注意这个地址并需要是真正的内存地址,它的核心是“索引”。例如一个数据就可以实现这种功能。uint16_t data[100]
,数组的索引就是地址。例如我用data[0]
表示姓名,data[1]
表示年龄。那么姓名的地址就是0,年龄的地址就是1。
这种方法的优点和缺点与第一种方法相反,物理意义不明确,但移植性强、维护性好。
下面是我自创的一种通信协议,传输浮点数。前两个字节为帧头,不同帧头分别代表从机主动上传、主机下发修改数据、主机下发查询数据。(这种通信协议为一对一,不支持总线通信)
(1)单片机主动上传数据:
发送N个数据(32 bits)一共4N+6个帧字节。
(2)上位机下发更改数据:
发送N个数据(32bits)也是一共2N+6个帧字节。
(3)上位机下发查询数据:
查询从起始地址开始的N个数据,查询帧是6个字节。下位机收到数据按照上传数据格式上传。
相关文章:
单片机(STM32)与上位机传输浮点数
目录 单片机(STM32)与上位机传输数据的方法1. 传输整形数据2. 传输浮点数据3. 如何打包与解包 单片机(STM32)与上位机传输数据的方法 在进行单片机程序的开发时,常常需要与其他设备进行通信。一种情况是与其他电路板通信,比如STM32主机与STM32从机通信&…...
50etf期权交易规则杠杆怎么计算?
今天带你了解50etf期权交易规则杠杆怎么计算?近年来,期权交易在股票市场中变得愈发流行,其中50ETF期权备受关注。作为一种金融衍生品,50ETF期权为投资者提供了更灵活的投资方式和更多的策略选择。 50etf期权交易规则杠杆怎么计算&…...
鸿蒙: 基础认证
先贴鸿蒙认证 官网10个类别总结如下 https://developer.huawei.com/consumer/cn/training/dev-cert-detail/101666948302721398 10节课学习完考试 考试 90分合格 3次机会 1个小时 不能切屏 运行hello world hvigorfile.ts是工程级编译构建任务脚本 build-profile.json5是工程…...
2024年最佳插电式混合动力电动汽车
对电动汽车充满好奇和环保意识的司机们还没有准备好跨入纯电动汽车,他们可以找到一个折衷方案,即插电式混合动力车。 在过去的16年里,我一直在把握汽车行业的脉搏。试驾数百辆汽车、电动汽车、插电式混合动力车,跟踪汽车行业的新闻…...
上海交通大学、中科大 开源镜像站停止 Docker Hub 仓库镜像支持后的可用替代源
上海交通大学 Linux 用户组发布公告: 即时起中止对 Docker Hub 仓库的镜像。Docker 相关工具默认会自动处理失效镜像的回退,如果对官方源有访问困难问题,建议尝试使用其他仍在服务的镜像源。 源加速地址 有网友表示百度的 Docker Hub 加速器…...
【Linux】shell——条件判断test,各种运算符,expr
条件判断——test 真——0 假——1 test expression or [ expression ] 整数运算符 字符串运算符 -z 长度是否为0 -n 长度是否不为0 str1 str2 str1 ! str2 补 &&-->逻辑与,前面为真后面才会执行 || -->逻辑或,前面为假后面才…...
中介子方程二十二
X$XFX$XdXuXWXπX$XWXeXyXeXyXeXWX$XπXWXuXdX$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpXVX$XdXuXWXπX$XWXeXyXeXyXeXWX$XπXWXuXdX$XVXpX$XyXtXkXrXiXαX$XiXαXyXEX$XFX$XEXyXαXiX$XαXiXrXkXtXyX$XpXVX$XdXuXWXπX$XWXeXyXeXyXeXWX$XπXWXuXdX$XVXpX$XyXtXkXrXiXαX$XiXαXyXEX$…...
你还不会选ProfiNET和EtherCAT网线?
在现代工业自动化领域,ProfiNET和EtherCAT是两种非常流行的通信协议。选择合适的网线对于确保通信的稳定性和效率至关重要。 ProfiNET是什么? ProfiNET是一种基于以太网的通信协议,由德国西门子公司开发。它支持实时通信,广泛应用…...
醉美酒话:承载着深厚文化底蕴的敬酒词
这些敬酒词凝聚了中华酒文化的精髓,每一句都体现了对美好愿景的深深祝愿,同时也展示了中文语言的丰富与魅力。 一、“步步高升”酒: 第一杯,酒至三分,象征着龙洒点滴、财运将至。我衷心祝愿您财富如江水般滚滚而来&a…...
vue3-sfc-loader动态加载一个异步vue组件生成cesium画面
在 Vue.js 3 中,使用 vue3-sfc-loader 可以动态加载异步的 Vue 单文件组件(.vue 文件)。这个工具允许你在运行时根据需要加载和解析 .vue 文件,使得组件的加载变得更加灵活和动态。 下面是一个简单的示例,演示如何使用…...
flink学习-状态管理
状态管理 在flink中,算子可以分为无状态和有状态两种情况。 无状态的算子只需要观察每个独立事件,根据当前输入的数据直接输出结果。像:filter、flatMap、map都属于无状态的算子。 有状态的算子则是除当前数据之外,还需要一些其他…...
OpenCV图像算术位运算
一 图像相加 import cv2 import numpy as npgirlcv2.imread(./2037548.jpg)#图像的加法运算就是矩阵的加法运算 #因此加法运算的两张图必须是相等的print(girl.shape)imgnp.ones((1920,1080,3),np.uint8)*50 cv2.imshow(girl,girl) resultcv2.add(girl,img) cv2.imshow(result…...
【调试笔记-20240611-Linux-配置 OpenWrt-23.05 支持泛域名 acme 更新】
调试笔记-系列文章目录 调试笔记-20240611-Linux-配置 OpenWrt-23.05 支持泛域名 acme 更新 文章目录 调试笔记-系列文章目录调试笔记-20240611-Linux-配置 OpenWrt-23.05 支持泛域名 acme 更新 前言一、调试环境操作系统:Windows 10 专业版调试环境调试目标 二、调…...
ssm宠物网站系统-计算机毕业设计源码07183
摘 要 在信息飞速发展的今天,网络已成为人们重要的信息交流平台。宠物网站每天都有大量的信息需要通过网络发布,为此,本人开发了一个基于B/S(浏览器/服务器)模式的宠物网站系统。 该系统以JJava编程语言、MySQL和SSM框…...
想上币的项目方怎么去选择交易所
在区块链和加密货币蓬勃发展的今天,许多项目方都渴望通过交易所上线其代币,以扩大影响力、提升流动性和市场认可度。然而,选择合适的交易所并非易事,它关乎项目的未来发展和市场地位。那么,对于有上币意向的项目来说&a…...
mysql如何创建并执行事件?
在 MySQL 中,事件调度器允许您在指定的时间间隔执行 SQL 语句。这类似于操作系统中的计划任务(如 cron 作业)。 前提条件 确保您的 MySQL 服务器已启用事件调度器。可以通过以下命令检查并启用: SHOW VARIABLES LIKE event_scheduler;如果返回的值是 OFF,可以通过以下命…...
k8s环境里查看containerd创建的容器对应的netns
如何查看containerd创建的容器对应的netns 要查看由 containerd 创建的容器对应的网络命名空间(netns),你可以遵循以下步骤。这个过程涉及到了解容器的 ID,以及使用 ctr 命令或其他方式来检索容器的详细信息。这里假定你已经具备…...
学习笔记——网络管理与运维——SNMP(基本配置)
四、SNMP基本配置 1、SNMP配置举例 整个华为数通学习笔记系列中,本人是以网络视频与网络文章的方式自学的,并按自己理解的方式总结了学习笔记,某些笔记段落中可能有部分文字或图片与网络中有雷同,并非抄袭。完处于学习态度&#x…...
CMake从安装到精通
目录 引言 1. CMake的安装 2. CMake的原理 3. CMake入门 3.1 CMakeLists.txt与注释 3.2 版本指定与工程描述 3.3 生成可执行程序 3.4 定义变量与指定输出路径 3.5 指定C标准 3.6 搜索文件 3.7 包含头文件 4. CMake进阶 4.1 生成动静态库 4.2 链接动静态库 4.…...
【C++】认识STL
【C】认识STL STL的概念STL的版本STL的六大组件STL的三个境界STL的缺陷 STL的概念 SLT(standard template libaray-标准模板库):是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个保罗数据结构与算法的软件框架。 STL的版本 原…...
力扣 50.pow(x,n)
class Solution { public: double quickMul(double x,long long N){ if(N0) return 1; double valuequickMul(x,N/2); return N%20?value*value:value*value*x; } double myPow(double x, int n) { long long Nn; return N>0?quickMul(x, N):1.0/quickMul(x, N); } };...
R可视化:微生物相对丰度或富集热图可视化
欢迎大家关注全网生信学习者系列: WX公zhong号:生信学习者Xiao hong书:生信学习者知hu:生信学习者CDSN:生信学习者2介绍 热图(Heatmap)是一种数据可视化方法,它通过颜色的深浅或色调的变化来展示数据的分布和密度。在微生物学领域,热图常用于表示微生物在不同分组(如…...
Unity Maximum Allowed Timestep的说明
Maximum Allowed Timestep的说明 关于Maximum Allowed Timestep这个配置的说明,Unity有一份官方的说明。 Time-maximumDeltaTime - Unity 脚本 API 结合Unity的函数执行顺序,我们可以简单理解为: FixedUpdate在1次Update可能会执行N次&am…...
长短期记忆神经网络(LSTM)的回归预测(免费完整源代码)【MATLAB】
LSTM(Long Short-Term Memory,长短期记忆网络)是一种特殊类型的递归神经网络(RNN),专门用于处理和预测基于时间序列的数据。与传统RNN相比,LSTM在处理长期依赖问题时具有显著优势。 LSTM的基本…...
关于 python request 的 response 返回 b‘\xa3\xff\xff\x11E .....‘ 类型的数据的解决方案
最近写开发一个爬虫, 程序在本地好好的,返回的是正常的 html, 但是到了生产环境,不知道为什么返回的是一堆乱码 长这样: 查了好几天都没有进展, 对其进行各种转码均无效 今天终于找到解决办法了ÿ…...
后端高频面试题分享-用Java判断一个列表是否是另一个列表的顺序子集
问题描述 编写一个函数,该函数接受两个列表作为参数,判断第一个列表是否是第二个列表的顺序子集,返回True或False。 要求 判断一个列表是否是另一个列表的顺序子集,即第一个列表的所有元素在第二个列表需要顺序出现。列表中的元…...
【数据初步变现】论自助BI在数字化转型中如何赋能业务
引言:数字化转型要求企业更加依赖数据来指导业务决策。自助BI作为数据分析的重要工具,能够迅速、准确地从海量数据中提取有价值的信息,为企业的战略规划和业务执行提供有力支持。在数字化时代,企业需要快速响应市场变化并优化业务…...
Python 学习 第二册 第14章 网络编程
----用教授的方式学习 目录 14.1 几个网络模块 14.1.1 模块 socket 14.1.2 模块 urllib 和 urllib2 14.1.3 其他模块 14.2 SocketServer 及相关的类 14.3.1 使用 SocketServer 实现分叉和线程化 14.3.2 使用 select 和 poll 实现异步 I/O 14.4 Twisted 14.4.1 下载…...
微信 小程序应用,页面,组件的生命周期
组件生命周期 组件的生命周期:指的是组件自身的一些钩子函数,这些函数在特定的时间节点时被自动触发 组件的生命周期函数需要在 lifetimes 字段内进行声明 最重要的生命周期是 created attached detached 包含一个组件生命周期流程的最主要时间点 定…...
代码随想录算法训练营Day41|背包问题、分割等和子集
背包问题 二维 46. 携带研究材料(第六期模拟笔试) (kamacoder.com) dp数组有两维,横轴表示背包重量j(0-j),纵轴表示不同物品(0-i),dp[i][j]即表示从下标为[0-i]的物品…...
双线主机可以做彩票网站吗/网站优化包括对什么优化
64位windows安装storm前需要先搞定zookeeper和python,所以下面我们3步走: 一、zookeeper 1、上https://zookeeper.apache.org/点击下方download到新页面,还得点一次中间的download,再选一个镜像链接http://mirrors.tuna.tsinghua.…...
网站设置了自动登录怎么显示密码/最有效的15个营销方法
首先去官网下载MySQLhttps://dev.mysql.com/downloads/mysql/5.7.html#downloads我是下载的5.7.23 zip版本,解压到C:\mysql-5.7.23-winx64然后配置环境变量:变量名:MYSQL_HOME变量值:C:\mysql-5.7.23-winx64在Path变量值最前面添加…...
logo在线设计网站/拼多多关键词优化步骤
1.自我介绍 2.项目介绍 3.项目中数据库设计 4.外键理解 5.左连接,右连接,内连接理解 6.实际应用左连接,右连接,内连接及索引 7.tcp,udp区别 8.get和post区别 9.tcp/ip协议 10.DNS解析过程 11.进程与线程区别 12.死锁理…...
wordpress是php模板吗/长春百度网站快速排名
记得有篇文章谈过,人生境界可以分为真、善、美三个阶段,技术人生也是如此。 所谓真,很简单,就是真理。搞技术的人比较单纯,往往就较“真”,认一个“理”。“我爱我师,更爱真理”。由于真&#x…...
wordpress分页出现404/友情链接建立遵循的原则包括
可以用抽象工厂模式来造车。 车的品牌有很多,而且车的属性也不少,比如车的类型、排量、门的数量,等等。可以提炼出有关车的一个抽象类: public abstract class Car{public string Model { get; set; }public string Engine { get;…...
可以做本地生活服务的有哪些网站/站长统计app
转自:江南烟雨 惊群问题的产生 在建立连接的时候,Nginx处于充分发挥多核CPU架构性能的考虑,使用了多个worker子进程监听相同端口的设计,这样多个子进程在accept建立新连接时会有争抢,这会带来著名的“惊群”问题&#…...