1.小于0度的转换

我们知道当测量的实际温度为0度以下时,temp没转换时的情况为下图所示

13.9.png

我们已经知道高5位为1表示的是负数,那么-0.5度的时候为什么是1111 1111 1111 1000。


负数的计算涉及到补码的知识。首先0xFFF8,除去高5位那就是

111 1111 1000

反码为 000 0000 0111

而补码就是反码加1,也就是补码为000 0000 1000

这样0.5就是由补码(十进制的8)乘以0.0625得来。


我们要知道,负数的时候需要关注的是temp的低11位,补码其实就是2的11次方(2048)减去temp的低11位的数值。


-55度的时候,补码为2048-0x0490=880。 转换就是880*0.0625=55。加上符号就是-55度了。


因为测量负数时只能测-0.1~-55.0,所以液晶屏的显示就有像以下两种情况

13.10.png

13.11.png


代码上我们是这样处理的


temp=temp&0x07FF;                   //清除掉高5位使其变为0

temp=2048-temp;                     //此时的temp为补码     

temp_float=(float)temp*0.0625*10.0; //实际温度值再乘以10倍

temp=(unsigned int)temp_float;      //得到16位整型的数值

  

str[0]='-';                         //添加负数的符号

str[1]='0'+( (temp/100)%10 );       //当温度在-10度以下时需要显示十位数

str[2]='0'+( (temp/10)%10 );        //温度必须显示个位数,哪怕是0,比如“-0.5”

str[3]='.';

str[4]='0'+( temp%10 );             //温度必须显示小数点后的一位

  

if(str[1]=='0')

    str[1]='-';                     //如果温度没有低于等于-10.0度(比如是-9.8度),让str[1]填充负数符号,如果温度低于等于-10.0度,那么填充负数符号的是str[0]

    LcdShowStr(0, 0, str+1);        //温度高于-10.0度,只需显示4个字符

}

else LcdShowStr(0, 0, str);         //温度低于等于-10.0度,显示5个字符


实际温度是-10.0以下的话就是显示5个字符(比如-11.7度)。

实际温度大于-10.0的话,比如-9.8度,要做到高位为0不显示,所以str[1]等于'0'时让“str[1]='-';”。这样的话“LcdShowStr(0, 0, str+1);”就是如下图显示了


13.12.png


2.再谈指针

以上两种转换方式我们整合成了一个“温度转换”的函数


unsigned char TEMP_CONV(unsigned int *temp, unsigned char *str)

{

    unsigned char res;

    float  temp_float;

     

    res = Get18B20Temp(temp);  //读取当前温度,传入的参数是指针类型

    if (res)                   //读取成功时,进行温度转换

    {

        if( (*temp>>11)==0 )   //温度大于等于0度     

        {   

            temp_float=( (float)(*temp) ) *0.0625*10.0;  //*temp就是没有转换时的16位那个变量,然后再把实际温度值再乘以10倍

            *temp=(unsigned int)temp_float;              //得到16位整型的数值

            str[0]='0'+( (*temp/1000)%10 );              //当温度大于等于100度时需要显示百位数

            str[1]='0'+( (*temp/100)%10 );               //当温度大于等于10度时需要显示十位数

            str[2]='0'+( (*temp/10)%10 );                //当温度大于等于1度时需要显示个位数

            str[3]='.';

            str[4]='0'+( (*temp)%10 );                   //温度必须显示小数点后的一位

  

            if(str[0]=='0')temp_i++;

            if(str[1]=='0')temp_i++;

  

            return 1;//读取温度成功,返回值一律为1

        } 

  

        else if( (*temp>>11)>0 )//温度小于0度     

        {

            *temp=(*temp)&0x07FF;                       //清除掉高5位使其变为0

            *temp=2048-(*temp);                         //此时的temp为补码     

            temp_float=( (float)(*temp) )*0.0625*10.0;  //实际温度值再乘以10倍

            *temp=(unsigned int)temp_float;             //得到16位整型的数值

  

            str[0]='-';                                 //添加负数的符号

            str[1]='0'+( (*temp/100)%10 );              //当温度在-10度以下时需要显示十位数

            str[2]='0'+( (*temp/10)%10 );               //温度必须显示个位数,哪怕是0,比如“-0.5”

            str[3]='.';

            str[4]='0'+( (*temp)%10 );                  //温度必须显示小数点后的一位

  

            if(str[1]=='0')

            { 

                str[1]='-';

                temp_i=1;//实际温度大于-10.0度的时候,假如是-5.4度,那么“LcdShowStr(0, 0, str+temp_i);”就是显示“-5.4”,小数点就是在第3个显示格上显示

                         //实际温度小于等于-10.0度的时候,假如是-12.6度,str[1]不等于‘0’,

                         //这样temp_i是等于0的,那么“LcdShowStr(0, 0, str+temp_i);”显示“-12.6”,小数点就是在第4个显示格上显示  

            }

  

            return 1;    //读取温度成功,返回值一律为1

        } 

    } 

      

    return 0;//读取温度不成功,返回值为0

}


