蓝桥杯单片机设计与开发_基础模块_DS18B20

Posted _小猪沉塘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯单片机设计与开发_基础模块_DS18B20相关的知识,希望对你有一定的参考价值。

一、前言

从今天开始,笔者将向大家逐一讲解蓝桥杯的大部分竞赛模块,笔者将基于上一篇文章(蓝桥杯单片机设计与开发_标准模板)中讲解的标准模板编写程序。按照顺序(DS18B20、DS1302、PCF8591、AT24C02、PWM、串口通信、NE555以及超声波测距),为大家做出详细编程指导。

二、DS18B20 温度传感器

DS18B20 又叫温度传感器。笔者将基于蓝桥杯官方给的赛点资源包(蓝桥杯单片机设计与开发_赛点资源数据包)进行编程,为大家讲解编程调用各语句的含义,帮助大家编写温度传感器的程序,也便于大家记忆。

1、导入底层驱动代码

首先,创建工程和导入.c文件笔者已在文章(蓝桥杯单片机设计与开发_标准模板)中向大家详细介绍了,这里就不再赘述。
读者可下载赛点资源包(蓝桥杯单片机设计与开发_赛点资源数据包),解压后可得到以下图片所示文件。
在这里插入图片描述
我们双击打开文件“3-底层驱动代码参考”文件,将得到以下.c.h文件。接下来将包含DS18B20 的文件onewire.c 和 onewire.h 文件拷贝到工程所在文件夹中。
在这里插入图片描述
然后双击工程中 Source Group 1,将这两个文件导入,便可以开始编写程序了。

在这里插入图片描述

2、DS18B20驱动函数

首先,在编写驱动函数之前,我们需要对底层驱动代码 onewire.c 中的延迟函数 Delay_OneWire() 做出修改,将延迟时间增大 12 倍!。因为比赛使用的IAP15系列单片机速度比STC89C52系列单片机速度快12倍,如果不改时序上将出现问题,无法正常读取温度。
笔者采用一个 for 循环,在 while 循环中重复循环 12 次,达到延迟效果。

void Delay_OneWire(u16 t)  //STC89C52RC
{
	u8 num;                             //定义计数变量
	while(t--)
		for(num = 0;num <= 12;num++);     //延迟时长扩大12倍
}

接下来,就开始在 onewire.c 文件中编写温度读取函数。我们可以打开赛点资源数据包中的文件“5-竞赛板芯片资料”。

在这里插入图片描述
打开“DS18B20”芯片手册。笔者将借助芯片手册中的资料编写温度读取函数并为大家讲解。
在这里插入图片描述
温度读取函数:在编写温度读取函数时,我们只需要通过调用底层驱动函数中的初始化、写入、读取函数。

int rd_temperature(void)   //读取温度函数
{
	int temp = 0;            //定义温度读取返回值
	u8 tmh,tml;              //定义温度读取高八位和第八位
	
    init_ds18b20();          //设备初始化
	Write_DS18B20(0xcc);     //跳过ROM地址指令
	Write_DS18B20(0x44);     //安装温度转换指令
	
	init_ds18b20();
	Write_DS18B20(0xcc);     //跳过ROM地址指令
	Write_DS18B20(0xbe);     //安装温度读取指令
	
	tml=Read_DS18B20();      //读取低八位
	tmh=Read_DS18B20();      //读取高八位
	
	//将温度高八位和低八位组合成16位int类型
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	
	return temp;             //返回温度读取值
}

其中,在写入函数 Write_DS18B20() 写入的指令可通过查阅芯片资料手册,不需要死记硬背。
在这里插入图片描述
在这里插入图片描述
在编写完温度传感器驱动函数后务必要在 onewire.h 文件中声明函数,才可在主函数中调用。

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

int rd_temperature();      //声明函数

#endif

3、主函数调用

在主函数中调用温度传感器驱动函数,首先需要在主函数开头包含驱动 DS18B20 驱动函数的头文件。

#include "STC15F2K60S2.h"   //头文件
#include "onewire.h"        //包含DS18B20驱动头文件

