【蓝桥杯单片机学习记录7】DS18B20的温度转换与读取流程

目录

DS18B20的温度转换与读取流程

DS18B20的数据处理

 主程序

onewire.h

onewire.c 


DS18B20的温度转换与读取流程

  1. DS18B20复位
  2. 写入字节0xcc,跳过ROM指令
  3. 写入字节0x44,开始温度转换
  4. 延时700~900ms
  5. DS18B20复位
  6. 写入字节0xcc,跳过ROM指令
  7. 写入字节0xbe,读取高速暂存器
  8. 读取暂存器的第0字节,即温度数据的LSB
  9. 读取暂存器的第1字节,即温度数据的MSB
  10. DS18B20复位,表示读取数据结束
  11. 将LSB和MSB整合成一个16位数据
  12. 判断读取结果的符号,进行正负温度的数据处理
//DS18B20温度采样与结果处理参考代码
void Read_Temperature()
{
	unsigned char LSB,MSB ;
	
	Init_DS18B20();		      //DS18B20复位	
	Write_DS18B20(0xCC);	      //跳过ROM操作指令
	Write_DS18B20(0x44);          //开始温度转换
	Delay(1000);                  //延时700ms左右,等待温度转换完成
	Init_DS18B20();		      //DS18B20复位
	Write_DS18B20(0xCC);	      //跳过ROM操作指令	
	Write_DS18B20(0xBE);	      //开始读取高速暂存器		
	LSB = Read_DS18B20();	      //读取温度数据的低8位
	MSB = Read_DS18B20();	      //读取温度数据的高8位
	Init_DS18B20();		      //DS18B20复位,停止暂存器数据读取

	T_dat = 0x0000;
	T_dat = MSB;
	T_dat <<= 8;
	T_dat = T_dat | LSB;         //将LSB和MSB整合成为一个16位的整数
	//首先通过温度数据的高5位判断采用结果是正温度还是负温度
	if((T_dat & 0xf800) == 0x0000)    //正温度的处理办法
	{
		T_dat >>= 4;         //取出温度结果的整数部分
		T_dat = T_dat*10;    //放大10倍,然后加上小数部分
		T_dat = T_dat + (LSB&0x0f)*0.625;
	}
}

DS18B20的数据处理

以16位带符号位扩展的二进制补码形式读出

低4位为小数部分,中间7位为整数部分,高5位为符号位

分辨率为0.0625
高5位为扩展符号位,即BIT15~BIT11为00000,读出的数据为正温度,若为11111,则为负温度。在应用开发中,首先要对读出的温度数据的符号位进行判断,再根据正负温度的不同,进行相应的处理。

读出数据为正温度时,将LSB和MSB整合成的16位整数乘以0.0625;读出数据为负温度时,将LSB和MSB整合成的16位整数取反加一后,乘以0.0625;

在上电复位时,温度寄存器中的值为0x0550,即+85摄氏度

如果要求温度结果保留1位小数:
首先将温度结果的整数部分取出: T_dat >>= 4;即 T_dat = 0x0019 = 25。
然后将整数部分放大10倍: T_dat = T_dat × 10 ;即 T_dat = 250。
然后将小数部分取出: LSB&0x0f,其结果为0x06。
再将小数部分乘以0.0625的10倍,即0x06 × 0.625 = 3.73。
最后将整数部分和小数部分相加: T_dat = 250 + 3.73 = 253(因为 T_dat 是整型)
对于温度数据253,在数码管显示的时候,在十位出加上一个小数点,就变成了:25.3

如果要求温度结果只显示整数部分
T_dat >>= 4;即 T_dat = 0x0019 = 25 摄氏度。

 主程序

#include "reg52.h"
#include "absacc.h"
#include "onewire.h"

unsigned char SMGNoDot_CA[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x90,0x90}; //无小数点
unsigned char SMGDot_CA[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //显示小数点
unsigned int temp=0;
void delaySMG(unsigned int t)
{
	while(t--);
}

void displaySMGbit(unsigned char pos,unsigned char dat) //第pos个数码管显示数字dat
{
	XBYTE[0xe000]=0xff;
	XBYTE[0xc000]=0x01<>=4;
/*
  if((temp&0xf800)==0x0000)  //取出来高五位
  {
  	temp>>4;//把小数移走   ,右移4位,相当于*0.0625
	temp=temp*10;
	temp=temp+(LSB&0x0f)*0.625;//低四位取出来为小数,此时分辨率放大了10倍
   }
   */
}


void main()
{
    XBYTE[0x8000]=0x00;
	while(1)
	{
		read_DS18B20_temp();
	  displaySMGtemp();
	}
}

注意事项

  1. 先将 赛点资源的onewire.c文件和onewire.h文件复制到自己建立的工程下。
  2. 打开 onewire.h文件,检查文件代码是否完整,并确认总线引脚定义是否和CT107D的硬件对应,即P1^4。如果不对应,则将其修改过来。
  3. 打开 onewire.c文件, 研读各个底层驱动代码的具体实现,初步判断是时序的延时是否合理,如有明显错误,则将其修改过来。
  4. 根据DS18B20的工作原理和操作流程,编写读取温度结果和处理温度数据的函数
  5.  根据得到的温度结果,刷新数码管显示。这个部分,可以用MM模式来实现,可以用IO模式来实现。

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned char rd_temperature(void);  //; ;
bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);

#endif

onewire.c 

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "reg52.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(50);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(50);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(50);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(120);
  	DQ = 0;
  	Delay_OneWire(800);
  	DQ = 1;
  	Delay_OneWire(100); 
    initflag = DQ;     
  	Delay_OneWire(50);
  
  	return initflag;
}

 这里的延时是进行修改过的,扩大了十倍

你可能感兴趣的:(蓝桥杯单片机学习记录,c语言,单片机,开发语言)