51单片机-温度传感器代码独立文件

发布者:EtherealGlow最新更新时间:2021-08-30 来源: eefocus关键字:51单片机  温度传感器 手机看文章 扫描二维码
随时随地手机看文章

创建好“ds18b20.c”和“ds18b20.h”文件,把下面代码添加进各自的文件。


1.ds18b20.c代码


我们在宋老师的代码基础上添加了温度转换函数,原理在上一讲已经讲解清楚了。


#include

#include

#include

   

unsigned char temp_i=0;//定义全局变量temp_i用来帮助液晶屏灵活显示

 

/* 软件延时函数,延时时间(t*10)us */

void DelayX10us(unsigned char t)

{

    do {

           _nop_();

           _nop_();

           _nop_();

           _nop_();

           _nop_();

           _nop_();

           _nop_();

           _nop_();

    } while (--t);

}

 

/* 复位总线,获取存在脉冲,以启动一次读写操作 */

unsigned char Get18B20Ack()

{

    unsigned char ack;

      

    EA = 0;           //禁止总中断

    IO_18B20 = 0;     //产生500us复位脉冲

    DelayX10us(50);

    IO_18B20 = 1;

    DelayX10us(6);    //延时60us

    ack = IO_18B20;   //读取存在脉冲

    while(!IO_18B20); //等待存在脉冲结束

    EA = 1;           //重新使能总中断

      

    return ack;

}

 

/* 向DS18B20写入一个字节,dat-待写入字节 */

void Write18B20(unsigned char dat)

{

    unsigned char mask;

      

    EA = 0;                             //禁止总中断

    for (mask=0x01; mask!=0; mask<<=1)  //低位在先,依次移出8个bit

    {

        IO_18B20 = 0;                   //产生2us低电平脉冲

        _nop_();

        _nop_();

        if ((mask&dat) == 0)            //输出该bit值

            IO_18B20 = 0;

        else

            IO_18B20 = 1;

        DelayX10us(6);                  //延时60us

        IO_18B20 = 1;                   //拉高通信引脚

    }

    EA = 1;                             //重新使能总中断

}

 

/* 从DS18B20读取一个字节,返回值-读到的字节 */

unsigned char Read18B20()

{

    unsigned char dat;

    unsigned char mask;

      

    EA = 0;                             //禁止总中断

    for (mask=0x01; mask!=0; mask<<=1)  //低位在先,依次采集8个bit

    {

        IO_18B20 = 0;                   //产生2us低电平脉冲

        _nop_();

        _nop_();

        IO_18B20 = 1;                   //结束低电平脉冲,等待18B20输出数据

        _nop_();                        //延时2us

        _nop_();

        if (!IO_18B20)                  //读取通信引脚上的值

            dat &= ~mask;

        else

            dat |= mask;

        DelayX10us(6);                  //再延时60us

    }

    EA = 1;                             //重新使能总中断

    

    return dat;

}

 

/* 启动一次18B20温度转换,返回值-表示是否启动成功 */

unsigned char Start18B20()

{

    unsigned char ack;

      

    ack = Get18B20Ack();   //执行总线复位,并获取18B20应答

    if (ack == 0)          //如18B20正确应答,则启动一次转换

    {

        Write18B20(0xCC);  //跳过ROM操作

        Write18B20(0x44);  //启动一次温度转换

    }

    return !ack;           //ack==0表示操作成功,所以返回值对其取非,返回值就是1了

}

 

/* 读取DS18B20转换的温度值,返回值-表示是否读取成功 */

unsigned char Get18B20Temp(int *temp)

{

    unsigned char ack;

    unsigned char LSB, MSB;                     //16bit温度值的低字节和高字节

      

    ack = Get18B20Ack();                        //执行总线复位,并获取18B20应答

    if (ack == 0)                               //如18B20正确应答,则读取温度值

    {

        Write18B20(0xCC);                       //跳过ROM操作

        Write18B20(0xBE);                       //发送读命令

        LSB = Read18B20();                      //读温度值的低字节

        MSB = Read18B20();                      //读温度值的高字节

        *temp = ((unsigned int)MSB << 8) + LSB; //合成为16bit整型数

    }

    return !ack;                                //ack==0表示操作成功,所以返回值对其取非,返回值就是1了

}

 

/* 温度转换 */

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

}

 


2.ds18b20.h代码


#ifndef __DS18B20_H__

#define __DS18B20_H__

   

sbit IO_18B20 = P3^2;                                            //DS18B20通信引脚

[1] [2]
关键字:51单片机  温度传感器 引用地址:51单片机-温度传感器代码独立文件

上一篇:51单片机-温度传感器代码解析Ⅱ
下一篇:51单片机-AD与DA合成文件

推荐阅读最新更新时间:2024-11-19 06:45

皇冠3.0轿车温度传感器的原理与检修
电喷发动机冷却液的温度是ECU决定喷油器喷油量的重要依据,进气温度则是ECU修正喷油器喷油量的重要依据。而这两种温度信号能否准确地传给ECU,温度传感器起着决定性的作用。因此,在维修养护中,对发动机温度传感器的检测至关重要。皇冠3.02JZ一GE型发动机冷却液温度传感器与进气温度传感器的结构原理及技术检测方法极为相近,现以冷却液温度传感器为主,重点介绍其结构原理及检测方法。 结构原理 冷却液温度传感器安装在汽缸体左侧的前端,外部与动力转向泵相邻,其结构如图 1(a)所示。传感器的感温元件为热敏电阻,它具有负温度一电阻系数:当温度升高时电阻值减小,温度降低时电阻值增大。ECU内部的冷却液温度信号为电桥电路,传感器的热敏电阻为臂桥电
[嵌入式]
51单片机浮点数运算原理
  单片机一般浮点数均采用士MxC的形式来表示,其中M称为尾数。它一般取为小数0≤M l,E为阶码,它为指数部分,它的基是C。C可以取各种数,对于十进制数,它一般取10,而对于二进制数,C-般取2,对于十进制数,可以很方便地把它换成十进制浮点数。对于微机系统来说,常用的浮点数均为C=2,在浮点数中,有一位专门用来表示数的符号,阶码E的位数取决于数值的表示范围,一般取一个字节,而尾数则根据计算所需的精度,取2~4字节。      浮点数也有各种各样表示有符号数的方法,其中数的符号常和尾数放在一起,即把士M作为一个有符号的小数,它可以采用原码、补码等各种表示方法,而阶码可采用各种不同的长度,并且数的符号也可以放于各种不同的地方。所以浮
