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

在手机上编写安卓appwordpress模板seo

在手机上编写安卓app,wordpress模板seo,常熟市网页设计公司,收录查询关于C语言连续强制类型转换,是从温度传感器中数据处理拓展讨论的一个问题。一. 温度传感器datasheet1. 图一温度结果和限制2. 图二 温度寄存器,IIC从这里读取。二. IIC接收数据到温度处理计算代码怎么写?问题的重点在于通过IIC传输数据时&…

关于C语言连续强制类型转换,是从温度传感器中数据处理拓展讨论的一个问题。

一. 温度传感器datasheet

1. 图一温度结果和限制

2. 图二 温度寄存器,IIC从这里读取。

二. IIC接收数据到温度处理计算代码怎么写?

问题的重点在于通过IIC传输数据时,是一个一个Bytes传输的,但温度数据是int16_t,如何把两个byts重组处理成int16_t?

1. 方式一

这是来自朋友的开源代码,基本写法和逻辑没有太大问题,但是比较绕哈。
uint8_t TEMP_ARRAY[2];//通过IIC从温度寄存器读取的两个BYTE温度数据。

    if(TEMP_ARRAY[0]&0x80)

        {

        zero_flag=1;

        temp=TEMP_ARRAY[0];

        temp<<=8;

        temp+=TEMP_ARRAY[1];

        temp=~temp_ct7117;

        temp+=1;

        high_byte=(temp&0xff00)>>8;

        low_byte=(temp&0x00ff);

        dot_value=high_byte;

        dot_value+=(low_byte>1)*0.0078125;

        dot_value=-dot_value;

        }

    else

        {

       

        dot_value=TEMP_ARRAY[0];

        dot_value+=((TEMP_ARRAY[1])>>1)*0.0078125;

        TEMP_Display_Vlaue=dot_value*10;

        zero_flag=0;

        }

2. 方式二,涉及C语言连续强制类型转换。

写法看起来会简单非常多。但是要理解C语言连续强制转换逻辑。

uint8_t rxBuf[2];//数组用于存储温度寄存器数据。

int32_t raw_temperature;//用于存储寄存器16bit的值,这个值是rxBuf合并计算出来的。

double temperature;//温度数据。

raw_temperature = (((int32_t)(int8_t)rxBuf[0]) << 8) | rxBuf[1];
temperature = raw_temperature * (78125e-7);//计算摄氏度温度,保留小数。

2.1. 解析:

接收到的数据被存储在无符号的数组中,首先高八位在rxBuf[0]中,通过datasheet以及C语言int16_t的数据表示可以知道,当rxBuf[0]大于等于0x80时(也可以把0x80当作无符号数据看待),温度是负数。

int8_t的十六进制0x80~0xFF表示的都是负数。int16_t数据的正负数由最高位决定。

所以第一个高八位,直接先转换成int8_t数据,接着再转换成int32_t。

2.1.1. 有符号数据的位移
操作符号位是否可能变化条件说明备注
左移<<符号位被移除时(如负数左移)若原符号位(最高位)为1(负数),左移后可能变为0(正数)
右移>>

算术右移保留原符号位高位补原符号位(负数补1,正数补0),符号位本身不变

PS:如果位移位数超过数据位数,将可能发生未知行为,依赖编译器和CPU。

接着进行左移8位的操作。左移不是会移除符号位吗?注意上面说的是可能,因为数据是补码的方式存储,并且被转换成了int32_t,一个int8_t的负数被转换成了int32_t,它的bit8~bit31会全为1,所以这时候左移不会有任何影响,总结来说当原有符号数据宽度扩展到更大的数据类型宽度时,左移不会改变数据,也不会影响符号位。

2.2. 连续强制转换逻辑:从右到左依次转换,编译器并不会直接忽略中间的转换类型。

比如:如果温度是负数时,下面第二行代码将输出错误的数值。⚠️⚠️⚠️⚠️

raw_temperature = (((int32_t)(int8_t)rxBuf[0]) << 8) | rxBuf[1];
raw_temperature = (((int32_t)rxBuf[0]) << 8) | rxBuf[1];

ok,这个方式比较适合老道的程序员,新手要谨慎,千万别依葫芦画瓢。

