DS18B20单总线数字温度传感器使用(基于stm32f103)

注:原理图

 

18b20.c

#include "18b20.h"
#include "stm32f10x.h"                  // Device header

void DS18B20_IO_OUT(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;


    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_8;//PORTA0 推挽输出
    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
}

void DS18B20_IO_IN(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
}

//复位DS18B20

void DS18B20_Rst(void)

{                 

    DS18B20_IO_OUT(); //设置为输出模式

    DS18B20_DQ_OUT=0; //拉低DQ

    Delay_us(750);    //拉低750us(至少480us)

    DS18B20_DQ_OUT=1; //DQ=1拉高释放总线

    Delay_us(15);     //15US
  
}

//返回1:未检测到DS18B20的存在

//返回0:存在

/*
主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,
并在随后的480微秒时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。
若无低电平出现一直都是高电平说明总线上无器件应答。 
作为从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,
如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,
告诉主机本器件已做好准备。若没有检测到就一直在检测等待。
*/
u8 DS18B20_Check(void)

{   
    u8 retry=0;
    DS18B20_IO_IN();//SET PA0INPUT
    while(DS18B20_DQ_IN&&retry<200)// DS18B20_DQ_IN的作用为读引脚,观察其是否为低电平
    {
        retry++;//如果为高电平,则retry++
        Delay_us(1);
    }
    if(retry>=200)//未检测到18B20
    {
      return 1;
    }
    else
    {
        retry=0;
    }
    while(!DS18B20_DQ_IN&&retry<240)
    {
        retry++;//低电平时retry++
        Delay_us(1);
    }
    if(retry>=240)return 1;//由于拉低总线的时间在60~240us,大于240则没检测到18B20    
    return 0;
}

//初始化DS18B20的IO口DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
u8 DS18B20_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA时钟

    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_8;//PORTA0 推挽输出
    GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_8);    //输出1

    DS18B20_Rst();
    return DS18B20_Check();//未检测到DS18B20则返回1
}





//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_Write_Byte(u8 dat)     
{             
    u8 j;
    u8 testb;
    DS18B20_IO_OUT();//设置IO口为输出
    for (j=1;j<=8;j++) //八位数据,一位一位写
    {
        testb=dat&0x01;//取第一位数据
        dat=dat>>1;//移位
        if (testb) //输出高
        {
            DS18B20_DQ_OUT=0;//主机输出低电平
            Delay_us(2);//延时2us                            
            DS18B20_DQ_OUT=1;
            Delay_us(60);     //延时60us
        }
        else//输出低
        {
            DS18B20_DQ_OUT=0;//主机输出低电平
            Delay_us(60);             
            DS18B20_DQ_OUT=1;//释放总线
            Delay_us(2);                          
        }     
    }
}


//从DS18B20读取一个位
//返回值:1/0
u8 DS18B20_Read_Bit(void)
{
    u8 data;
    DS18B20_IO_OUT();//设置IO口为输出
    DS18B20_DQ_OUT=0; //输出低电平2us
    Delay_us(2);
    DS18B20_DQ_OUT=1; //拉高释放总线
    DS18B20_IO_IN();//设置IO口为输入
    Delay_us(12);//延时12us
    if(DS18B20_DQ_IN)data=1;//读取总线数据(当前电平)
    else data=0;
    Delay_us(50);//延时50us           
    return data;

}

 

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

void DS18B20_Start(void)// ds1820 start convert

{     
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
}

//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值(-550~1250)
short DS18B20_Get_Temp(void)
{
   u8 temp;
   u8 TL,TH;
   short tem;
   DS18B20_Start ();                    // ds1820 start convert
   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>xxxxx111)温度为负
   {
       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;    
}

18b20.h

#ifndef   __18B20_H
#define   __18B20_H
#include "sys.h"
#include "stm32f10x.h"
#include "delay.h"  //#include "SysTick.h"

#define DS18B20_DQ_OUT PAout(8)

#define DS18B20_DQ_IN PAin(8)
 
short DS18B20_Get_Temp(void);

u8 DS18B20_Init(void);
 
 
#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香菜是个好东西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值