蓝桥杯_单片机_入门基础知识(七)_DS18b20

持续关注阿杰在线更新保姆式蓝桥杯笔记~~坚持日更

目录

一、DS18b20温度传感器简介

附:

单总线系统

二、DS18b20温度传感器原理

三、DS18b20温度传感器内部结构

四、DS18b20温度传感器ROM和暂存器

ROM:

 暂存器

五、DS18B20的温度转换规则

六、DS18b20温度传感器操作步骤

七、编程思路

八、代码区


一、DS18b20温度传感器简介

DS18B20本身就是一个温度传感器,只需要将DS18B20的数据引脚和单片机的一个I/O口接上,单片机通过1-Wire(单总线)协议与DS18B20进行通信,读出温度。

CT107D开发板电路图如下:


附:

单总线系统


单总线系统包括一个总线控制器一个或多个从机。DS18B20 总是充当从机。当只有一只从机挂在总线上时,系统被称为“单点”系统;如果由多只从机挂在总线上,系统被称为“多点”。
所有的数据和指令的传递都是从最低有效位开始通过单总线。


二、DS18b20温度传感器原理

三、DS18b20温度传感器内部结构

英文版:

中文版: 

四、DS18b20温度传感器ROM和暂存器

ROM:

 暂存器

中文版:

 英文版:

 

 

五、DS18B20的温度转换规则

DS18B20 的核心功能是它的直接读数字的温度传感器。温度传感器的精度为用户可编程的 9,10,11 或 12 位,分别以 0.5℃,0.25℃,0.125℃和 0.0625℃增量递增。在上电状态下默认的精度为 12 位。DS18B20 启动后保持低功耗等待状态;当需要执行温度测量和 AD 转换时,总线控制器必须发出[44h]命令。在那之后,产生的温度数据以两个字节的形式被存储到高速暂存器的温度寄存器中,DS18B20 继续保持等待状态。当 DS18B20 由外部电源供电时,总线控制器在温度转换指令之后发起“读时序”(见单总线系统节),DS18B20 正在温度转换中返回0,转换结束返回 1。如果 DS18B20 由寄生电源供电,除非在进入温度转换时总线被一个强上拉拉高,否则将不会由返回值。寄生电源的总线要求在 DS18B20 供电节详细解释。

 ​​​​

六、DS18b20温度传感器操作步骤

步骤一:

 

步骤二:

 步骤三:

七、编程思路

Main()
{
Key_Proc()
Seg_Proc()
Led_Proc()
}


Time_1() interrupt 3
{
  ++ Key_Slow_Down降速
  ++Seg_Slow_Down  降速

  Led_Disp()
  Seg_Disp(seg_buf, pos); //显示刷新
  if( ++pos == 8 ) 	pos = 0;
}

