STM32初始化结构体变量时成员排序的问题

2023-11-10

平台:STM32F103RCT6+MDK
笔者在调试时发现,结构体不同类型成员的定义顺序对于程序运行过程中的取值可能会产生很大的BUG
开始时定义:

/***********************输入参数结构体**********************/
typedef struct {
u8 TempRange;			//温度最大值 ℃
float PressRange;		//压力范围 Kpa
u8 HandTemp;			//手工温度 ℃
float HandPress;		//手工压力 Kpa
HORA HandOrAutoTemp;	//手工or自动温度 此处数据类型为枚举类型
HORA HandOrAutoPress;	//手工or自动压力 此处数据类型为枚举类型
}INPUTSTRUCT;

INPUTSTRUCT InputPara={			/*输入界面数据*/
100,							//温度范围 -50~?
101.32f,						//压力范围
0,								//手工温度值
0.0f,							//手工压力值
Manual,							//手工/自动? 手工
Manual							//手工/自动? 手工
};

在以上的定义中,编译无警告无错误,程序正常运行,但是在整个程序里面调用的所有float类型数据都不会是定义时候的值!即使有的float数据不是在本结构体变量中定义的,调用的值也会异常!而其他的不管是字符型,整型或者枚举类型都不会有错误
经过漫长的DEBUG,终于定位问题所在:

float PressRange;		//压力范围 Kpa
u8 HandTemp;			//手工温度 ℃

交换位置
结构体定义和变量定义修改为:

/***********************输入参数结构体**********************/
typedef struct {
u8 TempRange;			//温度最大值 ℃
u8 HandTemp;			//手工温度 ℃
float PressRange;		//压力范围 Kpa
float HandPress;		//手工压力 Kpa
HORA HandOrAutoTemp;	//手工or自动温度
HORA HandOrAutoPress;	//手工or自动压力
}INPUTSTRUCT;

INPUTSTRUCT InputPara={			/*输入界面数据*/
100,							//温度范围 -50~?
0,								//手工温度值
101.32f,						//压力范围
0.0f,							//手工压力值
Manual,							//手工/自动? 手工
Manual							//手工/自动? 手工
};

编译下载,程序运行正常,所有的float变量也恢复正常!

奇怪的是,在另一个结构体定义中,float的顺序并没有对整个程序造成影响:

DEBUGSTRUCT DebugPara={			/*调试界面数据*/
50.0f,							//流量系数
9.8f,							//重力加速度
0.27f,							//风阻系数
5.0f,							//节流件宽度
10.0f,							//总质量
200.0f,							//等效力臂
200.0f,							//节流件长度
10.0f,							//保留长度
0,								//手工零点
Relative,						//相对/绝对? 相对零点
Baud9600,						//波特率
0x00,							//模块地址
0,								//静态置零
50.0f,							//K0范围
0,								//K1范围
... ...
};

对于float变量,内存中的储存方式是以指数方式存储的,这是浮点数与其他类型数据在内存上的存储区别。所以笔者猜测,在定义结构体时,由于偶尔的一次排序差别导致float数据在内存上偏移了n个字节,MCU在取值时每次都取了错误的float数据,导致取值与原本的值有很大差别。
而有时候在定义成员时,由于成员之间的排列顺序正好弥补了本该产生的字节对不齐(如笔者举的第二个例子)所以会“负负得正”正好没有出现问题。

由于该问题没有一个确切的产生时机,所以在每次出现这种bug时无法精确定位到关键所在,目前的办法是,定义变量时不对变量赋初值,定义好变量之后再对各个成员进行赋初值,这样不会产生bug:

INPUTSTRUCT InputPara;
int main(void)
{
	InputPara.TempRange=100;			//温度最大值 ℃
	InputPara.PressRange=101.32f;		//压力范围 Kpa
	InputPara.HandTemp=0;			//手工温度 ℃
	InputPara.HandPress=0.0f;		//手工压力 Kpa
	InputPara.HandOrAutoTemp=Manual;	//手工or自动温度
	InputPara.HandOrAutoPress=Manual;	//手工or自动压力
	... ...
}

以上这种办法就可以不考虑结构体成员的排序问题,也不会产生错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32初始化结构体变量时成员排序的问题 的相关文章