[单片机]
51单片机 ret和reti
原来在8051构架中--中断系统中含有两个不可寻址的“优先级生效”触发器。一个用于指出CPU是否正在执行高优先级的中断服务程序,这个触发器为1时,系统将屏蔽所有的中断请求;另一个则指出CPU是否正在执行低优先级中断服务程序,该触发器为1时,将阻止除高优先级以外的一切中断请求。由此可见,若要响应同级甚至是低级中断请求,必须使得该“优先级生效”触发器清零。但该触发器又是不可寻址的,所以无法用软件直接清零。” 通常情况下,在普通的汇编子程序中用RET做返回,在中断服务子程序中用RETI起中断返回作用。两条指令都能从堆栈中弹出断点地址并装入PC中,使 CPU回到原来主程序的断点处继续运行。然而,RET和RETI有本质的区别:当某一中断源响
[单片机]
手把手教你学51单片机:硬件基础知识学习
一、电磁干扰 使用去耦电容来达到电磁兼容目的。 二、去耦电容的应用 类比电流和水流,可得到去耦电容的作用: (1)缓冲作用:防止电流不稳定时对电子元器件的冲击。 (2)稳定作用:稳定电压电流,使之不产生大的波动。 故该如何选取电容: (1)耐压值:一般选取系统电压的1.5倍到2倍。 (2)滤波电容:一般为0.1uf,滤除高频信号干扰,可加在电源处作为去耦高频电容。 (3)稳定电压:较大电流通过时会加大电容用来稳压。 三、三极管 3.1三极管分类 NPN、PNP 3.2三极管原理 3.2.1口诀 箭头指內PNP,导通电压顺箭头过,电压导通,电流控制。 3.2.2电流控制 三极
[单片机]
手把手教你学<font color='red'>51</font><font color='red'>单片机</font>:硬件基础知识学习
51单片机快热式热水器程序
/*-------------------------------------- 快热式热水器程序 MCU AT89C51 XAL 12MHz --------------------------------------*/ //#pragma SRC #include reg51.h #include intrins.h #include math.h void delay(unsigned int); //延时函数 void display(void); //显示函数 unsigned char keysCAN(void); //按键扫描处理函数 void heatCTRl(void); /
[单片机]
AVR,C51和PIC单片机比较
八位单片机由于内部构造简单,体积小,成本低廉,在一些较简单的控制器中应用很广。即便到了本世纪,在单片机应用中,仍占有相当的份额。由于八位单片机种类繁多,本文仅将常用的几种在性能上作一个简单的比较,供读者在使用时作参考。 1. 51系列   应用最广泛的八位单片机首推Intel的51系列,由于产品硬件结构合理,指令系统规范,加之生产历史“悠久”,有先入为主的优势。世界有许多著名的芯片公司都购买了51芯片的核心专利技术,并在其基础上进行性能上的扩充,使得芯片得到进一步的完善,形成了一个庞大的体系,直到现在仍在不断翻新,把单片机世界炒得沸沸扬扬。有人推测,51芯片可能最终形成事实上的标准MCU芯片。   51系列优点之一是它从内部
[单片机]
51单片机的P1、P2、P3口的工作原理
1、P1口某一位的内部电路结构如下图所示,在51单片机的P0,P1,P2,P3口中,P1口的结构最简单,用途也最单一。仅仅只作为普通的数据输入/输出(I/O)端口使用。从图中可以看出,P0口与P1口的主要差别在于:P1端口用内部上拉电阻代替了P0端口的场效应管,并且输出的信息只有内部总线的信息,没有了数据/地址总线的复用。 1)P1口用作输入端口 如果P1口用作输入端口,即Q=0,/Q=1;则场效应管导通,引脚被直接连到电源的地GND上,即使引脚输入的是高电平,被直接拉低为 0 ,所以,与P0端口一样,在将数据输入P1端口之前,先要通过内部总线向锁存器写 1 ,这样/Q=0,场效应管截止,P1端口输入的
[单片机]
<font color='red'>51</font><font color='red'>单片机</font>的P1、P2、P3口的工作原理
基于MC74型电路的无线数字温度传感器
      1 概述    将普通传感器与低功耗无线发射控制器和接收装置连在一起就可构成无线传感器,如果将该系统接入因特网(Intemet)甚至还可以组成无线网络传感器。文中介绍利用MC74型集成串行数字温度传感器组成的无线数字温度传感器。   MC74是安森美公司生产的8位串行接口集成数字温度传感器,其温度数据由热传感单元转换而来。MC74的温度分辨率为±1°C,转换速率通常为8次采样/秒。在正常工作条件下,静态电流为200μA(典型值),在待机条件下,静态电流为5μA(典型值)。其他设备与MC74的通信可由2线SM总线,I2C兼容串行总线来实现.该总线可用于多区域监控.配置寄存器CONFIG中的SHDN位可用来激活低功耗
[工业控制]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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