温度数值转换函数
编写温度数据转换函数需要注意的是:读取温度数值需要再乘以 0.0625 转换成十进制温度值。笔者将读取温度值读取到小数点后四位,采用的方法是将乘以 0.0625 后的数据放大 10000 倍,再通过取余除数的方法得到各位小数值。因数值放大到百万级别,因此需要定义长整型数值。
得到各位数后,通过改变缓冲区 dspbuf 的数值,在数码管1~7中显示读取到的温度数值。

void datachange(long int temp)     //读取温度数据转换函数
{
	temp = temp*0.0625*10000;        //放大10000倍,读取小数点后四位
                    
	dspbuf[1] = temp/1000000;            //取温度的百位数
	dspbuf[2] = temp%1000000/100000;     //取温度的十位数
	dspbuf[3] = temp%100000/10000+11;    //取温度个位数并加上小数点
	dspbuf[4] = temp%10000/1000;         //取温度的小数点第一位
	dspbuf[5] = temp%1000/100;           //取温度的小数点第二位
	dspbuf[6] = temp%100/10;             //取温度的小数点第三位
	dspbuf[7] = temp%10;                 //取温度的小数点第四位
}

除此之外,笔者将个位数后的小数点显示出来,采取的方法是在定义 tab 数组时,在后面再定义十个小数点点亮的数,即通过将 0~9 对应的高八位减去 8,即可点亮小数点 dp 位。再在数码管显示的缓冲区上加上 11,即可显示带小数点的数字。

u8 code tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};   //定义数组存放数码管数字状态

中断函数
笔者在中断函数中定义每 50ms 产生一次中断,将温度读取标志位置 1,进行温度读取。

bit temp_flag = 0;     //定义温度读取标志位
void timer0() interrupt 1    //定义中断模式1
{
	static u8 t_20ms = 0;      //定义静态变量计时20ms
	static u8 t_50ms = 0;      //定义静态变量计时50ms
	
	display();                 //数码管显示函数
	
	t_20ms++;                  //计数自增
	t_50ms++;                  //计数自增
	
	if(t_20ms >= 10)           //判断计时时间
	{
		t_20ms = 0;              //计数清零
		key_flag = 1;            //按键标志位置1
	}
	
	if(t_50ms >= 10)           //判断计时时间
	{
		t_50ms = 0;              //计数清零
		temp_flag = 1;           //温度标志位置1
	}
}

main主函数
笔者在主函数开头中定义温度读取开关变量 temp_w,通过与 1 异或,可实功能:按一次 S4 打开温度传感器,每 50ms 读取一次温度;再按一次 S4 关闭温度传感器。

void main()      //主函数
{
	u8 key_re;     //定义变量读取按键返回值
	u8 temp_w = 0; //定义温度读取开关变量
	
	all_init();    //初始化函数
	Timer0Init();  //定时器0初始化
	
	while(1)
	{
		if(key_flag)            //每20ms扫描一次按键
		{
			key_flag = 0;         //标志位置0
			key_re = Read_key();  //读取按键
			 
			if(key_re != 0xff)    //判断按键是否按下
			{
				//判断按键
				switch(key_re)
				{
					//放入需要执行的功能
					case 4: temp_w ^= 1;break;  //按一次按键打开/关闭温度传感器
				}
			}
		}
		
		if((temp_w) && (temp_flag))    //定义温度读取函数
		{
			temp_flag = 0;               //清空标志位
			datachange(rd_temperature());  //调用温度读取及转换函数
		}
	}
}

至此,本次 DS18B20 温度传感器程序已编写完毕。由于笔者近期事情比较多,更新文章较慢,请各位见谅。接下来几天笔者也将尽量早点将各个模块的编程都更新完毕!欢迎读者在评论区交流!!

以上是关于蓝桥杯单片机设计与开发_基础模块_DS18B20的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯单片机设计与开发_基础模块_DS18B20

蓝桥杯单片机设计与开发_基础模块_DS18B20

STM32G4备战蓝桥杯嵌入式---模块配置---DS18B20(拓展板)

STM32G4备战蓝桥杯嵌入式---模块配置---DS18B20(拓展板)

蓝桥杯单片机设计与开发_标准模板

蓝桥杯——根据手册写底层