3. 方式三,类型只是告诉编译器、CPU应该怎么去解释处理这段内存。

0x81赋值给有符号和无符号数据是怎么识别的,甚至给double,会怎么样?

只要了解数据类型其数据的内存布局或者说表示方法,我们就可以利用这个方法直接处理。

uint8_t rxBuf[2];//从温度传感器寄存器读取的数值。
int16_t raw_temp = 0;//rxBuf温度数据重组重组成int16_t
uint16_t raw = (rxBuf[0]<<8)|rxBuf[1];//rxBuf温度数据重组重组成uint16_t
raw_temp |= raw;//按位操作。
int32_t temp = raw_temp * 0.0078125*10;//乘10是把数据放大10倍,以保留一位小数。
cout << temp<< endl;

重点看第四行,按位操作。为什么可以这么做。

类型只是告诉编译器、CPU应该怎么去解释这段内存。

利用这个规则,直接按位操作,而不是进行强制类型。

数据的整个处理过程都是按位处理和uint8_t左移处理(左移时会被隐式转换成更高的类型,所以数据无影响),所以重组前后的数据在内存中没有发生任何变化。

如果处理器支持,你甚至可以直接raw_temp = (*(int16_t * )rxBuf)。处理器需要两个满足:①内存对齐,②字节序匹配(IIC是低地址存高八位,也即大端。MCU一般是小段,低地址低八位。所以rxBuf[0]存储IIC低八位时,则满足条件。)。


3.1. 方式三的简化效率版本。

// IIC大端序传感器 → 小端序处理器。
// 以下是简化版本,执行效率最高。//方式三简化版本1
raw_temp = (*(int16_t * )rxBuf)//方式三简化版本2
int16_t raw_temp = (int16_t)( (rxBuf[0] << 8) | rxBuf[1] );

4. 方式四,方式三的安全版本。

// 使用显式字节序的联合体
int32_t decode_temperature(const uint8_t* buf)
{union {int16_t val;struct {uint8_t lsb;    //低八位,无符号。int8_t msb;  // 高八位,有符号存储 };} raw;raw.lsb  = buf[1];raw.msb  = (int8_t)buf[0];  // 强制符号转换 // 定点运算(保留3位小数)return (raw.val  * 78125LL) / 10000000;
}

这个方案是最优解,①字节大小端序的更加安全。②符号位安全无隐患。③可移植性和可读性高。

方案三的简化版本也可以使用,执行效率是最高的。

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

相关文章:

  • 凯盛建设公司网站网页设计模板html代码手机版
  • 网站大全官网徐州建设工程
  • 套别人的网站模板吗上海市企业信用信息公示系统官网
  • 公司网站用什么程序高端响应式网站开发
  • 设计师网站 知乎业务推广平台
  • 西安做网站公司魔盒局域网视频网站开发
  • 南京g3云推广上海城市分站seo
  • 网站app开发公司wordpress图片分类
  • 伪原创嵌入网站北京网站设计公司哪儿济南兴田德润简介
  • 河南教育平台网站建设宁夏百度公司
  • 重庆产品推广类网站公司部门职位
  • 代做cad平面图的网站网站会员功能
  • 网站建设论文 优帮云怎么制作网站地图
  • 关于域名和主机论坛的网站广州公司制作网站
  • 深圳网站seo推广优化公司组织架构
  • 兰州网站备案广东手机网站建设哪家专业
  • 网站建设需要钱吗营销策划岗位职责
  • 大同网站建设没有网站怎么做网推
  • 电子销售网站报表模块如何做禁用wordpress自动保存插件
  • 网站设计创意方案黑龙江省城乡和住房建设厅网站首页
  • 实力网站建设oppo手机应用商店
  • 手机分销网站江苏城乡建设教育网站
  • 中国建设银行嵊州市支行网站网站制作 流程
  • 荆州网站建设多少钱wordpress头像上传插件
  • 三五互联网站密山网站
  • 给别人做网站赚钱吗给网站人做网站
  • 怎么注册网站农商1号的网站建设费
  • 长治企业网站建设价格西安微网站开发
  • 杰奇怎么做网站地图北京昨晚出什么大事
  • 做宠物网站心得制作一个网站多少钱啊