理解C语言中的位操作和整数类型:一个温度传感器读取问题的解析

前言:当我们编写嵌入式系统的代码时,我们经常需要使用位操作来处理硬件设备的数据。然而,如果我们对C语言的位操作和整数类型不完全理解,可能会遇到一些难以理解的问题。在这篇博客中,我将通过一个实际的例子来解释这些概念,并提供一个解决方案。

问题描述

我们有一个函数,用于读取一个温度传感器(MPU6050)的数据。这个函数通过I2C接口从传感器读取两个字节的数据,然后通过位操作将这两个字节合并成一个16位的整数。然后,这个整数被转换为实际的温度值。

然而,我们发现了一个问题。当我们将这个16位的整数定义为int类型时,我们得到的温度值大约是208。但是当我们将它定义为int16_t类型时,我们得到的温度值是25,这是一个正常的温度值。那么,为什么会出现这种情况呢?

问题分析

在C语言中,int类型的大小是平台相关的,它可以是16位,32位,或64位。而int16_t是一个明确的16位整数。在我们的例子中,问题的关键在于位操作。

我们的代码中有这样一行:(data[0] << 8 | data[1])。这是一个位操作,它将data[0]左移8位,然后与data[1]进行位或操作。如果data[0]的最高位(符号位)是1(也就是说,它是一个负数),那么在32位或64位的int中,这个位移操作会将高位填充为1,这是因为C语言的位移操作是带符号的。这将导致整个int变得非常大,这就解释了为什么我们看到的结果是208。

而当我们将这个16位的整数定义为int16_t类型时,位移操作只会在16位内进行,因此即使data[0]的最高位是1,也不会影响整数的其他位,因此我们得到了正确的结果。

解决方案

解决这个问题的方法很简单:我们需要明确地使用int16_t类型来定义我们的16位整数。这样,无论我们的平台的int类型是多少位,我们都可以得到正确的结果。

这是修正后的代码:

void MPU6050_Read_Temperature(double *temperature) {uint8_t data[2];M_I2C_Reicive_Byte(MPU6050_TEMP_OUT_H, &data[0]);M_I2C_Reicive_Byte(MPU6050_TEMP_OUT_L, &data[1]);int16_t sum = (data[0] << 8 | data[1]);*temperature = sum / 340.0 + 36.53;
}

结论

在使用位操作运算符时,应当注意所使用变量类型,避免将符号数误判为数据写入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/828182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git之常见的license及其适用场景

Git之常用license MIT License 特点 MIT 许可证是一种非常宽松的许可证&#xff0c;允许在几乎所有项目中自由使用、修改和分发源代码或二进制形式。它几乎没有使用限制和责任限制。 适用场景 MIT 许可证非常适合开源项目&#xff0c;尤其是那些希望被广泛使用和采纳的项目…

在ubuntu上搭建nexus私有仓库(指定版本以及jdk!)

前言 本来以为搭建一个nexus随随便便就好了&#xff0c;但是遇到了最新版本根本没办法在jdk17下面正常运行—起码我调了一下不知道怎么运行&#xff0c;我才知道。。。不升级版本其实是很有道理的。 这一篇是最新版本的尝试&#xff1a; 在ubuntu上搭建nexus私有仓库[失败草稿…

升级 jQuery:努力打造健康的 Web 生态

jQuery 对 Web 的影响始终是显而易见的。当 jQuery 在 2006 年首次推出时&#xff0c;几乎立即成为 Web 开发人员的基本工具。它简化了 JavaScript 编程&#xff0c;使操作 HTML 文档、处理事件、执行动画等变得更加容易。从那时起&#xff0c;它在 Web 标准和浏览器功能的演变…

从0开始用C写贪吃蛇(基于链表)

目录 1. 游戏背景 2. 游戏效果演示​编辑​编辑​编辑 3. 实现目标 4. 技术要点 5. 控制台程序 5.1 设置控制台窗口的长宽和名字 5.2 控制台屏幕上的坐标COORD 6.Win32 API 6.1 GetStdHandle 6.2 GetConsoleCursorInfo 6.3 CONSOLE_CURSOR_INFO 6.4 SetConsole…

Docker 网络与资源控制

一 Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根 据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默 认网关。因为在同…

带头循环双向链表专题

1. 双向链表的结构 带头链表⾥的头节点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位节点不存储任何有效元素&#xff0c;只是站在这⾥“放哨 的” “哨兵位”存在的意义&#xff1a; 遍历循环链表避免死循环。 2. 双向链表的实现 2.1双向链表结构 typedef int DataTyp…

最新AI创作系统ChatGPT网站源码Midjourney-AI绘画系统,Suno-v3-AI音乐生成大模型。

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

Java-校验规则Integer使用 @NotEmpty注解报错

