作者简介:大家好啊,我叫DW,每天分享一些我新学到的知识,期待和大家一起进步
系列专栏:STM32
小实验目标:读取3个DS18B20的ROM并实现多点测量温度
如有写得不好的地方欢迎大家指正开发板:正点原子STM32F103Mini版
创作时间:2022年6月6日
在之前写过的DS18B20文章的基础上,稍做修改,就可以测量每个DS18B20的64位ROM序列号。
16.[STM32]从原理开始带你了解DS18B20温度传感器-四位数码管显示温度
一字节为8位,我们需要读出8字节,8字节就为64位数据,我们把8字节的数据存放到一个数组中,然后通过串口打印出来。在之前文章的基础上,添加一个读DS18B20ROM的函数。
//读取ROM
void DS18B20_Read_Rom(void){
u8 rom[8];
DS18B20_Start_Signal();//启动信号
DS18B20_Write_Byte(0x33);//读ROM
for(u8 i=0;i<8;i++){
rom[i] = DS18B20_Read_Byte();//读取一个字节
printf("%#.2x,",rom[i]);//%#x:打印的十六进制结果前面加上0X
}
printf("\r\n");
}
我们通过该函数,可以读出8字节数据,并通过串口打印出来,本实验需要用到3个DS18B20,不能一次读取完3个DS18B20的64位ROM序列号,需要一个一个读取,读取三次,获得64位ROM序列号后就可以把他们挂接在一根总线上,然后同时读取温度了。
下面是获取到的3个DS18B20对应的三组ROM表。
得到3组64位ROM后,我们创建3个数组,分别存放读取到的ROM,只有通过64位ROM我们才能搜索对应的DS18B20,之后通过ROM匹配,我们就可以匹配总线上对应的DS18B20,进而实现温度的转换。
u8 rom1[]={0x28,0xd3,0xf6,0x48,0xf6,0xdd,0x3c,0xd5,}; //64 ROM
u8 rom2[]={0x28,0xa3,0xf9,0x96,0xf0,0x01,0x3c,0xf2,};
u8 rom3[]={0x28,0x18,0xa8,0x96,0xf0,0x01,0x3c,0x55,};
由于需要直接调用数组,为了获取数据更加准确,故我们需要设置一个指针类型的变量rom,8字节的ROM需要写8次,每次写一个字节。
在写每个字节之前需要发送一个启动信号,之后再发送匹配ROM的指令0X55,最后在进行写一个字节的操作。
//匹配ROM
void DS18B20_Match_Rom(u8 *rom){
DS18B20_Start_Signal();//启动信号
DS18B20_Write_Byte(0x55); //匹配ROM
for(u8 i=0;i<8;i++){
DS18B20_Write_Byte(*rom++);//写字节
}
}
在DS18B20温度转换函数的基础上,稍做修改,加上刚刚编写的匹配ROM函数,修改后的函数如下。
void DS18B20_Read_Temperature(u8 *rom,u16 *data){
u8 LSB = 0,MSB = 0;
u16 Temp = 0;
//温度转换
DS18B20_Match_Rom(rom);//匹配ROM
DS18B20_Write_Byte(0X44);//温度变换
delay_ms(750);
//12位精度 750ms 数码管本身有延时,故这个延时可以去掉
DS18B20_Match_Rom(rom);
DS18B20_Write_Byte(0XBE);//读暂存存储器
LSB = DS18B20_Read_Byte();
MSB = DS18B20_Read_Byte();
Temp = (MSB<<8) | LSB;//数据合并为16位
if((Temp&0XF800) == 0XF800){ //负温度;s=1 正温度: s=0
*data =(((~Temp+0X01)* -0.0625)+0.5)*10.0;
}
else{
*data =((Temp*0.0625)+0.5)*10.0;
}
}
最后,在main函数中调用温度转换函数和LCD1602显示函数即可。
#include "delay.h"
#include "lcd1602.h"
#include "DS18b20.h"
#include "usart.h"
u8 rom1[]={0x28,0xd3,0xf6,0x48,0xf6,0xdd,0x3c,0xd5,}; //64 ROM
u8 rom2[]={0x28,0xa3,0xf9,0x96,0xf0,0x01,0x3c,0xf2,};
u8 rom3[]={0x28,0x18,0xa8,0x96,0xf0,0x01,0x3c,0x55,};
int main(){
u16 Temp = 0;
delay_init();
LCD1602_UserConfig();
LCD1602_Init();
DS18B20_UserConfig();
uart_init(115200);
while(1){
DS18B20_Read_Rom();//测量ROM
delay_ms(1000);
DS18B20_Read_Temperature(rom1,&Temp);
LCD1602_Number_Display(0XC0,Temp);
DS18B20_Read_Temperature(rom2,&Temp);
LCD1602_Number_Display(0XC6,Temp);
DS18B20_Read_Temperature(rom3,&Temp);
LCD1602_Number_Display(0XCC,Temp);
}
}
好了,一起来看实验效果图吧!在LCD1602上显示3个位置DS18B20测量的温度,实现的多个DS18B20挂接在一条总线的操作。
提示:
本文章选择了两片74HC595驱动LCD1602液晶,如果没有该芯片的话可以看看之前的第四篇文章,把LCD1602部分的函数调换即可。
3个DS18B20是通过一条总线连接的,即数据引脚PB0都连接到DS18B20的数据总线上。
本章结束,我们下一章见
参考资料:
1.STM32固件库手册
2.正点原子STM32不完全手册_库函数版本
3.参考视频
4.4.STM32F103-LCD1602显示字符
5.17.[STM32]仅用三根线带你驱动LCD1602液晶
资料已上传,需要自取