蓝桥杯-单片机基础9——基于2023年官方onewire通信代码外设讲解(温度传感器DS18B20)

蓝桥杯单片机组备赛指南请查看这篇文章:戳此跳转蓝桥杯备赛指南文章

本文章针对蓝桥杯-单片机组比赛开发板所写,代码可直接在比赛开发板上使用。

型号:国信天长4T开发板(绿板),芯片:IAP15F2K61S2

(使用国信天长蓝板也可以完美兼容,与绿板几乎无差别)


万幸,蓝桥杯比赛板上使用onewire进行通信的外设只有温度传感器——DS18B20

1. 代码目的

        通过对开发板外设DS18B20的正确设置,获取温度传感器的温度数值,并显示到数码管上。

2. 头文件设置

        对于需要进行通信的外设,官方提供了底层onewire.c文件,我们可以直接采用该文件中已经定义好的函数,来对DS18B20进行正确的通信设置。但是,从16年开始为了增加难度,官方提供的代码会故意出现一些错误与遗漏,我们以2023年官方提供的底层文件为参考

下载链接:链接:https://pan.baidu.com/s/1LfixDiinqsOhYbhrAptbMQ      提取码:1111

        要正确使用官方提供的底层文件onewire.c有两种方式:

方式一:(直接复制)

        将该文档中的代码全部复制粘贴到我们建立的工程文件的C文件中,并直接在我们自己的C文件中进行函数调用。缺点是会造成我们的代码文件破500行,调试起来眼花缭乱;优点是简单粗暴,学习成本不高。

方式二:(自定义头文件,推荐)

        该方法比较推崇,建议学会,小蜜蜂老师有一节课专门讲如何操作,这里只介绍该项目的操作过程。

步骤一:建立新建一个头文件,在项目的source group文件夹中右键选择“add new items”,然后添加一个后缀为.h的文件:

        然后keil5就会打开一个新的文本编辑页面,这个页面就需要写我们对官方提供的onewire.c文件的头文件,在这个文件中输入以下内容:

#ifndef __ONEWIRE_H__
#define __ONEWIRE_H__void Write_DS18B20(unsigned char dat);	
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);#endif

        中间三行为需要在主函数文件中调用的函数声明,直接在onewire.c文件中复制过来。其他的部分是头文件固定格式,需要牢记。

步骤二:正确添加底层文件onewire.c

        在项目的source group文件夹中右键选择“add existing items”,然后添加百度网盘下载的onewire.c的文件:

        然后keil5工程栏就出现了一个onewire.c的文件,然后我们需要检查该文件是否缺少了一些东西。

        打开该文件,点击编译,我们来看看有什么反应:

        报错提示文件中的DQ变量不存在,因此我们需要在该文件的最上方对DQ变量进行定义,查看比赛提供的原理图:

        可以发现DQ端口外部连接到了P1^4引脚上,因此我们需要在onewire.c中,将DQ变量看作一个特殊位变量,并对其进行定义,定义好之后再次进行编译查看:

        发现报错反而多了一个P1,而P1在公共二进制文件库中可以由头文件reg52.h引用,因此我们需要在onewire.c定义该头文件:

        此时编译后我们发现,错误全部消失,只有一些提示我们存在未调用程序的警告,无所谓,说明我们的修改成功了。

        到此处,对于官方提供的底层代码文件添加完毕,在比赛中,我们可以采用这种一边编译,一边排错的方式对官方埋得坑进行避雷。

        需要我们额外添加的代码只有两行,全部底层文件onewire.c如下:

/*	# 	单总线代码片段说明1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题中对单片机时钟频率的要求,进行代码调试和修改。
*/#include <reg52.h>  //引入头文件,排除P1不存在错误sbit DQ = P1^4;  //根据原理图定义特殊位变量DQ//
void Delay_OneWire(unsigned int t)  
{unsigned char i;while(t--){for(i=0;i<12;i++);}
}//
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);
}//
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(5);}return dat;
}//
bit init_ds18b20(void)
{bit initflag = 0;DQ = 1;Delay_OneWire(12);DQ = 0;Delay_OneWire(80);DQ = 1;Delay_OneWire(10); initflag = DQ;     Delay_OneWire(5);return initflag;
}

步骤三:在主函数文件中,添加头文件:

3. 原理图介绍

        该外设已经有了固定的硬件连接,因此我们只需要关注其DQ位与单片机的P14引脚连接到了一起。

对DS18B20外设的额外介绍:

        DQ全称为数字信号输入输出端,该传感器的最低温度精度为0.0625℃,并将读取到的温度保存到MSB、LSB两个8位寄存器当中。寄存器各位如下:

