【蓝桥杯09】——DS18B20温度传感器

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复位。表示读取数据结束

IAP15F2K60S2的运算速度比51要快12倍,给的底层驱动代码一般是51的,使用发现温度不准,只需要把onewire.c驱动代码中的延时增大10倍或者12倍就可以了。

#include <STC15F2K60S2.H>
#include <absacc.h>
#include <onewire.h>

void delay(unsigned int t);
void delayTemp(unsigned int t);
void delaySMGall(unsigned char dat);
void delaySMGbit(unsigned char w,unsigned char n);
void delaySMGtemp();
void Read_DS18B20Temp();

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 main()
{
    
    
	XBYTE[0xa000]=0x00;

	while(1)
	{
    
    
		Read_DS18B20Temp();
		delaySMGtemp();
  }
}

void Read_DS18B20Temp()
{
    
    
	unsigned char LSB; //温度的低八位
	unsigned char MSB; //温度的高八位
	
	init_ds18b20();       //1.DS18B20复位
	Write_DS18B20(0xcc);  //2.写入字节0xcc,跳过ROM指令
	Write_DS18B20(0x44);  //3.写入字节0x44,开始温度转换
	delayTemp(1000);      //4.延时700~900ms
	
	init_ds18b20();       //5.DS18B20复位
	Write_DS18B20(0xcc);  //6.写入字节0xcc,跳过ROM指令
	Write_DS18B20(0xbe);  //7.写入字节0xbe,读取高速暂存器
	
  LSB=Read_DS18B20();   //8.读取暂存器的第0字节,即温度数据的LSB
  MSB=Read_DS18B20();    //9.读取暂存器的第1字节,即温度数据的MSB
  init_ds18b20();       //10.DS18B20复位。表示读取数据结束 
	
	temp=MSB;
	temp=(temp<<8)|LSB;
	temp>>=4; //移除小数部分
	/*if((temp&0xf800)==0x0000)  // 有小数,判断温度是不是正数  正数temp=0567, 与上f800等于0000
	{
		temp>>=4;
		temp=temp*10;
		temp=temp+(LSB&0x0f)*0.0625;
  }*/
}

void delaySMGall(unsigned char dat)
{
    
    
	XBYTE[0xe000]=0xff;
	XBYTE[0xc000]=dat;
}
void delaySMGbit(unsigned char w,unsigned char n) //第w个数码管显示数字n
{
    
    
	XBYTE[0xe000]=0xff;
	XBYTE[0xc000]=0x01<<w;
	XBYTE[0xe000]=n;
}
void delaySMGtemp() //显示温度
{
    
     
	//显示小数部分
	/*delaySMGbit(7,SMGNoDot_CA[temp%10]);
	delay(100);
	delaySMGbit(6,SMGDot_CA[(temp/100)%10]);
	delay(100);
	delaySMGbit(5,SMGNoDot_CA[temp/100]);
	delay(100);*/
	
	//只显示整数
	delaySMGbit(7,SMGNoDot_CA[temp%10]);
	delay(100);
	delaySMGbit(6,SMGNoDot_CA[temp/10]);
	delay(100);
	delaySMGbit(5,0xff);
	delay(100);
	
	//只需要3个数码管显示温度,其他数码管不亮
	delaySMGbit(4,0xff);
	delay(100);
	delaySMGbit(3,0xff);
	delay(100);
	delaySMGbit(2,0xff);
	delay(100);
	delaySMGbit(1,0xff);
	delay(100);
	delaySMGbit(0,0xff);
	delay(100);
	delaySMGall(0xff);
}

void delayTemp(unsigned int t)
{
    
    
	while(t--)
	{
    
    
		delaySMGtemp();
  }
}

void delay(unsigned int t)
{
    
    
	while(t--);
}

底层驱动代码

/*
  程序说明: 单总线驱动程序
  软件环境: 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;
}
#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

猜你喜欢

转载自blog.csdn.net/z3447643805/article/details/113827895