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可以程序设定9~12位的分辨率,温度转换为12位数字格式最大值为750毫秒,精度为:±0.5°C。可选更小的封装方式,更宽的电压适用范围。分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存

        DS18B20的性能是新一代产品中最好的!性能价格比也非常出色!由于DS18B20是一条口线通信,所以中央微处理器与DS18B20只有一个一条口线连接。为读写以及温度转换可以从数据线本身获得能量,不需要外接电源。 因为每一个DS18B20包含一个独特的序号,多个DS18B20可以同时存在于一条总线。它的用途很多,包括空调环境控制,感测建筑物内温设备或机器,并进行过程监测和控制。

DS18B20实物图和引脚封装图

e2edc9b9c647410c89fcd8386cb2a2b9.jpeg

面对着平的那一面,左负右正,一旦接反就会立刻发热,有可能烧毁!同时,接反也是导致该传感器总是显示85℃的原因。实际操作中将正负反接,传感器立即发热,液晶屏不能显示读数,正负接好后显示85℃。

DS18B20引脚说明:

  • GND:电源地线
  • DQ:数字信号输入/输出端。
  • VDD:外接供电电源输入端。
  • DS18B20与STM32连接接线图:

  • GND:地
  • DQ:接PA0同时接一个上拉电阻
  • VDD:3.3V
  •  ef24e9e3a4354b2fbb6be98483813054.png

    外接上拉电阻阻值:

    DS18B20的工作电流约为1mA,VCC一般为5V,则电阻R=5V/1mA=5KΩ,故接了一个阻值相近的5.1kΩ电阻。

    2. 操作函数的编写

    1.DS18B20函数的初始化 

    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);//初始串口
    }

    2. 切换DS18B20输出输入引脚函数

    //输入输出模式选择函数 
    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);//初始串口
    }

     3. DS18B20启动时序

    551bff23366345afbd1213a96df16fb1.png

            由上图可以知道,VCC为电源,中间的那根线为数据线,GND为地。第一步,利用单片机发送指令将数据线引脚输出为低电平且保持480us的时间,之后,释放总线(拉高,延时30us);第二,之后DS18B20开始向单片机进行信号的反馈,反馈它的脉冲存在或者不存在,如果DS18B20存在,它会在60-240us之内向单片机反馈一个低电平,我们读取这个电平信号就可以知道DS18B20是否存在了,具体函数如下:

    //启动信号 判断是否成功
    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,则说明我们的 启动程序没有问题。 

    6edebadf163245e49f7ca238ef3fd67e.jpeg

     4.DS18B20写时序

     b81b22d7625a4438bcee6ea18219e1a3.png

            这个时序图有两部分组成,分别为写“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数据
    	}
    }

    5. DS18B20读时序

    dfac78f48a14474daaee6031a03864aa.png  

            读时序需要带有返回值, 所以定义一个带返回值的函数。对总线进行读数据之前需要对数据进行移位,之后配置数据线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;
    }

    6.温度转换 

    温度寄存器格式和温度/数据对应关系 608032de370744bda5ce7ea613749abf.png

    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芯片驱动四位数码管

    资料已上传,需要自取

    物联沃分享整理
    物联沃-IOTWORD物联网 » 16. STM32学习:DS18B20温度传感器与四位数码管显示

    发表评论