MSBSSSSS2^62^52^4
LSB2^32^22^12^02^{-1}2^{-2}2^{-3}2^{-4}

从表格中进行观察我们可以发现,

        高位的MSB寄存器的前5位用于表示温度是否为整数,当全为0时极为整数,编程时不需要在意。最后3位与LSB的高4位共同构成温度的整数部分值

        LSB的低4位构成了温度的小数部分。

        温度具体数值转换方式与二进制转十进制相同,编程时,只需要将MSB和LSB中的有效数值位读取出来,合并成一个11位的2进制数,并乘以精度0.0625即可得到当前的准确温度值。

        但是温度是存在小数的,因此我们常常将温度值乘以10,构成一个无小数的整数,从而便于在数码管中进行显示。

4. DS18B20操作流程

4.1 时序操作流程

1DS18B20初始化复位
2写入0xCC,跳过ROM寻址指令
3写入0x44,开始温度转换
4延时700~900ms
5DS18B20初始化复位
6写入0xCC,跳过ROM寻址指令
7写入0xBE,读取高速暂存器
8读取温度数值存入LSB
9读取温度数值存入MSB

        以上所有的操作,除了第4步延时以外,其余函数都在官方提供的底层代码中直接调用。为了方便使用,我们常常自己写延时函数,并且在延时函数中放入我们的数码管刷新函数,避免在这段延时期间,数码管产生明显的闪烁。

4.2 程序操作流程

        一般我们不可能遇到温度为零下的可能,因此我直接去掉了判断温度是否大于零的部分。

        最后三行为数值提取的思路,不要死记,建议理解,注意对temperature的左移和右移会引起其值的大小变化:右移4位相当于除以16,或者乘以0.0256

5. 代码参考

#include <reg52.h>
#include <intrins.h>
#include "onewire.h"void SMGrunning ();unsigned char code duanma[10] = { 0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90 };
unsigned char code duanma_dot[10] = { 0x40 , 0x79 , 0x24 , 0x30 , 0x10 , 0x12 , 0x02 , 0x78 , 0x00 , 0x10 };void Delay2ms()		//@12.000MHz
{unsigned char i, j;i = 20;j = 50;do{while (--j);} while (--i);
}void Delay800ms()		//@12.000MHz
{unsigned char j;_nop_();_nop_();j = 20;do{SMGrunning ();} while (--j);}void select_HC573 ( unsigned char channal )
{switch ( channal ){case 4:P2 = ( P2 & 0x1f ) | 0x80;break;case 5:P2 = ( P2 & 0x1f ) | 0xa0;break;case 6:P2 = ( P2 & 0x1f ) | 0xc0;break;case 7:P2 = ( P2 & 0x1f ) | 0xe0;break;}
}void SMG_state ( unsigned char pos_SMG , unsigned char value_SMG )
{select_HC573 ( 6 );P0 = 0x01 << pos_SMG;select_HC573 ( 7 );P0 = value_SMG;
}void SMG_all_down ()
{select_HC573 ( 6 );P0 = 0xff;select_HC573 ( 7 );P0 = 0xff;
}unsigned int temperature = 0;
void ds18b20_temperature ()
{unsigned char LSB,MSB;init_ds18b20();Write_DS18B20(0xcc);	Write_DS18B20(0x44);Delay800ms();init_ds18b20();Write_DS18B20(0xcc);	Write_DS18B20(0xbe);LSB = Read_DS18B20();MSB = Read_DS18B20();temperature = MSB;temperature = ( temperature << 8 ) | LSB;temperature = (temperature >> 4)*10 + (LSB & 0x0f)*0.625;}void SMGrunning ()
{SMG_state( 0 , 0xff );Delay2ms();SMG_state( 1 , 0xff );Delay2ms();SMG_state( 2 , 0xff );Delay2ms();SMG_state( 3 , 0xff );Delay2ms();SMG_state( 4 , 0xff );Delay2ms();SMG_state( 5 , duanma[temperature/100] );Delay2ms();SMG_state( 6 , duanma_dot[temperature/10%10] );Delay2ms();SMG_state( 7 , duanma[temperature%10] );Delay2ms();SMG_all_down ();}int main ()
{while ( 1 ){ds18b20_temperature ();SMGrunning ();}
}

6. 编程思路重述

定义一个全局变量temperature,用于使用官方提供的函数进行DS18B20温度获取