随机推荐

  • 【创作赢红包】Python第3章 流程控制

    这里写目录标题 本章导读 真值测试 比较运算 成员运算 for循环 while循环 项目实训1 项目实训2 项目实训3 项目实训4 项目实训5 项目实训6 项目实训7 项目实训8 项目实训9 项目实训10 项目实训11 项目实训12 项目实
  • ​在可视化大屏中轻松完成机器学习建模和调参应用实例

    Streamlit 是一个开源 Python 库 可帮助开发人员为其系统创建交互式图形用户界面 它专为机器学习和数据科学家团队设计 使用 Streamlit 我们可以快速创建交互式 Web 应用程序并进行部署 前端工作对数据科学家来说并不重
  • 互联网生活中的隐私保护:用隐私换便利还是花钱护隐私?

    近日 某高校毕业生在校期间窃取学校内网数据 收集全校学生个人隐私信息的新闻引发了人们对互联网生活中个人信息安全问题的再度关注 在大数据时代 算法分发带来了隐私侵犯 在享受消费生活等便捷权利的同时 似乎又有不少个人信息泄露的担忧 用隐私换便利
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • Python 函数的说明文档

    视频版教程 Python3零基础7天入门实战视频教程 用 备注说明 然后我们调用函数的地方 鼠标移动上去就能看到函数的说明 提供代码的可读性 def add x y 两数相加函数 param x 两数相加数x param y 两数相加数y
  • matlab中Img(:,:,n)函数的说明

    Img n 中 n可以取1 2 3分别代表img图像的第1 2 3通道 即对应着R G B三种颜色 也就是说 Img 1 是红色分量图像 Img 2 是绿色分量图像 Img 3 是蓝色分量图像 具体也可通过如下一段函数定义可以看出 img
  • zabbix使用手册

    1 添加主机组 将多个主机合并在一个逻辑组件内即为主机组 分组的目的是将同一属性的主机归类 方 便以后管理 例如以业务指标划分组 以系统版本划分组 以应用程序划分组等 主机组中可以包含主机 也可以包含模板 进入zabbix管理界面 单击 配
  • 手把手教你运行yolov6 (小白版教程)

    一 yolov6的介绍 二 yolov6的吐槽 三 yolov6运行详解 前言 自己运行yolov6的完整教程 一 yolov6的介绍 我在此应用美团视觉部官方的说法叙述一下yolov6 YOLOv6 是美团视觉智能部研发的一款目标检测框架
  • 【Linux】VMware安装unbuntu18.04虚拟机-超详细步骤(附镜像文件)

    这次为大家带来的是在VMware创建的虚拟机上安装ubuntu18 04桌面版系统 ubuntu18 04也是目前比较流行的一个linux系统版本 接下来就一起来实操吧 文章目录 一 环境准备 二 创建虚拟机 三 安装虚拟机 一 环境准备
  • 包、模块、函数

    包 模块 函数 一 while循环与使用场景 1 while循环 counter 1 while counter lt 10 counter 1 print counter else print EOF 运行结果 2 3 4 5 6 7 8
  • 邮件发送原理和实现

    邮件发送 拓展 MIME 多用途互联网邮件扩展类型 就是附件 1 准备工作 获取QQ邮箱权限 测试代码 package com jyw import com sun mail util MailSSLSocketFactory import
  • wifi名称可以有空格吗_是真的吗?WiFi名称后面带“5G”,网速会更快?

    要想体验快到飞起的千兆网速 感受全屋覆盖的满分信号 移动全千兆 你值得拥有 千兆5G 无论是旅途中紧急处理工作 文件 图片秒传秒下 还是在外时与家人视频问候 无卡顿低延迟 用千兆5G 网速始终快人一步 千兆宽带 品质生活从品质宽带开始 用千
  • AcWing--756. 蛇形矩阵

    输入两个整数 n 和 m 输出一个 n 行 m 列的矩阵 将数字 1 到 n m 按照回字蛇形填充至矩阵中 具体矩阵形式可参考样例 输入格式 输入共一行 包含两个整数 n 和 m 输出格式 输出满足要求的矩阵 矩阵占 n 行 每行包含 m
  • Linux——使用第三方库链接的方式——动态式

    回顾上文 122条消息 Linux使用第三方库链接的使用方式 静态式 橙予清的zzz 的博客 CSDN博客https blog csdn net weixin 69283129 article details 131414804 spm 1
  • 【qiankun】微前端在项目中的具体使用

    1 安装qiankun npm install qiankun save 2 主应用中注册和配置qiankun 在主应用的入口文件main ts中 引入qiankun的注册方法 import registerMicroApps start
  • java/php/net/python健身房管理系统设计

    本系统带文档lw万字以上 答辩PPT 查重 如果这个题目不合适 可以去我上传的资源里面找题目 找不到的话 评论留下题目 或者站内私信我 有时间看到机会给您发 系统设计 4 1 系统体系结构 健身房管理系统的结构图4 1所示
  • mysql localhost值_jdbc:mysql://localhost:3306/mysql这句话中localhost具体指什么的localhost?能修改么?在哪里配置的?...

    展开全部 jdbc mysql 是指JDBC连接方式 localhost 是指你的本机地址 3306 SQL数据库的端口 jdbc 就是你要连接的32313133353236313431303231363533e59b9ee7ad94313
  • Mysql 8.0修改密码

    1 mysql u root p 原来的密码 进入数据库中 2 show databases 3 use mysql 4 使用下面的语句修改密码 ALTER USER root localhost IDENTIFIED WITH mysql
  • 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接

    驱动程序无法通过使用安全套接字层 SSL 加密与 SQL Server 建立安全连接 错误 The server selected protocol version TLS10 is not accepted by client prefe
  • STM32初始化结构体变量时成员排序的问题

    平台 STM32F103RCT6 MDK 笔者在调试时发现 结构体不同类型成员的定义顺序对于程序运行过程中的取值可能会产生很大的BUG 开始时定义 输入参数结构体 typedef struct u8 TempRange 温度最大值 floa