资讯详情

16.[STM32]从原理开始带你了解DS18B20温度传感器-四位数码管显示温度

??? 大家好,我叫你。DW,每天分享一些我学到的新知识,期待和大家一起进步 ?? ??? 系列专栏:STM32 ?? ??? ??? ??小实验目标显示在四位数字管上DS18B20收集到的温度值 ??如果你写得不好,欢迎你纠正。

??开发板:正原子STM32F103Mini版?? 2022年6月1日创作时间

由于我最近拿到了驾照和忙碌的毕业论文,我停了20多天。我从今天开始恢复更新。接下来,我将继续更新一些常用的传感器,期待与您一起进步!

1. 数字温度传感器(DS18B20)

2. 操作函数的编写


???-------------------------------???

???-------------------------------???

1. 数字温度传感器(DS18B20)

DS18B20具,简化了分布式温度传感应用,不需要外部元件的可用数据总线,电压范围为3.0 V至5.5 V 没有备用电源 测量温度范围-55 ° C至 125 ℃ 。

DS18B20可以程序设置,精度为:±0.5°C。可选较小的包装方法,电压适用范围较宽。用户设置的分辨率设置和报警温度存储在EEPROM中,

DS18B性能是新一代产品中最好的!性价比也很出色!由于DS18B20是口线通信,所以中央微处理器和DS18B只有一条口线连接。读写和温度转换可以从数据线本身获得能量,无需外部电源。。它有许多用途,包括空调环境控制、建筑内温设备或机器感知、过程监测和控制。

e2edc9b9c647410c89fcd8386cb2a2b9.jpeg

同时,传感器总是显示85℃原因。在实际操作中,正负连接,传感器立即加热,液晶屏不能显示读数,正负连接显示85℃。

2. 编写操作函数

void DS18B20_UserConfig(void){   GPIO_InitTypeDef GPIO_InitStructure;//定义结构体    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置PB0时钟    GPIO_InitStructure.GPIO_Pin = DS18B20;//PA0  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;///端口输出率  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推拉输出模式  GPIO_Init(DS18B20_PROT,&GPIO_InitStructure);///初始串口 }

///输入输出模式选择函数  void Output_Input_Mode(u8 cmd){    GPIO_InitTypeDef GPIO_InitStructure;//定义结构体    if(cmd){//1:输出模式    GPIO_InitStructure.GPIO_Pin = DS18B20;//PB0  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;///端口输出率  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推拉输出模式  }  else{//0:输入模式     GPIO_InitStructure.GPIO_Pin = DS18B20;//PB0  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;///上拉模式  }  GPIO_Init(DS18B20_PROT,&GPIO_InitStructure);///初始串口 }

从上图可以看出,VCC中间的线是数据线,GND为地。第一步是用单片机发送指令将数据线引脚输出到低电平,并保持480us之后,释放总线(拉高,延迟30us);第二,之后DS18B如果它的脉冲存在或不存在,20开始反馈给单片机。DS18B20存在,它会在60-240us内向单片机反馈低电平,读这个电平信号就知道了DS18B具体函数如下:

///启动信号 判断是否成功 u8 DS18B20_Start_Signal(void){   u8 data;    //写  Output_Input_Mode(1)  DS18B20_Low;  delay_us(480);  DS18B20_High;  delay_us(30);    //阅读引脚状态 1:DS18B20失败 0:DS18B20成功  Output_Input_Mode(0)  data = GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20);//读取输入状态  60~240us  delay_us(200);//200us  480 30 240=750  960-750=210  取200us即可    return data; }

当我们插上DS18B20后,数字管显示0,拔掉DS18B20后,数字管显示1表示我们 启动程序没有问题。

此时序图由写0和写1操作两部分组成。我们只需要读写1操作,因为如果不是1,那就是0,系统会自动补充0。

我们需要一个一个地写数据,一个字节需要八次。编写数据时,需要将数据引脚配置为推拉输出。从写1部分时序图可以看出,我们需要降低总线的时间>1us,我们选择延迟2us即可,2us之后可以把数据写到总线,然后把数据写到总线;DS18B20先出低位后出高位,所以数据需要从高位移动到低位,但每次都需要先判断低位;写完之后,我们需要进行一定的延时,延时时间为:15us 30us=40us,此时是将数据写入相应寄存器的时间,最后将总线拉高释放总线,然后将数据每个循环向右移动,以便可以写第二帧数据了。

//向DS18B20写数据
//写:输出模式 1
void DS18B20_Write_Byte(u8 data){
	

	for(u8 i=0;i<8;i++){
		
		Output_Input_Mode(1);
		DS18B20_Low;
		delay_us(2);
		
		((data&0x01)) ? DS18B20_High : DS18B20_Low;//DS18B20 低位先出,故&0x01
		delay_us(45);
		DS18B20_High;//拉高总线

		data>>=1;//数据右移八次 既完成写8bit数据
	}
}

  

        读时序需要带有返回值, 所以定义一个带返回值的函数。对总线进行读数据之前需要对数据进行移位,之后配置数据线IO口的状态,对引脚进行写操作,拉低数据引脚,延时2us后在拉高数据引脚;之后进行读操作,IO口选择为输入模式,如果读到的数据为“1”,就或上“1”,否则系统自动补“0”,由于读操作流程的时间和写操作流程的时间是一样的,故也需要增加45us的延时。

//读DS18B20数据
//读:输入模式 0
u8 DS18B20_Read_Byte(void){

	u8 data;
	
	for(u8 i=0;i<8;i++){
		
		data>>=1;
		Output_Input_Mode(1);
		DS18B20_Low;
		delay_us(2);
		DS18B20_High;//拉高总线
		
		Output_Input_Mode(0);
		if(GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20) == SET){
			
			data |= 0x80;//从高位开始
		}
			delay_us(45);
	}
	return data;
}

Ds18b20用12位存贮温值度最高位为符号位下图为18b20的温度存储方式,负温度 S = 1/ 正温度 S = 0 。

传输方式先传低位后传高位。

配置寄存器允许用户设定9位,10位,11位和12位的温度分辨率,分别对应着温度的分辨率为:0.5°C,0.25°C,0.125°C,0.0625°C

默认为12位分辨率:0.0625°C

(1)发送启动信号,向总线写指令;

(2)由于先读取低位(LSB).在读取高位(MSB),故需要合并数据(temp);

(3)温度转换公式,负温度转换:反码+1;

//获取温度值 
void DS18B20_Read_Temperature(u16 *data){
	
	u8 LSB = 0,MSB = 0; 
	u16 temp;
	//温度转换
	DS18B20_Start_Signal();
	DS18B20_Write_Byte(0xcc);//跳过ROM
	DS18B20_Write_Byte(0x44);//温度变换
	//delay_ms(750);
	//12位精度 750ms  数码管本身有延时,故这个延时可以去掉
	
	//读取寄存器
	DS18B20_Start_Signal();
	DS18B20_Write_Byte(0xcc);//跳过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;
	}
}

        把程序性烧录进去后,可以看到四位数码管显示对应的温度。 

        好了,今天的分享就到这里了,如果觉得有用的话记得收藏和点赞哦,谢谢大家!

🌜🌜🌜🌜🌜🌜

参考资料: 1.STM32固件库手册 2.正点原子STM32不完全手册_库函数版本 3.参考视频 4.数字电子技术基础 

5.芯片驱动四位数码管">15.[STM32]一篇文章教会你使用75HC595芯片驱动四位数码管

资料已上传,需要自取

标签: 电子设备温度传感器电子20pin连接器外接5k电阻到5v

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台