Proteus教程第四讲:DS18B20温度测量

描述

视频教程:https://www.bilibili.com/video/BV1bf4y1U7ff

 

传感器基本概念 

1、按传感器的物理量分类:可分为位移、温度、速度、流量、力、气体成份等传感器。 2、按传感器工作原理分类:可分为电阻、电感、光栅、电压、电容、霍尔、光电、热电偶等传感器。 3、按传感器输出信号的性质分类:可分为:输出为开关量“1”和"0”或“开”和“关”的开关型传感器;输出为模拟型传感器;输出为脉冲或代码的数字型传感器。 

传感器传感器
#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
#define uchar unsigned char
#define uint unsigned int
typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;
#define uchar unsigned char
#define uint unsigned int
#define SEG P0
sbit SCAN1 = P2^0;
sbit SCAN2 = P2^1;
sbit SCAN3 = P2^2;
sbit SCAN4 = P2^3;
uchar number;
uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int display=0;//数码管刷新

void delay_ms(uint j)                        //1ms
{
        uchar i=250;
        for(;j >0;j--)
{
                while(--i);
                i=249;
                while(--i);
                i=250;
        }
}
sbit DQ=P3^7; 				//数据传输线接单片机的相应的引脚 
unsigned char tempL=0; 		//设全局变量
unsigned char tempH=0; 
unsigned int sdata;			//测量到的温度的整数部分
unsigned char xiaoshu1;		//小数第一位
unsigned char xiaoshu2;		//小数第二位
unsigned char xiaoshu;		//两位小数
bit fg=1;        			//温度正负标志
uint T_H;
void delay(unsigned char i)
{
	for(i;i >0;i--);
}
void Init_DS18B20(void) 
{
	unsigned char x=0;
	DQ=1; 					//DQ先置高 
	delay(8); 				//稍延时
	DQ=0; 					//发送复位脉冲 
	delay(80); 				//延时( >480us) 
	DQ=1; 					//拉高数据线 
	delay(5); 				//等待(15~60us) 
	x=DQ; 					//用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1 
	delay(20); 
}

//读一个字节
ReadOneChar(void)  			//主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号
{
	unsigned char i=0; 		//每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期
	unsigned char dat=0; 
	for (i=8;i >0;i--) 		//一个字节有8位 
	{
		DQ=1; 
		delay(1); 
		DQ=0;
		dat >>=1; 
		DQ=1; 
		if(DQ) 
		dat|=0x80; 
		delay(4);
	} 
	return(dat);
}

//写一个字节
void WriteOneChar(unsigned char dat) 
{ 
	unsigned char i=0; 		//数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
	for(i=8;i >0;i--) 		//在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。 
	{
		DQ=0; 				//在开始另一个写周期前必须有1us以上的高电平恢复期。 
		DQ=dat&0x01; 
		delay(5); 
		DQ=1; 
		dat >>=1;
	} 
	delay(4);
}

//读温度值(低位放tempL;高位放tempH;)
void ReadTemperature(void) 
{ 
	Init_DS18B20(); 					//初始化
	WriteOneChar(0xcc); 				//跳过读序列号的操作
	WriteOneChar(0x44); 				//启动温度转换
	delay(125); 						//转换需要一点时间,延时 
	Init_DS18B20(); 					//初始化
	WriteOneChar(0xcc); 				//跳过读序列号的操作 
	WriteOneChar(0xbe); 				//读温度寄存器(头两个值分别为温度的低位和高位) 
	tempL=ReadOneChar(); 				//读出温度的低位LSB
	tempH=ReadOneChar(); 				//读出温度的高位MSB	
	if(tempH >0x7f)      				//最高位为1时温度是负
	{
		tempL=~tempL;					//补码转换,取反加一
		tempH=~tempH+1;       
		fg=0;      						//读取温度为负时fg=0
	}
	sdata = tempL/16+tempH*16;      	//整数部分
	xiaoshu1 = (tempL&0x0f)*10/16; 		//小数第一位
	xiaoshu2 = (tempL&0x0f)*100/16%10;	//小数第二位
	xiaoshu=xiaoshu1*10+xiaoshu2; 		//小数两位
	/*
	if(fg==0)
	{
		sdata=sdata-15;
		xiaoshu1=xiaoshu1-9;
	}
	*/
}
	
void main()
{
	TMOD |= 0x01;	  //开启定时器0  0x10时使用定时器1  0x11时启动两个
	TH0=0XFC;	//给定时器赋初值,定时1ms   TH1
	TL0=0X18;	 //TL1
	EA=1;            //总中断打开
	ET0=1;           //定时器0中断打开    ET1
	TR0=1;           //定时器0开关打开    TR1
	while(1)
	{
		ReadTemperature();
		delay_ms(500);
	}
}

void Timer0() interrupt 1     //参考上图  定时器1时为3
{
	static uint i;   //定义一个自变形变量
	TH0=0XFC;	//给定时器赋初值,定时1ms    TH1
	TL0=0X18;   //TL1
	i++;
	if(i==4)
	{
		i=0;
	SEG = 0XFF;
	switch(number)
	{

     case 0:SCAN4=1;SCAN3=0;SCAN2=0;SCAN1=0;SEG=distab[sdata%10];break;
	
     case 1:SCAN4=0;SCAN3=1;SCAN2=0;SCAN1=0;;SEG=distab[sdata/10];break;

     case 2:SCAN4=0;SCAN3=0;SCAN2=1;SCAN1=0;SEG=distab[0];break;

     case 3:SCAN4=0;SCAN3=0;SCAN2=0;SCAN1=1;;SEG=distab[0];break;

     default:break;
			
    }		
		number++;
    if(number >3)number=0;
	}	
}


   审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分