【1单片机入门记录】DS18B20的应用

本文详细介绍了如何在C语言中使用DS18B20温度传感器,包括Onewire初始化、驱动函数编写以及温度读取函数的实现,重点展示了如何在main.c文件中整合这些功能并处理数据。
摘要由CSDN通过智能技术生成

目录

一、Onewire初始化代码

二、注意:多个.c文件的使用

三、DS18B20的驱动函数

(1)init_ds18b20

(2)Write_DS18B20

(3)Read_DS18B20

四、DS18B20温度读取函数

五、功能实现(代码)

(1)

(2)

(3)main.c


一、Onewire初始化代码

  1. 加载“Onewire.c”文件,主函数中添加“Onewire.h”头文件;
  2. 调节软件延迟时长(全部扩大10倍即可){解释:蓝桥杯给的资料是89C52的代码,由于开发板使用的是stc15系列,所以扩大十倍}
  3. 编写温度数据获取函数,并且在头文件中定义;
  4. 编写用户功能函数;

二、注意:多个.c文件的使用

  • 不管有多少个函数,C总是从main()主函数开始执行。
  • 一个工程里面包括多个.c的文件,其实每个.c的文件里就是一系列函数而已。
  • 一般更多的.C文件,要配合其.H文件来使用,变量的定义,函数的定义均放置在头文件中
  • 如果要使用这些函数,要在头文件里加入#include“XXX.h”
  • 三、DS18B20的驱动函数

  • (1)init_ds18b20

  • 接口函数:init_ds18b20

    函数原型

    bit init_ds18b20(void)

    功能描述

    OneWire总线启动函数;

    入口参数1

    返回值

    0或1,是否得到OneWire总线的响应。

    注意事项

    该函数需要用户调用;

(2)Write_DS18B20​​​​​​​

接口函数:Write_DS18B20

函数原型

void Write_DS18B20(unsigned char dat)

功能描述

使用OneWire总线往从机写一个字节数据函数;

入口参数1

Dat:需要往从机写入的一个字节数据

返回值

注意事项

该函数需要用户调用;

(3)Read_DS18B20

函数原型

unsigned char Read_DS18B20(void)

功能描述

使用OneWire总线从从机读出一个字节数据函数;

入口参数1

返回值

从机独处的一个字节数据;

注意事项

该函数需要用户调用;

四、DS18B20温度读取函数

bit Temper_Flag = 0 ;
unsigned int Temp;

unsigned long Temp_get(void)
{
	unsigned char low,high;
	
	if(Temper_Flag == 0 )
	{
		Temper_Flag = 1 ;
		init_ds18b20();
		Write_DS18B20(0XCC);
		Write_DS18B20(0X44);		
	}
	else if( Temper_Flag == 1 )
	{
		Temper_Flag = 0 ;
		init_ds18b20();//启动总线
		Write_DS18B20(0XCC);//发送跳过ROM指令
		Write_DS18B20(0XBE);//发送读暂存器指令
		
		low=Read_DS18B20();//读暂存器的低8位
		high=Read_DS18B20();	//读暂存器的高8位
		Temp=high&0X0F;  // SSSS  XXXX  高4位清零(符号位)
		Temp <<= 8;			//	Temp =Temp << 8;高8位向左移8位
		Temp |= low; 			// Temp =Temp | low;存储低8位	
//	
	}
	return Temp;
}

  • 五、功能实现(代码)

(1)<onewire.h>

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned long Temp_get(void);

#endif

(2)<onewire.c>

#include <STC15F2K60S2.H>
#include <intrins.h>


sbit DQ = P1^4;  //单总线接口

void Delay1us(unsigned int us)		//@11.0592MHz
{
	unsigned int i=0;
	for(i=0;i<us;i++)
	{
		_nop_();	_nop_();	_nop_();		
	}
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
	bit init_flag = 1;
	
	DQ =1 ;
	Delay1us(10);
	DQ =0 ;
	Delay1us(600);
	DQ =1 ;
	Delay1us(70);
	init_flag = DQ ;
	Delay1us(200);
	
	return init_flag;
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i=0;
	
	for(i=0;i<8;i++)
	{
		DQ = 0; 
		Delay1us(2);
		DQ = (dat & 0x01); // 1100 1100 & 0000 0001 = 0000 0000 
		Delay1us(60);
		dat >>=1; 
		DQ = 1; 
		Delay1us(1);
	}
	Delay1us(50);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char dat;
	unsigned char i=0;
	
	for(i=0;i<8;i++)
	{
		DQ = 0; 
		Delay1us(2);
		dat >>=1; 
		DQ = 1;
		Delay1us(5);
		if(DQ==1)
		{
			dat |= 0x80;  //0000 0000 | 1000 0000 = 1000 0000   
		}
		Delay1us(55);
	}
	DQ = 1;
	Delay1us(10);
	return dat;
}