void Key_Proc(void)//按键处理,底层数据变更
{	//永远不变
	if(Key_Slow_Down) return;
	…
	Key_Down = Key_Value & (Key_Old ^ Key_Value	Key_Old = Key_Value;
	…
	//根据代码需求发生变化
	 Key_Down 控制状态信息变化
}


void Seg_Proc(void)//显示处理,显示信息生成
{
	//永远不变
	if(Seg_Slow_Down) return;
	Seg_Slow_Down = 1;//减速程序

	//根据代码需求发生变化
	根据状态信息,控制显示内容的采集和更换

	//永远不变
	Seg_Tran(seg_string, seg_buf);
}

void Led_Proc(void)//LED处理,显示信息生成
{
	显示信息的处理
}

八、代码区


 **main.c文件**

#include "bsp_init.h"
#include "bsp_led.h"
#include "bsp_seg.h"
#include "bsp_key.h"
#include "timer.h"
#include "onewire.h"
#include "ds1302.h"
#include "stdio.h"

//------------------------
/*函数声明*/
void Key_Proc(void);//按键处理,底层数据变更
void Seg_Proc(void);//显示处理,显示信息生成
void Led_Proc(void);//LED处理,LED状态信息表示

//------------------------
/*变量声明*/

//数码管
unsigned char seg_string[10];//放置字符串
unsigned char seg_buf[8];//放置字符串转换后的段码到数组
unsigned char pos;//中断显示专用
//按键
unsigned char Key_Value;//读取按键的数值存储变量
unsigned char Key_Down,Key_Old;//读取按键的数值存储变量	
//灯
unsigned char ucLed;//记录LED的状态信息
//减速
unsigned char Key_slow;//按键减速
unsigned char Seg_slow;//按键减速
//ds1302
unsigned char ucRTC[3] = {23,59,55};//数组初始值,里边放的是时分秒的数值
//变化区
unsigned int ms_count;//记录毫秒数据
unsigned char s_count;//记录秒数据

unsigned char mode;//界面切换

//------------------------
/*main*/
void main()
{
	Cls_peripheral();//关闭外设
	Timer1Init();//定时器1初始化,并且使能定时器1中断,1ms进入一次
	EA = 1;//打开总中断
	
	Set_Rtc(ucRTC);//设置RTC时间,23-59-55
	
	while(1)
	{
		Key_Proc();//按键处理,底层数据变更
		Seg_Proc();//显示处理,显示信息生成
		Led_Proc();//LED处理,LED状态信息表示
	}
}

//------------------------
/*timer1_interrupt*/
void timer1()interrupt 3
{
	if(++Key_slow == 10)	Key_slow = 0;
	if(++Seg_slow == 500)	Seg_slow = 0;
	
	if(++ms_count == 1000) //记录运行时间 
	{		
		s_count++;
		ms_count = 0;
	}
	
	Seg_Disp(seg_buf,pos);//数码管显示刷新
	if(++pos == 8)	pos = 0;
	
	Led_Disp(ucLed);//LED显示
}

//------------------------
/*Key_Proc*/
void Key_Proc(void)//按键处理,底层数据变更
{
	if(Key_slow)	return;
	Key_slow = 1;//减速程序
	
	Key_Value = Key_Read_BTN();//读取按键按下的编号
	Key_Down = Key_Value & (Key_Value ^ Key_Old);
	Key_Old = Key_Value;
	
	if(Key_Down)//如果捕捉到下降沿跳变
	{
		if(++mode == 3)	mode = 0;//保证mode在0-2之间翻滚
	}
}

//------------------------
/*Seg_Proc*/
void Seg_Proc(void)//显示处理,显示信息生成
{
	if(Seg_slow)	return;
	Seg_slow = 1;//减速程序
	
	switch(mode)
	{
		case 0:	
			sprintf(seg_string,"----%04.2f",rd_temperature()/16.0);
							//读取18b20的温度数值,将要显示的数值打印到字符串当中
		break;
		
		case 1:	
			Read_Rtc(ucRTC);//读取1302内部时分秒的数据,放到预定义的数组空间中	
			sprintf(seg_string,"%02d-%02d-%02d",(unsigned int)ucRTC[0],(unsigned int)ucRTC[1],(unsigned int)ucRTC[2]);
							//将要显示的数值打印到字符串当中
		break;
		
		case 2:	
			sprintf(seg_string,"-----%03d",(unsigned int)s_count);
                            //将要显示的数值打印到字符串当中	
		break;
	}
	
	Seg_Tran(seg_string,seg_buf);
}

//------------------------
/*Led_Proc*/
void Led_Proc(void)//LED处理,LED状态信息表示
{
	switch(mode)
	{
		case 0:	
			ucLed = 0x03;//让L1 L2两个亮
		break;
		case 1:	
			ucLed = 0x0c;//让L3 L4亮
		break;
		case 2:	
			ucLed = 0x30;//让L5 L6亮
		break;
	}
}

 **onewire.c文件**

#include "onewire.h"

sbit DQ = P1^4;

单总线延时函数
void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}

//通过单总线向DS18B20写一个字节
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);

}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
//	unsigned char index = 0;
  	   	
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 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); // 延时大于480us
  	DQ = 1;
  	Delay_OneWire(10);  // 14
  	initflag = DQ;     // initflag等于1初始化失败
  	Delay_OneWire(5);
  
  	return initflag;
}

//函数名:读取温度函数
//入口参数:无
//返回值:温度高低两个字节
//函数功能:完成温度转换,并返回转换之后的温度数据;
unsigned int rd_temperature(void)
{
	unsigned char low,high;//返回的温度数据的高低八位
	
	init_ds18b20();//步骤一:初始化 
	Write_DS18B20(0xcc);//步骤二:跳过ROM(ROM操作指令)
	Write_DS18B20(0x44);//步骤三:进行温度转换(DS18B20功能指令)
	
	init_ds18b20();//初始化
	Write_DS18B20(0xcc);//跳过ROM
	Write_DS18B20(0xbe);//读取温度
	
	low = Read_DS18B20();//读取低位
	high = Read_DS18B20();//读取高位	
	
	return ((high<<8) | low);
}

巧:

按照这种编程思路,要把驱动代码void Delay_us(void)函数去掉,否则可能去掉BUG。

全局变量初始值皆为0;局部变量初始值则取决于该单元上次使用后的情况。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值