【蓝桥杯单片机学习记录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<<pos;
	XBYTE[0xe000]=dat;
}

void displayall(unsigned char dat)
{
  	XBYTE[0xe000]=0xff;
	XBYTE[0xe000]=dat;
}

//
void displaySMGtemp() //显示温度
{ 
	/*
	displaySMGbit(7,SMGNoDot_CA[temp%10]);
	delaySMG(100);
	displaySMGbit(6,SMGDot_CA[(temp%100)/10]);
	delaySMG(100);
	displaySMGbit(5,SMGNoDot_CA[temp/100]);
	delaySMG(100);
	*/

	displaySMGbit(7,SMGNoDot_CA[temp%10]);
	delaySMG(100);
	displaySMGbit(6,SMGNoDot_CA[temp/10]);
	delaySMG(100);
	displaySMGbit(5,0xff);
	delaySMG(100);

	//只需要3个数码管显示温度,其他数码管不亮
	displaySMGbit(4,0xff);
	delaySMG(100);
	displaySMGbit(3,0xff);
	delaySMG(100);
	displaySMGbit(2,0xff);
	delaySMG(100);
	displaySMGbit(1,0xff);
	delaySMG(100);
	displaySMGbit(0,0xff);
	delaySMG(100);

	displayall(0xff);
}

void delay(unsigned int t)
{
 while(t--)
 {
 	displaySMGtemp();//让动态扫描没有间断
 }	
}

void read_DS18B20_temp()
{
  unsigned char LSB,MSB;

  init_ds18b20();//初始化
  Write_DS18B20(0xcc);
  Write_DS18B20(0x44);
  delay(1000);

  init_ds18b20();//初始化
  Write_DS18B20(0xcc);
  Write_DS18B20(0xbe);
  
  LSB=Read_DS18B20();
  MSB=Read_DS18B20();

  temp=MSB;
  temp<<=8;
  temp=temp|LSB;

  temp>>=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;
}

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

  • 7
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,我可以帮您回答这个问题。DS18B20是一种数字温度传感器,可以通过单片机读取温度数据并进行显示。下面是一个简单的DS18B20温度转换与显示的示例: 1. 硬件连接 将DS18B20的VCC引脚连接到单片机的电源正极,GND引脚连接到单片机的电源负极,DQ引脚连接到单片机的一个GPIO口。 2. 软件实现 在单片机上编写程序,读取DS18B20温度数据并进行显示。以下是一个基于STC89C52单片机的示例代码: ```c #include <reg52.h> #include <intrins.h> #define DQ P2_0 sbit beep=P2^3; typedef unsigned char uchar; typedef unsigned int uint; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 }; uchar TempData[2]; void Delay1ms(uint y){ uint x; for(;y>0;y--) for(x=110;x>0;x--); } bit Init_DS18B20(){ bit initflag; EA=0; DQ=1;Delay1ms(1); DQ=0;Delay1ms(20); DQ=1;Delay1ms(1); initflag=DQ; Delay1ms(30); EA=1; return initflag; } void Write_DS18B20(uchar dat){ uchar i; EA=0; for(i=0;i<8;i++){ DQ=0; _nop_();_nop_(); DQ=dat&0x01; Delay1ms(6); DQ=1; dat>>=1; } EA=1; } uchar Read_DS18B20(){ uchar i,dat; EA=0; for(i=0;i<8;i++){ DQ=0; _nop_();_nop_(); dat>>=1; DQ=1; if(DQ) dat|=0x80; Delay1ms(6); DQ=1; } EA=1; return dat; } void Convert_DS18B20(){ Init_DS18B20(); Write_DS18B20(0xcc); Write_DS18B20(0x44); } void Read_Temp(){ uchar temp; int t; Init_DS18B20(); Write_DS18B20(0xcc); Write_DS18B20(0xbe); temp=Read_DS18B20(); TempData[0]=temp>>4; TempData[1]=temp&0x0f; temp=Read_DS18B20(); TempData[1]|=(temp&0xf0)>>4; TempData[0]=table[TempData[0]]; TempData[1]=table[TempData[1]]; } void main(){ while(1){ Convert_DS18B20(); Delay1ms(500); Read_Temp(); P0=TempData[0]; P1=TempData[1]; } } ``` 该示例程序使用了STC89C52单片机的P0和P1口作为数码管的控制引脚,通过读取DS18B20温度数据并进行转换后,将结果显示在数码管上。 希望以上内容对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值