//unsigned long Temp_get(void)
//{
//	unsigned char low,high;
//	unsigned int Temp;
//	
//	init_ds18b20();				
//	Write_DS18B20(0XCC);	//发送跳过ROM指令
//	Write_DS18B20(0X44);	//发送启动温度转换指令
//	Delay1us(200);		//延迟
//	
//	init_ds18b20();				//启动总线
//	Write_DS18B20(0XCC);	
//	Write_DS18B20(0XBE);	
//	
//	low=Read_DS18B20();		
//	high=Read_DS18B20();	
//	
//	Temp=high&0X0F; 	 		// SSSS  XXXX   
//	Temp <<= 8;						//	Temp =Temp << 8; 
//	Temp |= low; 					// Temp =Temp | low; 
//	return Temp;
//}

bit Temper_Flag = 0 ;
unsigned int Temp;

unsigned long Temp_get(void)
{
	unsigned char low,high;
	
	if(Temper_Flag == 0 )
	{
		Temper_Flag = 1 ;
		init_ds18b20();
		Write_DS18B20(0XCC);
		Write_DS18B20(0X44);		
	}
	else if( Temper_Flag == 1 )
	{
		Temper_Flag = 0 ;
		init_ds18b20();//启动总线
		Write_DS18B20(0XCC);//发送跳过ROM指令
		Write_DS18B20(0XBE);//发送读暂存器指令
		
		low=Read_DS18B20();//读暂存器的低8位
		high=Read_DS18B20();	//读暂存器的高8位
		Temp=high&0X0F;  // SSSS  XXXX  高4位清零(符号位)
		Temp <<= 8;			//	Temp =Temp << 8;高8位向左移8位
		Temp |= low; 			// Temp =Temp | low;存储低8位	
//	
	}
	return Temp;
}

(3)main.c

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

unsigned char Key_Value = 0;

unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,\
										 0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,\
										 0XBF,0XFF};
unsigned char DigCom=0;
unsigned char DigBuf[8] = {20,20,20,20,20,20,20,20};

unsigned char LED_Bit=0XFF;
unsigned char Actuator_Bit=0X00;

#define LEDx_ON(n) 	{ LED_Bit&=_crol_(0XFE,n-1); P0=LED_Bit; P2|=0X80;	P2&=0X9F;	P2&=0X1F;}
#define LEDx_OFF(n) { LED_Bit|=_crol_(0X01,n-1); P0=LED_Bit; P2|=0X80;	P2&=0X9F;	P2&=0X1F;}

#define Buzzer_ON 	Actuator_Bit|=0x40; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF; P2&=0X1F;		
#define Buzzer_OFF 	Actuator_Bit&=0XBF; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF;	P2&=0X1F;
#define Relay_ON 		Actuator_Bit|=0x10; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF;	P2&=0X1F;
#define Relay_OFF 	Actuator_Bit&=0XEF; P0=Actuator_Bit;	P2|=0XA0;	P2&=0XBF;	P2&=0X1F;

unsigned char LED = 1 ;
unsigned int LED_tt =0;
bit LED_Ref = 0 ;

unsigned int SEG_tt =0;		//定义一个数码管计数时间标识位
bit SEG_Ref = 0 ;					//定义一个数码管刷新标识位
bit SEG_Run = 0 ;					//定义一个控制数码管运行标识位
unsigned int Num = 999 ;

unsigned int Temp_tt =0;		//定义一个温度传感刷新及时变量
bit Temp_Ref =0;						//定义一个温度传感刷新标志位
unsigned int Temper = 0 ;		//定义一个存储温度数据的变量(16位)
unsigned char Temp_Vaue = 0 ;			//定义一个只存储温度整数数据的变量
unsigned long Temp_DotValue = 0 ;	//定义一个计算温度带小数位的变量


void All_Init(void);
void Delay_MS(unsigned int ms);
void Key_Scan(void);
void Timer0Init(void);		//1毫秒@11.0592MHz

