再有5天就是“黄金”假期~放七天假,上七天班(学)!不管怎么样,该做什么就做什么。学习便学习,工作便工作,走路便走路,吃饭便吃饭。
今天我们一起完成一个比较完整的作品,基于ds18b20和labview的多点温度测量系统。我重点介绍实现多点ds18b20温度驱动模块的思路,具体实现大家可以阅读源码。驱动源码参考了不少资料,在此感谢那些乐于分享的程序员。分享,传递,沉淀,这一直都是我们坚持的信念。
关于ds18b20的特性、工作原理、时序等,请参考相关资料:
ds18b20官方手册:https://datasheets.maximintegrated.com/en/ds/ds18b20.pdf
ds18b20的复位(初始化)、读时序、写时序:https://blog.csdn.net/qq_17017545/article/details/82120467
ds18b20多点测温方案(多个ds18b20挂在一根总线上):https://blog.csdn.net/redeemer_qi/article/details/108854687
一、多点温度测量系统架构
多点温度测量系统框图如图1所示。编号为1#~8#的ds18b20连接到8051单片机的p0口,每个ds18b20占p0口的一个i/o,1#对应p0.1,2#对应p0.1, ......, 8#对应p0.7。8051单片机周期读取多点温度,通过串口上报到labview上位机。
图1 多点温度测量系统框图
在我们的例子中,只实现了3点温度。由于我们采用了模块化编程,要扩展到8路只需改动2个地方(猜猜是哪里)。图2给出了仿真电路图。我们在串口仿真电路图上增加了3个ds18b20,分别接p0.0、p0.1和p0.2。
图2 多点测温仿真电路图
二、db18b20多点温度驱动模块设计思路
网上有很多单个ds18b20温度驱动程序源码,可惜的是这些源码无法直接使用,因为源码里ds18b20初始化函数、读温度函数、写ds18b20函数等代码绑定到了固定的i/o引脚(如p1.0),读和写都是基于单个i/o实现。以至于代码无法复用。
https://blog.csdn.net/redeemer_qi/article/details/108854687提供了多个ds18b20挂在单一总线的多点测温方案,大家可以去研究研究。我们今天使用另外的思路。
思路来源:arduino里的i/o读写函数( digitalread,digitalwrite)是通过指定pin序号来实现数字引脚的读写操作的。在分析这两个函数的原型时,发现它们是通过port和bit_mask来对整个port的寄存器操作实现的。举例来说,我们要写1到p0.0,则对p0寄存器进行以下操作:
p0 = p0|0x01; //或写成:p0|=0x01; 某位或1,就能置该位为1。
对p0.0写0,则是:
p0 = p0&(~0x01); //或写为 p0 &= ~0x01; 某位与0,则该位清零。某位与1,该位保持不变。
p0是port, 0x01是p0.0在p0寄存器的bit mask。表1给出了p0.0~p0.7的位掩码(bit mask)。
i/o 位掩码(二进制)
位掩码(十六进制)
p0.0
0000_0001b
0x01
p0.1
0000_0010b
0x02
p0.2
0000_0100b
0x04
p0.3
0000_1000b
0x08
p0.4
0001_0000b
0x10
p0.5
0010_0000b
0x20
p0.6
0100_0000b
0x40
p0.7
1000_0000b
0x80
练习:使用位掩码对p0.5操作,写1和清零。
//你的答案 前面解决了写i/o。哪如何实现读取某个io的状态呢?使用位掩码~正确。
uchar value = port & bit_mask; //非零表示输入高电平,全零表示输入低电平。if(value): //高电平 do somethingelse: //低电平 do something
例如 if(p0 & 0x04)就能读取到p0.2的输入状态。请分析为什么?
我们设计了ds18b20.h,在该头文件里定义了port、bit_mask和相关的驱动函数(ds18b20初始化、读字节、写字节、读温度)。下面简要概述ds18b20.h。
1、port和bit_mask
使用宏定义了port和bit_mask。
//三个ds18b20,分别接到p0.1, p0.2, p0.3//p0口最多连接8个ds18b20#define ds18b20_port p0#define ds18b20_1_mask 0x01 //sensor no. 1#define ds10b20_2_mask 0x02 //sensor no. 2#define ds10b20_3_mask 0x04 //sensor no. 3#define ds10b20_4_mask 0x08 //sensor no. 4#define ds10b20_5_mask 0x10 //sensor no. 5
ds18b20_get_mask( ) 函数实现了传感器编号到bit_mask的映射。例如, 1的dq引脚接到px.0, 掩码为0x01。
// 由序号获得ds18b20的引脚mask// no: 1,2,3uchar ds18b20_get_mask(uchar no){ uchar pin_mask; switch(no) { case 1: {pin_mask = ds18b20_1_mask; break;} case 2: {pin_mask = ds10b20_2_mask; break;} case 3: {pin_mask = ds10b20_3_mask; break;} default: break; } return pin_mask;} 2、重要驱动函数
(1)ds18b20初始化函数
//初始化ds18b20uchar ds18b20_init(uchar sensor_no){ uchar pin_mask; uchar ack; pin_mask= ds18b20_get_mask(sensor_no); ds18b20_port |= pin_mask; //置1 delay_10xus(1); //延时10us ds18b20_port &= ~pin_mask; //清零 delay_10xus(90);//拉低900us ds18b20_port |= pin_mask; //置1 delay_10xus(8); //80us后读ds18b20的响应 ack = ds18b20_port & pin_mask; //读引脚 delay_10xus(50); return ack;}
初始化函数供读操作、写操作前调用。也可以单独调用来判断ds18b20是否存在。ack为0表示传感器应答,ack为1表示传感器未应答(多次未应答可视为传感器不存在或损坏)。
(2)读温度驱动函数
// 读温度函数,返回浮点类型温度float ds18b20_read_temperature(uchar sensor_no){ uchar low_byte = 0; uchar hight_byte = 0; int temp = 0; float temperature = 0; if(ds18b20_init(sensor_no) == 0) // 温度传感器应答了 { is_ds10b20_exist = 1; ds18b20_start_convert(sensor_no); //开始转换 ds18b20_start_read(sensor_no); //开始读取 low_byte = ds18b20_read_byte(sensor_no); //读温度的低八位 hight_byte = ds18b20_read_byte(sensor_no); //读温度的高八位 temp = (hight_byte< ds18b20_n)//已经读完所有点的温度 { ds18b20_no = 1; } delayms(1000); //等待1s左右 }}
三、labview上位机程序改进
1、添加温度保存子vi(savetemperature.vi),如图4所示。实现将三个温度和当前时间戳存储到一个表格。
图4 savetemperature.vi程序框图
程序说明如下:
① 创建文件路径,使用了应用程序目录,实现将程序存储到程序目录下。目标文件由文件名和当前日期(年月日)组成。这样实现一天一个文件。
.xls扩展名指定文件为表格。
② 打开/创建文件,并设置文件指针到文件末尾,即从文件末尾新增数据。这样,就不会覆盖旧数据。
③ 调用格式化写入文件,巧妙地通过格式化将数据写到表格里。格式化字符为:
%.1f %.1f %.1f %s
三个%.1f对应三个温度值,存为1位小数的浮点数据。 是制表符,移动到下一个表格单元。%s为字符串,这里对应着时间戳字符串。
是换行,保证下一次数据存储到表格末尾的新的一行。
2、串口解释单个传感器数据的子vi(getreceivedata.vi)
程序框图如图5所示。说明如下:
① 先读取1个字节数据,并调用强制类型转换函数转换为u8数据。此为设备号,1个字节。
② 再读取4个字节数据,并调用强制类型转换函数转换为sgl数据。此为温度数据,4个字节。注意,不能转换为dbl数据,因为labview的dbl为64位,8个字节,类型不匹配。
图5 getreceivedata.vi程序框图
下图为labview主程序框图。需要注意的是,初始化串口时,禁用串口的启用停止符选项(f常量连接的选项)。
图6 主程序框图
三、运行结果
labview上位机运行后,立马收到了很多数据(这些都是缓冲在电脑串口缓存里)。如果想要丢弃掉,可以在进入while循环前清空串口缓冲区。
使用ds18b20.h时,应注意设置(修改):
1. ds18b20_port宏定义,改为实际使用的port(p0、p1、p2、p3)
2. 新增bit_mask, ds18b20.h只定义了5个,即ds18b20_1_mask到ds18b20_5_mask。
关于bit_mask,其实也无需预先定义宏。我们可根据sensor_no算出来,核心代码如下:
bit_mask = 0x01<0; i--) { ds18b20_port &= ~pin_mask; //清零 byte_rx >>= 1; ds18b20_port |= pin_mask; //置1 _nop_();_nop_(); if(ds18b20_port & pin_mask) //读到1 { byte_rx |=0x80; } delay_10xus(30); ds18b20_port |= pin_mask; //置1 } return(byte_rx);}// 写一个字节到ds18b20void ds18b20_write_byte(uchar c, uchar sensor_no){ uchar i; uchar pin_mask = ds18b20_get_mask(sensor_no); for(i=0;i>= 1; //取下一位,准备发送 }}// 开始温度采集转换void ds18b20_start_convert(uchar sensor_no){ ds18b20_init(sensor_no); ds18b20_write_byte(0xcc, sensor_no); //skip rom ds18b20_write_byte(0x44, sensor_no); //convert command}// 开始读取温度void ds18b20_start_read(uchar sensor_no){ ds18b20_init(sensor_no); ds18b20_write_byte(0xcc, sensor_no); //skip rom ds18b20_write_byte(0xbe, sensor_no); //read command}// 读温度,返回浮点类型温度float ds18b20_read_temperature(uchar sensor_no){ uchar low_byte = 0; uchar hight_byte = 0; int temp = 0; float temperature = 0; if(ds18b20_init(sensor_no) == 0) // 温度传感器应答了 { is_ds10b20_exist = 1; ds18b20_start_convert(sensor_no); //开始转换 ds18b20_start_read(sensor_no); //开始读取 low_byte = ds18b20_read_byte(sensor_no); //读温度的低八位 hight_byte = ds18b20_read_byte(sensor_no); //读温度的高八位 temp = (hight_byte< ds18b20_n)//已经读完所有点的温度 { ds18b20_no = 1; } delayms(1000); //等待1s左右 }}void keyscan(){ float temperature; if(key_s1 == 0) { delayms(10); //消抖 if(key_s1 == 0) //按键按下,读取并上报1#地点的温度 { temperature = ds18b20_readtemperature(1); //读温度 sendtemperature(1, temperature); //发送温度 } }}//延时函数void delayms(unsigned int nms){ unsigned int i,j; for(i=0;i
模拟前端(AFE),模拟前端(AFE)系统的结构
关于科大讯飞发布汉语言智能家居语义库的分析和应用
人体静电放电模式介绍
安森美新增100V N沟道MOSFET系列:NTP641x/
京东成北京首批5G覆盖办公楼宇 网速是4G的20倍
基于DS18B20和LabVIEW的多点温度测量系统
2019年夏秋季工业企业错峰生产实施法案,限时3个月期业企业错峰生产
新能源汽车的辐射真的比燃油车高吗?
华米旗舰新品将支持全网通eSIM独立通话功能
Nordic的nRF51系列SoC器件,将传统的游戏机控制器带给了移动游戏
IMASSA3智净扫地机评测 为家庭洁净带来不一样的体验
人工智能的未来在哪里
消防报警系统的防雷防浪涌解析
模拟转换器ADC的原理和一般步骤介绍
ERS electronic 公司推出高功率温度卡盘系统,该系统主要针对嵌入式处理器、DRAM 和 NAND 等应用的晶圆测试
电子哨兵、健康码手持机、智能核酸码采集终端等,助力国庆安全出行
摩托车防盗器电路设计,Motorcycle Alarm
无线蓝牙运动耳机好用吗?双12最值得入手的十大靠谱品牌
什么是量子自旋霍尔效应?
智能联网车辆电磁抗扰检测面临的问题及对策