蓝桥杯DS18B20模块(读取温度)

温度传感器DS18B20原理图:

 onewire总线

比赛中,官方提供的资源包里会头文件onewire.h和源代码onewire.c。把头文件和源代码添加到工程文件夹中,然后进行修改即可。

代码解析:

修改的地方:官方提供的资源包里面提供的是51通信程序,比赛用的是15系列的单片机,在相同晶振下15单片机的速度是51单片机的8-12倍。为了方便计算,在onewire.c源代码里的延时函数后面全给它添加一个0。下面是修改完成之后的代码。

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

 添加的代码:

官方提供只是提供的一部分程序,还需要我们添加一些驱动。

unsigned long Temperget(void);        //需要在onewire.h头文件中进行定义
{
	unsigned char low,high;
	unsigned long 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();
	
	temp=(high&0x0f);
	temp<<=8;
	temp=temp|low;
	temp=temp*625;
	
	return temp;
}

onewire.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned long Temperget(void);                //添加程序的定义

#endif

实现代码

结合半小时程序:

#include <STC15F2K60S2.H>
#include <ONEWIRE.H>
#define uchar unsigned char
#define uint unsigned int
	
uchar SMG_duanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
										0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xbf,0xff};        
uchar yi,er,san,si,wu,liu,qi,ba;
long wendu;
void Allinit(void);
void Delayms(int ms);
void Display1(uchar yi,uchar er);
void Display2(uchar san,uchar si);
void Display3(uchar wu,uchar liu);
void Display4(uchar qi,uchar ba);

void main(void)
{
	Allinit();
	while(1)
	{
		wendu=Temperget();
		yi=wendu/100000;er=wendu%100000/10000+10;   //后面+10,就是在数码管上加上小数点
		san=wendu%10000/1000;si=21;wu=21;liu=21;qi=21;ba=21;    //显示到小数点后一位
		Display1(yi,er);
		Display2(san,si);
		Display3(wu,liu);
		Display4(qi,ba);
	}
}
void Display1(uchar yi,uchar er)
{
	P2|=0xC0;
	P2&=0xDF;
	P0=0x01;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[yi];
	Delayms(1);
	
	P2|=0xC0;
	P2&=0xDF;
	P0=0x02;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[er];
	Delayms(1);
}
void Display2(uchar san,uchar si)
{
	P2|=0xC0;
	P2&=0xDF;
	P0=0x04;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[san];
	Delayms(1);
	
	P2|=0xC0;
	P2&=0xDF;
	P0=0x08;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[si];
	Delayms(1);
}
void Display3(uchar wu,uchar liu)
{
	P2|=0xC0;
	P2&=0xDF;
	P0=0x10;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[wu];
	Delayms(1);
	
	P2|=0xC0;
	P2&=0xDF;
	P0=0x20;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[liu];
	Delayms(1);
}
void Display4(uchar qi,uchar ba)
{
	P2|=0xC0;
	P2&=0xDF;
	P0=0x40;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[qi];
	Delayms(1);
	
	P2|=0xC0;
	P2&=0xDF;
	P0=0x80;
	P2|=0xE0;
	P2&=0xFF;
	P0=SMG_duanma[ba];
	Delayms(1);

    P2|=0xC0;
	P2&=0xDF;
	P0=0x80;
	P2|=0xE0;
	P2&=0xFF;
	P0=0xFF;
}
void Allinit(void)        //初始化
{
	P2|=0xA0;
	P2&=0xBF;
	P0=0x00;
	
	P2|=0xC0;
	P2&=0xDF;
	P0=0xFF;
	P2|=0xE0;
	P2&=0xFF;
	P0=0xFF;
	
	P2|=0x80;
	P2&=0x9F;
	P0=0xFF;
}
void Delayms(int ms)        //延时函数
{
	int i,j;
	for(i=0;i<ms;i++)
	for(j=845;j>0;j--);
}

猜你喜欢

转载自blog.csdn.net/m0_65270952/article/details/124077390