【小蜜蜂蓝桥杯笔记】DS18B20温度传感器的使用

蓝桥杯v20原理图

DS18B20

  • 更新(需要注意的部分)

    • 进行带小数点的高精度转换时,需要750ms的延时,建议将开始转换和读取数据的函数分开写,利用定时器保证750ms之后再去读取,不然会出现很奇怪的数字

    • 数据处理的时候,可将高八位和低八位数据储存在long类型数据中,得到的数乘以625,可得到一个6位整数,后四位为小数部分,例如:

      temp=high&0x0f;
      	temp=(high<<8)|low;
      	
      	temp1 = temp*625;
      	return temp1;
      
  • 简介

    DS18B20是数字温度传感器,为单总线设备

  • 温度转换与读取流程

    1. DS18B20复位。
    2. 写入字节0xCC,跳过ROM指令(单总线上连接的设备都有唯一的64位标号,但由于蓝桥杯开发版单总线只连接了18B20,所以可以跳过设备查找)。
    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 以16位带符号拓展的二进制补码读出

    • 低四位为小数部分,中间七位为整数部分,高五位为符号位,全为0时为正数,全为1时为负数。
      手册中的表格

    • DS18B20的分辨率为0.0625。读出温度为正温度时,将整合后的16位整数直接乘以0.0625即可。读出温度为负温度时,需取反+1后再乘以0.0625

  • 代码部分

  • onewire.c

/***********蓝桥杯onewire驱动************/
#include "onewire.h"

//单总线内部延时函数
void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);//此处应该修改延时长度
	}
}

//单总线写操作
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//单总线读操作
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		Delay_OneWire(1);//此处应加一小延时
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}
/**********自定义部分**********/
char rd_temperature(void){//读取整数
	unsigned char low,high;
	char temp;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	Delay_OneWire(200);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xBE);	
	low = Read_DS18B20();
	high = Read_DS18B20();
	init_ds18b20();
	temp=high;
	temp<<=4;
	temp=temp | (low>>4);
	return temp;
}

  • onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include "stc15f2k60s2.h"

sbit DQ = P1^4;  
//读取温度
char rd_temperature(void);  


#endif
  • main.c
#include "stc15f2k60s2.h"
#include "onewire.h"
//缩写
typedef unsigned char uchar;
typedef unsigned int uint;
//数码管部分
code uchar smg_dm[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uchar smg_num[]={10,10,10,10,10,10,10,10};
uchar com=0;
//全局变量
uchar temp_c=0;
bit temp_flag = 0;
char temp;
//函数声明
void hc138(uchar n){//38译码器
	if(n==0) P2=P2&0x1f|0x00;
	if(n==4) P2=P2&0x1f|0x80;
	if(n==5) P2=P2&0x1f|0xa0;
	if(n==6) P2=P2&0x1f|0xc0;
	if(n==7) P2=P2&0x1f|0xe0;
}
void init(){//初始化
	hc138(5);
	P0=0x00;
	hc138(4);
	P0=0xff;
	hc138(0);
}
void dsp(){//数码管显示
	P0=0xff;//消隐
	hc138(6);
	P0=0x01<<com;
	hc138(7);
	P0=smg_dm[smg_num[com]];
	(com==7)?(com=0):(com++);
}
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初始值
	TH0 = 0xD1;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;	//定时器0开始计时
	EA = 1;   //总中断使能on
	ET0 = 1;	//定时器0中断使能on
}
void Timer0ser() interrupt 1{
	temp_c++;
	if(temp_c==50){
		temp_c=0;
		temp_flag=1;
	}
	dsp();
}
//主函数
void main(){
	init();
	temp = rd_temperature();
	Timer0Init();
	while(1){
		if(temp_flag){
			temp_flag=0;
			temp = rd_temperature();
		}
		if(temp>=10){
			smg_num[6] = temp/10;
			smg_num[7] = temp%10;		
		}else{
			smg_num[6]=10;
			smg_num[7] = temp%10;
		}
	}
}
  • 5
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值