1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
在咕咕咕多日之后我们蓝桥杯推送组终于又恢复更新了!(撒花~)今天就来讲解一下蓝桥杯单片机CT107D平台上温度传感器DS18B20的使用。
在基础模块部分结束后我们会以一周一篇的频率为大家推送初赛题,到时候还请继续关注~ DS18B20的工作原理 我们所参加的蓝桥杯“单片机设计与开发”比赛会为我们提供DS18B20的驱动文件(onewire.c和onewire.h),其中已经包含DS18B20的初始化、读取、写入的函数,因此我们并不需要完全弄懂单总线的时序,熟悉DS18B20的基本操作流程便足够应对比赛了。而本文也不会详细描述这一部分,想了解的同学可以参阅文末的参考资料。 不过为了更好地理解操作流程,我们还是简单介绍一下DS18B20的工作原理。详细资料可以参考“蓝桥杯单片机组CT107D-------资料包/09.芯片手册/中文版/DS18B20中文资料.pdf”。 DS18B20 引脚图 DS18B20是一种单总线数字温度传感器,测试温度范围-55℃-125℃。它只需要一个单线接口就可以发送或接收信息,因此在中央微处理器和 DS1820 之间仅需一条连接线(加上地线)。用于读写和温度转换的电源可以从数据线本身获得,无需外部电源。单总线读写数据是靠控制起始时间和采样时间来完成,所以时序要求很严格,这也是DS18B20编程的难点。 DS18B20方框图 DS18B20内部主要由2部分组成:64位ROM和9字节高速暂存存储器。64位ROM中有一个独特的片序列号,所以可以实现一根总线上挂载多个DS18B20 的目的,这样就可以把温度传感器放在许多不同的地方。由于我们的开发平台只挂载了一个温度传感器,所以进行跳过ROM操作指令即可。 通过单总线端口访问DS1820的协议如下: • 复位初始化 • ROM 操作命令 • 存储器操作命令 • 执行/数据 DS18B20的高速暂存存储器由9个字节组成,当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。因此在读取时,如果只想获取温度数据,那在读完第0和第1个数据后就不再理会后面DS18B20发出的数据即可。在上电状态下,DS18B20默认的精度为12位。启动后它保持低功耗等待状态。当需要执行温度测量和AD转换时,总线控制器必须发出温度转换命令。在那之后,产生的温度数据以两个字节的形式被存储到高速暂存器的温度寄存器中,DS18B20继续保持等待状态。单片机可通过单线接口可以读到该数据,读取时低位在前,高位在后。 准备工作 假装我们已经对DS18B20有了一定的了解,现在我们就利用大赛提供的DS18B20的库文件和资料包中的例程试一试……等等,为什么我的数码管显示如此奇怪?不卖关子,这是因为我们购买的开发板上并没有DS18B20……(顺便一提,目前我们之前统一购买的那家淘宝店“西工大嵌入式电子科技”不知何时下架了这款开发板) 在购买了DS18B20之后,参照“CT107D_SCH.pdf”原理图上,将DS18B20的三个引脚与开发板上的预留接口连接。 安装好的DS18B2如图所示。 接着,我们还需要对DS18B20的驱动做一些小改动。打开资料中的“onewire.c”,可以看到这一段延时函数: void Delay_OneWire(unsigned int t) { while(t--); } 由于蓝桥杯“单片机设计与开发”比赛近两年才改用STC15F2K60S2单片机(有12T和1T两种速度模式),而这个延时函数是针对之前的STC89C52单片机(仅有12T速度模式),因此如果继续用这个函数就会造成时序错乱,因此我们有两种方法处理。个人推荐法一,法二感兴趣的可以尝试下。 法1:修改延时函数 因为STC15F2K60S2在1T的速度模式下比STC89C52快了不少,我们把延时函数增加到原来的12倍就可以让DS18B20的时序同步,因此可以加一段for循环: void Delay_OneWire(unsigned int t) { unsigned char i; while(t--) { for(i=0;i<12;i++); } } 法二:修改单片机的速度模式 这个方法需要用到辅助功能寄存器AUXR,可以作为对寄存器以及中断知识的复习巩固,让STC15F2K60S2处于12T的速度模式从而解决时序的问题。 另外,我们还需要把头文件添加到keil的项目中。 首先,将放有头文件的文件夹添加到路径中。在“options“找到”C51“选项卡,按图示添加。 我们还要把onewire,c文件添加到项目中,如下图所示。 这样我们就完成了准备工作,现在要做的就是读取DS18B20中的温度数据了。 温度采集程序 由于蓝桥杯对DS18B20的精度要求到整数即可,我们就写一个这样的函数,使测得的温度显示在数码管的后两位,并以一定的频率刷新。 首先我们来看一下读取一次DS18B20温度的基本操作: <1> 主机对DS18B20进行复位初始化(驱动中已有)。 <2> 主机向DS18B20写0xCC命令,跳过ROM。 <3> 主机向DS18B20写0x44命令,开始进行温度转换。 <4> 主机对DS18B20进行复位初始化。 <5> 主机向DS18B20写0xCC命令,跳过ROM。 <6> 主机向DS18B20写0xBE命令,依次读取DS18B20发出的从第0一第8,共九个字节的数据。由于我们只需要温度数据,读取前两个字节数据即可。 以下是读取温度的函数,之后分别取temp的个位、十位使其在数码管上显示即可。这个函数还没有考虑到负的温度,如果是负的话要先减1再添加“-“符号。 unsigned int temp = 0; …… ReadTemperature ()//仅整数 { unsigned char low,high; Init_DS18B20(); //复位初始化 Write_DS18B20(0xCC); //写0xCC命令,跳过ROM Write_DS18B20(0x44); //写0x44命令,开始进行温度转换 Init_DS18B20(); //复位初始化 Write_DS18B20(0xCC); //写0xCC命令,跳过ROM Write_DS18B20(0xBE); //写0xBE命令 low = Read_DS18B20(); //先读低八位(0字节) high = Read_DS18B20(); //再读高八位(1字节) temp = high<<4; temp |= (low>>4);//将两字节合成一个整型变量 return temp; } |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9055 浏览 16 评论
4086 浏览 18 评论
1174浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 18:02 , Processed in 2.479679 second(s), Total 78, Slave 59 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号