30.STM32 DS18B20

1.STM32 DS18B20

1.独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。
2.测温范围 -55℃~+125℃,精度为±0.5℃。
3.支持多点组网功能,多个DS18B20可以并联在唯一的三线(地,电源,数据线)上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。
4 .工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。
5.在使用中不需要任何外围元件。
6 .测量结果以9~12位数字量方式串行传送。

2.STM32 DS18B20封装

1.
请添加图片描述
2.
请添加图片描述

3.STM32 DS18B20硬件连接请添加图片描述## 4.STM32 DS18B20

1.是一种单总线,只有一根数据线,是一种半双工通信方式
2.有6种信号,复位脉冲,应答脉冲,写0,写1,读0,和读1。这些信号,除了应答信号以为,都是由主机发送同步信号,而且发送的所有的命令和数据都是低位在前。

5.STM32 DS18B20信号

1.复位信号
单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us,,以产生复位脉冲。(脉冲产生)
接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60 us。并进入接收模式(Rx)。
接着DS18B20拉低总线60~240 us,以产生低电平应答脉冲
就是产生脉冲,进入接收,产生应答
请添加图片描述
2.应答信号
把IO口设置为输入,等待DQ被拉低,或者等待200us超过时间了(直接返回没有应答)
第二个while是判断拉低的应答是否小于240us,如果超过就不是正常的应答
请添加图片描述
3.写信号
写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。
相反的
写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。
写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。请添加图片描述
4.读信号
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。
所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。
典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。
读一个位
请添加图片描述

读一个字节
请添加图片描述

6.STM32 DS18B20获取温度流程

复位 > 等待应答 > 发SKIP ROM命令(0xcc)> 发开始转换命令 > 延时 > 发送SKIP ROM命令
发读存储器命令(0xbe) > 连续读出两个字节数据
请添加图片描述

7.STM32 DS18B20源码

正点的ds18b20代码

#include "ds18b20.h"
#include "delay.h"
//	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//DS18B20驱动代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/16
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved									  
// 	

//复位DS18B20
void DS18B20_Rst(void)	   
{                 
	DS18B20_IO_OUT();   //设置为输出
  DS18B20_DQ_OUT=0;  //拉低DQ
  delay_us(750);      //拉低750us
  DS18B20_DQ_OUT=1;  //DQ=1 
	delay_us(15);       //15US
}

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_IO_IN();    //设置为输入
    while (DS18B20_DQ_IN&&retry<200)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!DS18B20_DQ_IN&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}

//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void) 
{
  u8 data;
	DS18B20_IO_OUT();   //设置为输出
  DS18B20_DQ_OUT=0; 
	delay_us(2);
  DS18B20_DQ_OUT=1; 
	DS18B20_IO_IN();    //设置为输入
	delay_us(12);
	if(DS18B20_DQ_IN)data=1;
  else data=0;	 
  delay_us(50);           
  return data;
}

//从DS18B20读取一个字节
//返回值:读到的数据
u8 DS18B20_Read_Byte(void)   
{        
  u8 i,j,dat;
  dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
  return dat;
}

//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
 {             
    u8 j;
    u8 testb;
    DS18B20_IO_OUT();     //设置为输出
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if(testb)       // 写1
        {
            DS18B20_DQ_OUT=0;
            delay_us(2);                            
            DS18B20_DQ_OUT=1;
            delay_us(60);             
        }
        else            //写0
        {
            DS18B20_DQ_OUT=0;
            delay_us(60);             
            DS18B20_DQ_OUT=1;
            delay_us(2);                          
        }
    }
}
 
//开始温度转换
void DS18B20_Start(void)
{   						               
    DS18B20_Rst();	   
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
}

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
u8 DS18B20_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOB_CLK_ENABLE();			//开启GPIOB时钟
	
    GPIO_Initure.Pin=GPIO_PIN_12;           //PB12
    GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);     //初始化
 
 	  DS18B20_Rst();
	  return DS18B20_Check();
}

//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
    short tem;
    DS18B20_Start ();           //开始转换
    DS18B20_Rst();
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);   // skip rom
    DS18B20_Write_Byte(0xbe);   // convert	    
    TL=DS18B20_Read_Byte();     // LSB   
    TH=DS18B20_Read_Byte();     // MSB   
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;//温度为负  
    }else temp=1;//温度为正	  	  
    tem=TH; //获得高八位
    tem<<=8;    
    tem+=TL;//获得底八位
    tem=(double)tem*0.625;//转换     
	if(temp)return tem; //返回温度值
	else return -tem;    
}

  • 0
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的DS18B20读取温度值的代码示例,其中使用了STM32F10x标准库函数。需要注意的是,这里使用了单总线模式,即将DS18B20的数据线与STM32的GPIO口相连,没有使用额外的硬件电路。 ds18b20.h文件: ```c #ifndef __DS18B20_H #define __DS18B20_H #include "stm32f10x.h" #define DS18B20_GPIO_PORT GPIOA #define DS18B20_GPIO_PIN GPIO_Pin_0 float DS18B20_GetTemperature(void); #endif /* __DS18B20_H */ ``` ds18b20.c文件: ```c #include "ds18b20.h" /* DS18B20复位 */ static void DS18B20_Reset(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure); GPIO_ResetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(500); GPIO_SetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(80); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure); } /* 发送字节数据 */ static void DS18B20_WriteByte(uint8_t data) { uint8_t i = 0; GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure); for (i = 0; i < 8; i++) { if ((data >> i) & 0x01) { GPIO_ResetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(1); GPIO_SetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(80); } else { GPIO_ResetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(80); GPIO_SetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(1); } } GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure); } /* 读取字节数据 */ static uint8_t DS18B20_ReadByte(void) { uint8_t i = 0, data = 0; GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure); for (i = 0; i < 8; i++) { GPIO_ResetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(4); GPIO_SetBits(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN); delay_us(10); if (GPIO_ReadInputDataBit(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN)) { data |= 0x01 << i; } delay_us(50); } GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure); return data; } /* 获取温度值 */ float DS18B20_GetTemperature(void) { uint8_t temp_l = 0, temp_h = 0; float temperature = 0.0; DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0x44); delay_ms(800); DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); temp_l = DS18B20_ReadByte(); temp_h = DS18B20_ReadByte(); temperature = (float)((int16_t)(temp_h << 8 | temp_l)) / 16.0; return temperature; } ``` 其中,delay_us和delay_ms函数为延时函数,需要自行实现。可以参考下面的示例: ```c void delay_us(uint32_t time) { uint32_t i = 0; for (i = 0; i < time * 8; i++); } void delay_ms(uint32_t time) { uint32_t i = 0; for (i = 0; i < time * 8000; i++); } ``` 此外,需要在主函数中调用库函数GPIO_Init和RCC_APB2PeriphClockCmd等函数初始化STM32的GPIO口和时钟。具体使用方法可以参考STM32F10x官方文档和示例代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值