蓝桥杯单片机之DS18B20温度传感器

简述:

蓝桥杯板子上的DS18B20温度传感器,通信方式是单总线通信(1一wire);同时在蓝桥杯比赛的资料包中,提供了一个关于DS18B20的库文件(onewire.h,onewire.c),里面有传感器复位 [bit init_ds18b20(void)]、写字节 [void Write_DS18B20(unsigned char dat)] 和读字节 [unsigned char Read_DS18B20(void)] 三个函数。所以我们不一定需要将I2C的时序搞得很清楚,只需要将DS18B20的基本操作流程弄明白。

根据提供的芯片数据手册可以获取的信息:

  • DS18B20 采用单总线协议与主机进行通信。在单线端口条件下,必须先建立ROM 操作协议,才能进行存储器和控制操作。

  • 配置寄存器允许用户将温度数字转换的分辨率设置为9、10、11或12位。DS18B20的核心功能是直接数字温度传感器。温度传感器的分辨率可由用户配置为9、10、11或12 位,分别对应0.5℃、0.25℃、0.125℃和0.0625℃的增量。上电时的默认分辨率为12位(即精度为0.0625℃)。

  • 通过单线总线端口访问 DS18B20 的协议如下:
    • 初始化
    • ROM 操作命令
    • 存储器操作命令
    • 执行/数据

ROM操作命令:

名称(寄存器地址)作用其他
Search ROM(F0H)主机识别总线上所有从机的ROM代码
Read ROM(33H)主机读取从机的64位ROM代码
Match ROM(55H)匹配64位ROM命令
Skip ROM(CCH)主机使用该命令同时寻址总线上的所有器件,无需发送器件的64位rom代码即可读取从机数据适合像CT107D开发板的设计,总线上只有一个器件的情况
Alarm Search(ECH)主机确定最近一次温度转换期间是否有DS18B20出现报警情况很少用到

主机可以使用 Skip ROM命令 同时寻址总线上的所有器件,而无需发送任何ROM代码信息。例如,主机可以通过发出Skip ROM命令,然后发出Convert T [44h]功能命令,使总线上的所有DS18B20同时执行温度转换。
请注意,Skip ROM命令适用于总线上有一个从机时。这种情况下,主机无需发送器件的64位ROM代码即可读取从机数据,从而节省了时间。

存储器操作命令

操作命令名称(寄存器地址)描述
Convert Temperatures(44H)该命令启动一次温度转换。转换后,产生的热数据存储在暂存存储器的2 字节温度寄存器
Write Scratchpad (4EH)该命令允许主机向DS18B20的暂存器写入3个字节的数据。
Read Scratchpad (BEH)该命令允许主机读取寄存器的数据。数据传输从字节0的最低有效位开始(低八位开始),继续通过暂存器,直到读取完高八位字节。

温度转换及温度获取

温度寄存器格式:

当需要执行温度测量时,总线控制器必须发出温度转换命令。在那之后,产生的温度数据以两个字节的形式被存储到高速暂存器的温度寄存器中,DS18B20继续保持等待状态。单片机可通过单线接口可以读到该数据,读取时低位在前,高位在后。

下表中高5位S为扩展符号位。当S=0时表示测得的温度值为正值,可以直接将二进制位转换为十进制;当S=1时,表示测得的温度值为负值,要先将补码变成原码,再计算十进制值。

原文:After the DS18B20 performs a temperature conversion, the temperature value is compared to the user-defined two’s complement alarm trigger values stored in the 1-byte TH and TL registers (see Figure 3). The sign bit (S) indicates if the value is positive or negative: for positive numbers S = 0 and for negative numbers S = 1.

在这里插入图片描述
在这里插入图片描述

获取温度的具体操作

读取一次DS18B20温度的基本操作:
<1> 对DS18B20进行复位初始化。
<2> 向DS18B20写0xCC命令,跳过ROM。
<3> 向DS18B20写0x44命令,开始进行温度转换。
<4> 等待温度转换完成。
<5> 对DS18B20进行复位初始化。
<6> 向DS18B20写0xCC命令,跳过ROM。
<7> 向DS18B20写0xBE命令,开始读取寄存器中的温度数据
<8>将读取的高八位和高八位的温度数据存入对应的变量中
<9>将DS18B20复位初始化。

完整读取一次温度数据的代码示例:
    Init_DS18B20();			//对DS18B20进行复位初始化。
    Write_DS18B20(0xCC);	//跳过ROM,仅总线上只有一个从机时使用
    Write_DS18B20(0x44);	//进行温度转换
    Init_DS18B20();			//对DS18B20进行复位初始化。
    Write_DS18B20(0xCC);	//跳过ROM,仅总线上只有一个从机时使用
    Write_DS18B20(0xBE);	//开始读取寄存器中的温度数据,需按照从低八位到高八位的顺序
    LSB = Read_DS18B20();	//将低八位存入LSB变量
    MSB = Read_DS18B20();	//将高八位存入MSB变量
    Init_DS18B20();			//对DS18B20进行复位初始化。