void main(void)
{
	All_Init();
	Timer0Init();
	EA=1;ET0=1;
	
	while(1)
	{
				if(Temp_Ref==1)
		{
			Temp_Ref=0;	
//			Temp_Vaue=Temp_get()>>4;
//			DigBuf[0]=21;DigBuf[1]=21;DigBuf[2]=21;DigBuf[3]=21;DigBuf[4]=21;
//			DigBuf[5]=21;DigBuf[6]=Temp_Vaue/10;DigBuf[7]=Temp_Vaue%10;	
				Temp_DotValue = Temp_get()*625; //扩大一万倍
			
			DigBuf[0]=21;DigBuf[1]=21;
			DigBuf[2]=Temp_DotValue/100000;
			DigBuf[3]=Temp_DotValue%100000/10000+10;// 显示带小数点的码值
			DigBuf[4]=Temp_DotValue%10000/1000;
			DigBuf[5]=Temp_DotValue%1000/100;
			DigBuf[6]=Temp_DotValue%100/10;
			DigBuf[7]=Temp_DotValue%10;					
		}
		
		Key_Scan();
		if(Key_Value==7){Key_Value=0;SEG_Run = 1 ;}
		if(Key_Value==6){Key_Value=0;SEG_Run = 0 ;}
		if(Key_Value==5){Key_Value=0;LEDx_ON(1);Buzzer_ON;}
		if(Key_Value==4){Key_Value=0;LEDx_OFF(1);Buzzer_OFF;}
		
		
	}
	
}

void All_Init(void)
{
	P0 = 0X00;//先设置关闭蜂鸣器继电器的P0输出值(全关)
	P2 |=0XA0;// 1010 0000 将P27 P25 设置为1 其他位保持不变 
	P2 &=0XBF;// 1011 1111将P26设置为0 其他位保持不变 
	P2 &=0X1F;// 0001 1111关闭所有的74HC573锁存器
	
	P0 = 0XFF;//1111 1111 先设置关闭所有的LED的P0输出值(全关)
	P2 |=0X80;//1000 0000 将P27设置为1 其他位保持不变
	P2 &=0X9F;//1001 1111 将P26 P25设置为0 其他位保持不变
	P2 &=0X1F;//0001 1111 关闭所有的74HC573锁存器
	
	P0 = 0X00;//1111 1111 //先设置选择数码管位选的P0输出值(全不选)
	P2 |=0XC0;//1100 0000 将P27设置为1 其他位保持不变
	P2 &=0XDF;//1101 1111 将P26 P25设置为0 其他位保持不变
	P2 &=0X1F;// 0001 1111 关闭所有的74HC573锁存器
	
}
void Delay_MS(unsigned int ms)		//@11.0592MHz
{
	unsigned char i, j;

	while(ms--)
	{
	_nop_();
	i = 2;
	j = 199;
	do
	{
		while (--j);
	} while (--i);
}
}


void Key_Scan(void)
{
	if(P30 == 0)
	{
		Delay_MS(10);
		if(P30 == 0)  Key_Value=7;
		while(!P30);
	}
	
		if(P31 == 0)
	{
		Delay_MS(10);
		if(P31 == 0)  Key_Value=6;
		while(!P31);
	}
		if(P32 == 0)
	{
		Delay_MS(10);
		if(P32 == 0)  Key_Value=5;
		while(!P32);
	}
		if(P33 == 0)
	{
		Delay_MS(10);
		if(P33 == 0)  Key_Value=4;
		while(!P33);
	}
		
	
}

void Timer0(void) interrupt 1
{
	P0 = 0X00;
	P2 |=0XC0;  // P2=P2|0XC0;   XXXX XXXX | 1100 0000 = 11XX XXXX
	P2 &=0XDF;	 // P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX	
	P2 &=0X1F;		//关闭所有的74HC573锁存器	
	
	P0=tab[DigBuf[DigCom]];	
	P2 |=0XE0;			//	P2=P2|0XE0;   XXXX XXXX | 1110 0000 = 111X XXXX
	P2 &=0XFF;		 	// P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX	
	P2 &=0X1F;			//关闭所有的74HC573锁存器
	
	P0=(0X01<<DigCom); 	//然后选中第一个数码管
	P2|=0XC0;  // P2=P2|0XC0;   XXXX XXXX | 1100 0000 = 11XX XXXX
	P2&=0XDF;	 // P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX	
	P2&=0X1F;		//关闭所有的74HC573锁存器

	if(++DigCom == 8)DigCom = 0 ;
	
	
	if(++LED_tt == 1000) {LED_tt = 0 ; LED_Ref = 1 ;}

	if(++SEG_tt==1000){SEG_tt=0;SEG_Ref=1;}
	
	if(++Temp_tt==1000){Temp_tt=0;Temp_Ref=1;}
		
}
void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;	 	 //定时器时钟1T模式
	TMOD &= 0xF0;		 //设置定时器模式
	TL0 = 0xCD;		   //设置定时初始值
	TH0 = 0xD4;		   //设置定时初始值
	TF0 = 0;		     //清除TF0标志
	TR0 = 1;		     //定时器0开始计时
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值