DS18B20温度模块驱动(STM32)

一、前期准备
单片机:STM32F103C8T6
开发环境:MDK5.14
库函数:标准库V3.5
DS18B20模块:淘宝有售
在这里插入图片描述

二、实验效果
在这里插入图片描述
在这里插入图片描述

三、驱动原理
看数据手册。
需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。

四、驱动代码
ds18b20.h

#ifndef __DS18B20_H__
#define	__DS18B20_H__
#include "stm32f10x.h"
#include "gpio.h"
#include "delay.h"

#define DS18B20_Direction_I  {GPIOA->CRL &= 0XFFFFFFF0; GPIOA->CRL |= 8;}
#define DS18B20_Direction_O  {GPIOA->CRL &= 0XFFFFFFF0; GPIOA->CRL |= 3;}

#define	DS18B20_DQ_O		 PAout(0) 
#define	DS18B20_DQ_I		 PAin(0) 

extern uint8_t DS18B20_IsOnline(void) ;
extern void DS18B20_StartConversion(void);
extern uint8_t DS18B20Configuration(void);
extern int16_t DS18B20_GetTemperature(void);
#endif

ds18b20.c

#include "ds18b20.h"

//复位DS18B20
void DS18B20_Reset(void)	   
{                 
	DS18B20_Direction_O; 	//SET PG11 OUTPUT
    DS18B20_DQ_O = 0; 	//拉低DQ
    DelayUs(750);    	//拉低750us
    DS18B20_DQ_O = 1; 	//DQ=1 
	DelayUs(15);     	//15US
}

//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
uint8_t DS18B20_IsOnline(void) 	   
{   
	uint16_t retry = 0;
	DS18B20_Direction_I;	//SET PA0 INPUT
	
    while (DS18B20_DQ_I && retry < 200)
	{
		retry++;
		DelayUs(1);
	};	 
	
	if(retry >= 200)
	{
		return 1;
	}
	else 
	{
		retry = 0;
	}
	
    while (!DS18B20_DQ_I && retry < 240)
	{
		retry ++;
		DelayUs(1);
	};
	
	if(retry >= 240)
	{
		return 1;	
	}		
	 
	return 0;
}

//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_ReadBit(void) 	 
{
    uint8_t data;
	DS18B20_Direction_O;	
    DS18B20_DQ_O = 0; 
	DelayUs(2);
    DS18B20_DQ_O = 1; 
	DS18B20_Direction_I;	
	DelayUs(12);
	if(DS18B20_DQ_I)
	{
		data = 1;
	}
    else 
	{
		data = 0;
	}	
    DelayUs(50);           
    return data;
}

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

//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_WriteByte(uint8_t dat)     
 {             
    uint8_t j;
    uint8_t testb;
	DS18B20_Direction_O;	//SET PG11 OUTPUT;
    for (j = 1; j <= 8; j ++) 
	{
        testb = dat & 0x01;
        dat >>= 1;
        if (testb) 
        {
            DS18B20_DQ_O = 0;	// Write 1
            DelayUs(2);                            
            DS18B20_DQ_O = 1;
            DelayUs(60);             
        }
        else 
        {
            DS18B20_DQ_O = 0;	// Write 0
            DelayUs(60);             
            DS18B20_DQ_O = 1;
            DelayUs(2);                          
        }
    }
}
 
//开始温度转换
void DS18B20_StartConversion(void) 
{   						               
    DS18B20_Reset();	   
	DS18B20_IsOnline();	 
    DS18B20_WriteByte(0xcc);	// skip rom
    DS18B20_WriteByte(0x44);	// convert
} 

//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
uint8_t DS18B20Configuration(void)
{
 	GPIO_InitTypeDef  MyGPIO;
 	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //使能PORTA口时钟 
	
 	MyGPIO.GPIO_Pin = GPIO_Pin_0;				//PORTA.00 推挽输出
 	MyGPIO.GPIO_Mode = GPIO_Mode_Out_PP; 		  
 	MyGPIO.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &MyGPIO);
 	DS18B20_DQ_O = 1;    //输出1
	
	DS18B20_Reset();
	return DS18B20_IsOnline();
}  

//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250) 
int16_t DS18B20_GetTemperature(void)
{
    uint8_t temp;
    uint8_t TL,TH;
	int16_t tem;
    DS18B20_StartConversion();  			// ds1820 start convert
    DS18B20_Reset();
    DS18B20_IsOnline();	 
    DS18B20_WriteByte(0xCC);	// skip rom
    DS18B20_WriteByte(0xBE);	// convert	    
    TL = DS18B20_ReadByte(); 	// LSB   
    TH = DS18B20_ReadByte(); 	// MSB  
	    	  
    if(TH > 7)
    {
        TH = ~TH;
        TL = ~TL; 
        temp = 0;					//温度为负  
    }
	else 
	{
		temp = 1;				//温度为正	  	
	}		
    tem = TH; 					//获得高八位
    tem <<= 8;    
    tem += TL;					//获得底八位
    tem = (float)tem * 0.625;		//转换     
	if(temp)
	{
		return tem; 		//返回温度值
	}
	else 
	{
		return -tem;
	}		
}

由于作者能力有限,有不妥之处欢迎指正,邮箱alex_hua@foxmail.com

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值