温度数据处理与数码管显示

根据储存温度数据的变量进行实际温度计算(正温度值):

unsigned int Digital_Output,Decimals,Integer;
Digital_Output = MSB << 8 | LSB 		//将高八位左移8位再加上低八位,形成一个16位的完整温度数据	
if(Digital_Output & 0xF800 == 0X0000)
{
		Integer  = (Digital_Output >>4)* 100;			//提取整数部分并乘以100
		Decimals =  (LSB & 0x0f) * 0.0625*100;	//提取分数部分乘以精度再乘以100
		Digital_Output =Integer+Decimals;
}

需要保留小数时的数据处理(数码管显示):
例如:我们要显示15.34

步骤:
1>15.34*100
2>利用1534进行每一位的提取
1534/1000 = 1;
1534/100%10 = 5;
1534/10%10 = 3;
1534%10 = 4;
3>将获取的每一位数显示在数码管上//记住数码管显示时,5是一个含有小数点的字形>

完整项目代码示例:

#include "reg52.h"
#include "onewire.h"	//引用资料中的单总线驱动头文件

unsigned int T_dat; //定义一个温度变量
/*数码管显示需要的字码*/
unsigned char SMG_NoDot[19] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x80, 0xc6, 0xc0, 0x86, 0x8e, 0xbf, 0x7f, 0xff}; //0-9、A-F、'-'、'.'
unsigned char code SMG_IsDot[10] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10};

void Delay500us();
void Read_Temperature();	//从DS18B20读取一次温度的操作,并将温度进行处理函数
void Display_Temperature(unsigned int dat); //温度数据的数码管显示,保留两位小数
void Digital_Tube(unsigned char Position, unsigned char Typeface);	//数码管单个字符显示函数

void main()
{
    while (1)
    {
        Read_Temperature();
        Display_Temperature(T_dat);
    }
}

void Delay500us()       //@12.000MHz
{
    unsigned char i, j;

    i = 6;
    j = 211;
    do
    {
        while (--j);
    }
    while (--i);
}

void Digital_Tube(unsigned char Position, unsigned char Typeface)   //Position是数码管第几位(从左到右,0开始),Typeface是显示的字样
{
    unsigned char Bit[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
    P2 = P2 & 0x1f | 0xc0;
    P0 = Bit[Position];
    P2 = P2 & 0x1f | 0xe0;
    P0 = Typeface;
    Delay500us();
    P0 = 0XFF;
    P2 = P2 & 0x1f ;    //数码管消影
}

void Display_Temperature(unsigned int dat)	//温度数据的数码管显示,保留两位小数
{
    Digital_Tube(7, SMG_NoDot[dat % 10]); 
    Digital_Tube(6, SMG_NoDot[dat / 10 % 10]);
    Digital_Tube(5, SMG_IsDot[(dat / 100) % 10]);
    Digital_Tube(4, SMG_NoDot[(dat / 1000) % 10]);
    
	/*数码管全灭,消影作用*/
    P2 = P2 & 0x1f | 0xc0;		
    P0 = 0XFF;
    P2 = P2 & 0x1f | 0xe0;
    P0 = 0XFF;
}

void Read_Temperature()	//从DS18B20读取一次温度的操作,并将温度进行处理函数
{
    unsigned char LSB, MSB;
	unsigned int Decimals,Integer;	//定义局部变量,整数、小数
	
    Init_DS18B20();			//对DS18B20进行复位初始化。
    Write_DS18B20(0xCC);	//跳过ROM,仅总线上只有一个从机时使用
    Write_DS18B20(0x44);	//进行温度转换
    Init_DS18B20();			//对DS18B20进行复位初始化。
    Write_DS18B20(0xCC);	//跳过ROM,仅总线上只有一个从机时使用
    Write_DS18B20(0xBE);	//开始读取寄存器中的温度数据,需按照从低八位到高八位的顺序
    LSB = Read_DS18B20();	//将低八位存入LSB变量
    MSB = Read_DS18B20();	//将高八位存入MSB变量
    Init_DS18B20();			//对DS18B20进行复位初始化。

    T_dat = 0x0000;			//数据初始化
    T_dat = MSB << 8 | LSB;	//将低八位和高八位进行合并

    if ((T_dat & 0xf800) == 0x0000)		//判断是不是正值
    {
		Integer  = (T_dat >>4)* 100;			//提取整数部分并乘以100
		Decimals =  (LSB & 0x0f) * 0.0625*100;	//提取分数部分乘以精度再乘以100
		T_dat=Integer+Decimals;		//将100倍的整数部分加上100倍的小数部分
    }
    /*if ((MSB& 0xf8) == 0x0000)		//判断是不是正值
    {
		T_dat=T_dat*0.0625*100;		//将100倍的整数部分加上100倍的小数部分
    }
    */
}

DS18B20的蓝桥杯文档及整个工程文件下载

  • 12
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值