时序步骤:

        初始化、写入0xCC、写入0X44

        初始化、写入0XCC、写入0XBE

        读取温度到LSB、读取温度到MSB

        整合MSB和LSB获得最终数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/571581.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第2章. 揭秘指令提示技术,轻松驾驭Chatgpt

Chatgpt的指令提示 想获取Chatgpt的高质文本&#xff1f;试试指令提示吧&#xff01;为模型指明方向&#xff0c;它就能产出我们心仪的内容。 指令提示技术&#xff0c;就是给Chatgpt一个明确的指引。想让它输出什么&#xff0c;只需简单告诉它。 提示公式&#xff1a;按这个…

弹性伸缩 AS

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

第1章 实时3D渲染流水线

前言 本书所剖析的Unity 3D内置着色器代码版本是2017.2.0f3&#xff0c;读者可以从Unity 3D官网下载这些着色器代码。这些代码以名为builtin_shaders-2017.2.0f3.zip的压缩包的形式提供&#xff0c;解压缩后&#xff0c;内有4个目录和1个license.txt文件。 目录CGIncludes存放了…

python3字典的排序

创建一个字典 dict1{a:2,b:3,c:8,d:4} 1、分别取键、值 取字典的所有键&#xff0c;所有的值&#xff0c;利用dict1.keys()&#xff0c;dict1.vaules()&#xff0c; 由于键&#xff0c;值有很多个&#xff0c;所以要加s&#xff0c;另外注意这里要加括号&#xff0c;这样的小…

python3怎么下载

百度搜索“python官网”。 点击进入官网&#xff0c;如图所示&#xff1a; 依次点击“Download”-“windows”。 如图会出现下载选项&#xff0c;根据电脑情况选择&#xff0c;这里我选择64位的。 选择executable版进行安装。 至此下载完成。

小程序接入第三方信息流流程 下载SDK

由第三方信息流提供相应的SDK下载链接以及接入说明和开发文档或其他方式接入&#xff0c;如果第三方能支持小程序SDK&#xff0c;则不需要后面步骤&#xff0c;只需要提供相关开发文档和接入方式接口 接入SDK 后台开发人员接入第三方提供的SDK&#xff0c;并进行相关接口开发…

鸿蒙OS开发案例:【API9】遍历沙漏文件夹并输入文件的大小

1.获取打印文件大小 /*** 获取打印文件大小*/static getFileSize(byteNum: number) {if (byteNum < 0) {return "shouldnt be less than zero!";} else if (byteNum < 1024) {return ${byteNum.toFixed(3)}B;} else if (byteNum < 1048576) {return (byteNu…

pt-archiver的实践分享,及为何要用 ob-archiver 归档数据的探讨

作者简介&#xff1a;肖杨&#xff0c;软件开发工程师 在数据密集型业务场景中&#xff0c;数据管理策略是否有效至关重要&#xff0c;它直接关系到系统性能与存储效率的提升。数据归档作为该策略的关键环节&#xff0c;不仅有助于优化数据库性能&#xff0c;还能有效降低存储成…

四川宏博蓬达法律咨询有限公司:法律服务的典范,值得信赖的合作伙伴

在当今社会&#xff0c;法律服务已经成为人们生活中不可或缺的一部分。无论是个人还是企业&#xff0c;都可能遇到各种法律问题&#xff0c;需要专业的法律机构来提供支持和帮助。四川宏博蓬达法律咨询有限公司就是在这样的背景下应运而生&#xff0c;成为众多客户信赖的法律服…

07、Lua 流程控制

Lua 流程控制 Lua 流程控制控制结构语句 Lua 流程控制 Lua编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码&#xff0c;在条件为 false 时执行其他指定代码。 以下是典型的流程控制流程图&#xff1a; 控制结构的条件表达式结…

【最新!红外小目标检测算法HCFNet】

文章目录 摘要1 引言2 相关工作2.1 传统方法2.2 深度学习方法 3 方法3.1 PPA3.2 维度感知选择性整合模块3.3 多稀释通道细化器模块3.4 损失函数设计 4 实验4.1 数据集与评估指标4.2 实现细节4.3 消融和对比 5 结论 论文&#xff1a;HCF-Net: Hierarchical Context Fusion Netwo…

Spring Task 知识点详解、案例、源代码解析

简介&#xff1a;Spring Task 定时任务   所谓定时任务。就是依据我们设定的时间定时运行任务&#xff0c;就像定时发邮件一样&#xff0c;设定时间到了。邮件就会自己主动发送。 在Spring大行其道的今天&#xff0c;Spring也提供了其定时任务功能&#xff0c;Spring Task。同…