ApiModelProperty(value "小组id")NotEmpty(message "小组id 不能为空")private Integer teamId; 1.假如不小心Integer使用NotEmpty注解报错 提示&#xff1a; No validator could be found for constraint javax.validation.constraints.NotEmpty va…

Ubuntu终端自动补全

文章目录 前言配置安装zsh安装 oh-my-zsh安装自动补全插件zsh-autosuggestions 参考 前言 Oh My Zsh 是一个针对命令行 shell 的开源框架&#xff0c;主要用于增强和美化命令行环境。它建立在 Zsh&#xff08;一种强大的 shell 替代品&#xff09;之上&#xff0c;提供了丰富的…

Kubernetes Kubelet 的 Cgroups 资源限制机制分析

前言 容器技术的两大技术基石&#xff0c;想必大家都有所了解&#xff0c;即 namespace 和 cgroups。但你知道 cgroups 是如何在 kubernetes 中发挥作用的吗&#xff1f;kubelet 都设置了哪些 cgroups 参数来实现对容器的资源限制的呢&#xff1f;本文就来扒一扒 Kubernetes k…

深度学习框架比较:TensorFlow vs PyTorch

TensorFlow和PyTorch是目前最流行的两个深度学习框架。它们都提供了强大的功能和灵活性&#xff0c;用于构建和训练复杂的深度学习模型。但是&#xff0c;它们在设计理念、用户体验和特定用例支持方面存在一些差异。以下是TensorFlow和PyTorch之间的比较&#xff0c;涵盖了它们…

使用队列对二叉树进行广度遍历

我们要对二叉树进行广度遍历&#xff0c;经典的数据结构就是队列&#xff0c;这也是许多算法题中要用到的基础&#xff0c;下面是一些基本思想 我们首先创建一个队列&#xff0c;开始遍历二叉树&#xff0c;这里记录一个值len&#xff0c;表示当前层有多少个元素&#xff0c;当…

Qt | 键盘事件

Qt | 鼠标事件第四节十、键盘事件 1、Qt 使用 QKeyEvent 类来描述与键盘有关的信息,比如按下或释放键的代码,使用枚举类型 QEvent::Type 描述与键盘有关的事件,比如 QEvent::KeyPress 表示键盘按下事件, QEvent::KeyRelease表示键盘释放事件等。 2、是否接收键盘事件,最…

STC8H8K64U I2C主机模式相关寄存器

STC8H8K64U I2C主机模式相关寄存器 STC8H8K64U-TSSOP20 I2CCFG I2C配置寄存器 I2CMSCR I2C主机控制寄存器 I2CMSST I2C主机状态寄存器 I2CMSAUX I2C主机辅助控制寄存器 I2CTXD I2C数据发送寄存器 I2CRXD I2C数据接收寄存器 I2CCFG I2C配置寄存器 B7ENI2C ENI2C&#xff1a…

文件多进程、多线程访问

处理多进程和多线程的文件读写操作需要确保对共享资源的访问是同步的&#xff0c;以防止数据竞争和不一致性。以下是一些常用的策略和工具&#xff1a; 多线程同步&#xff1a; 内置锁 (synchronized 关键字)&#xff1a;使用 Java 的 synchronized 关键字对代码块或方法进行同…

Android Compose页面跳转Demo

1.引入依赖 //jetpack compose导航 implementation("androidx.navigation:navigation-compose:2.5.3") 2.代码 import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundat…

基于Spring Boot的家具销售电商平台设计与实现

基于Spring Boot的家具销售电商平台设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 系统功能界面图&#xff0c;在系统首页可以查看首页…

Web集群_02

Web集群_01 Keepalived 概述 Keepalived实现了高可用集群 Keepalived最初是为LVS设计 , 专门监控各种服务器节点的状态 Keepalived 后加入了 VRRP 功能 , 防止单点故障 VRRP ( 虚拟冗余路由协议 ) VRRP能在不改变网组的情况下 , 将多台路由器虚拟成一个虚拟路由器 , 通过配…

【ZZULIOJ】1079: a+b(多实例测试2)(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy 提示 code 题目描述 计算AB 输入 输入数据有多组。 每组一行&#xff0c;为整数A, B。 输出 对每行输入&#xff0c;输出AB的值&#xff0c;单独占一行。 样例输入 Copy 1 2 3 4样例输出 Copy 3 7 提示 …

川宁生物环保方面优势明显合成生物学赋能未来

川宁生物一直秉持着"树立全球抗生素行业环保典范"的理念&#xff0c;在环保方面进行了大量的投入&#xff0c;总计超过27亿元人民币&#xff0c;占项目总投资的30%以上。川宁生物建设了一个占地面积超过300亩的环保系统&#xff0c;占厂区总面积的20%以上。在中国对抗…