这个函数在主函数里的用法就是判断返回值是否为1


if( TEMP_CONV(&temp,str)==1 )     //返回值为1代表读取温度成功


我们在主函数里定义了一个u16类型的变量temp,

传入给“unsigned char TEMP_CONV(unsigned int *temp, unsigned char *str)”的第一个参数是变量temp的指针,然后该函数执行的第一句“res = Get18B20Temp(temp);”此时传入的参数temp是个指针变量,“Get18B20Temp(temp)”函数内部的执行就是把温度数据赋给传入的指针的那个内存里,后面的“*temp”代表的就是这个内存的变量,也就是读出的未转换的温度值。

关键字:51单片机  温度传感器 引用地址:51单片机-温度传感器代码解析Ⅱ

上一篇:51单片机-温度传感器代码解析Ⅰ
下一篇:51单片机-温度传感器代码独立文件

推荐阅读

根据知名市场调查机构Gartner最新出炉的2018年第2季度全球智能手机销量排行,华为已经超过苹果成为全球第二大手机厂商。报告指出全球智能手机销量达到3.74亿台,同比增长2%。而华为增长迅速,在该季度总销量达到了4980万台,市场份额达到了13.3%,相比较去年同期的的9.8%有明显的增长。 报告中还指出苹果在该季度的销量为4470万台,市场份额为11.9%,而20...
初代芯片设计中,每次针对不同的产品都要将电路重新设计。随着芯片的迭代变快,2000年以后开始有了基于IP的设计方法,这被称为芯片设计的2.0时代。随着万物互联时代的脚步临近,对芯片成本和性能的要求也越来越高。于是,人们开始期待一种效率更高、成本更低的全新芯片设计方法。平头哥敏锐地嗅到了这一点,带来最新的一站式芯片设计平台——“无剑”,剑...
索尼已经宣布将于 2020 年 9 月 17 日欧洲中部时间上午 9 点,也就是北京时间下午 3 点举行新品发布会,预计将会推出小屏旗舰 Xperia 5 II 。现在,爆料网站 Slashleaks 已经放出了 Xperia 5 II 的官方渲染图。 IT之家了解到,索尼 Xperia 5 II 将是 Xperia 1 的缩小版,价格更低,搭载了 “带鱼屏”,屏...

史海拾趣

问答坊 | AI 解惑

单片机怎样处理LM331送来的信号

本帖最后由 paulhyde 于 2014-9-15 09:41 编辑 当将模拟信号转换成方波脉冲后,再将脉冲信号送入单片机,那么单片机是怎样处理这个脉冲信号的?  …

查看全部问答∨

求救

哪位高人有关于MSP430与CC1100点对点通信的程序?…

查看全部问答∨

FPGA QQ群:69611574 期待你的加入!

本帖最后由 paulhyde 于 2014-9-15 09:21 编辑 比赛结束了,学习没有结束,最近看论坛里有点冷清,大家要加油啊! FPGA_学生交流:69611574 期待你的加入!  …

查看全部问答∨

关于AT89S52单篇机,

你好,我刚买了上面那个型号,,但是,我烧写时,出现了编程器不存在,什么回事?…

查看全部问答∨

用软件如何实现蓝牙接收的数据转换

最近做了一个题目,使用蓝牙接收到的数据在LED点阵上显示出来,但是前提是不知道要接收的数据的内容。该如何实现接收到的数据用编程直接转换成LED点阵上能识别的二进制数。是该做一个字库还是有其他什么别的方法。请专业人士帮忙解决一下。谢谢。…

查看全部问答∨

wince启动时出错

目前通过网络下载将开发工作站上编译的wince镜像下载到目标机。现在目标机和开发工作站已经可以连接起来了,目标机上显示Jumping to 0x0013AC2C,开发工作站能出现下载进度显示界面。 但是下载结束后,出现如下Find Source的对话框,Please enter ...…

查看全部问答∨

哪位达人用过《EVC高级编程及其应用开发》这本书上基础数据库的例子?

我在wince下试了这个程序,可是不好使阿,添加不了,也删除不了,请问是还需要安装什么程序还是本身实例程序有问题啊?…

查看全部问答∨

USB虚拟串口例程从USB端发数据到串口是否一次只能了送一个

                                 USB虚拟串口例程Virtual_COM_Port没作任何修改,从USB端发数据到串口,两端都是用串口调试助手。比如从真实串口端发 ...…

查看全部问答∨

有人用verilog写过AD7685采样的代码吗?

最近在用FPGA做AD采样,芯片采用AD7685,由于刚学习fpga,如果有人弄过AD7685的话,能不能给点资料参考下。…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved