基于STM32的DS18B20驱动

最新更新时间:2019-03-07来源: eefocus关键字:STM32  DS18B20驱动 手机看文章 扫描二维码
随时随地手机看文章

#include "ds18b20.h"

#include "delay.h" 



short tmp_arg; //温度平滑滤波

//复位DS18B20

void DS18B20_Rst(void)   

{                 

DS18B20_IO_OUT(); //SET PG11 OUTPUT

    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(); //SET PG11 INPUT  

    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(); //SET PG11 OUTPUT

    DS18B20_DQ_OUT=0; 

delay_us(2);

    DS18B20_DQ_OUT=1; 

DS18B20_IO_IN(); //SET PG11 INPUT

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<

    }    

    return dat;

}

//写一个字节到DS18B20

//dat:要写入的字节

void DS18B20_Write_Byte(u8 dat)     

 {             

    u8 j;

    u8 testb;

DS18B20_IO_OUT(); //SET PG11 OUTPUT;

    for (j=1;j<=8;j++) 

{

        testb=dat&0x01;

        dat=dat>>1;

        if (testb) 

        {

            DS18B20_DQ_OUT=0; // Write 1

            delay_us(2);                            

            DS18B20_DQ_OUT=1;

            delay_us(60);             

        }

        else 

        {

            DS18B20_DQ_OUT=0; // Write 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_InitStructure;

  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE); //使能PORTG口时钟 


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //PORTG.11 推挽输出

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOG, &GPIO_InitStructure);



  GPIO_SetBits(GPIOG,GPIO_Pin_11);    //输出1



DS18B20_Rst();



return DS18B20_Check();

}  

//从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=~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;    

}



short Get_tempAverage(void)

{

u32 temp_sum;

short temp;


temp = DS18B20_Get_Temp();

if(DS18B20_Init() == 0) //温度采集的起始条件

{

tmp_arg = temp;

temp_sum = tmp_arg;

temp_sum = temp_sum<<3; //放大8倍

}

temp_sum += temp; //加最近的温度值7

temp_sum -= tmp_arg; //减最开始的温度值0

tmp_arg = temp_sum >> 3;

return tmp_arg;

}



 






#ifndef __DS18B20_H


#define __DS18B20_H 

#include "sys.h"   



//IO方向设置

#define DS18B20_IO_IN()  {GPIOB->CRL&=0xFFFFF0FF;GPIOB->CRL|=8 << 1;}

#define DS18B20_IO_OUT() {GPIOB->CRL&=0xFFFFF0FF;GPIOB->CRL|=7 << 1;}

////IO操作函数   

#define DS18B20_DQ_OUT PBout(1) //数据端口 PB1

#define DS18B20_DQ_IN  PBin(1)  //数据端口 PB1 



extern short tmp_arg; //温度平滑滤波



u8 DS18B20_Init(void);//初始化DS18B20

short DS18B20_Get_Temp(void);//获取温度

void DS18B20_Start(void);//开始温度转换

void DS18B20_Write_Byte(u8 dat);//写入一个字节

u8 DS18B20_Read_Byte(void);//读出一个字节

u8 DS18B20_Read_Bit(void);//读出一个位

u8 DS18B20_Check(void);//检测是否存在DS18B20

void DS18B20_Rst(void);//复位DS18B20  

short Get_tempAverage(void); //温度平滑滤波

#endif

关键字:STM32  DS18B20驱动 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/2019/ic-news030743349.html

上一篇:STM32 SPI2读W25Q128驱动
下一篇:基于STM32的智能学习空调项目的定时器捕获驱动

推荐阅读

STM32 SPI硬件模式
反复试验,发现SPI_NSS引脚的自动硬件控制与想象的不同,无论是否外加上拉,只要一使能SPI,SPI_Cmd(SPI1, ENABLE); SPI_NSS引脚就一直处于低电平,直到SPI_Cmd(SPI1, DISABLE);这个需要用程序来控制。  而用过其他芯片则是发送完成自动会拉高,这点是要注意的我说的就是做主机的时候SPI_SSOutputCmd(SPIx,ENABLE) 在soft模式时这句话有必要吗?我的理解是当hard模式,需要multimaster的时候,才应该要开启这个output功能,这点从我的截图上可以看出。我觉得,这里只要把SPI_InitStructure
发表于 2022-02-21
<font color='red'>STM32</font> SPI硬件模式
STM32 timer input filter
STM32的定时器输入通道都有一个滤波单元,分别位于每个输入通路上(下图中的黄色框)和外部触发输入通路上(下图中的兰色框),它们的作用是滤除输入信号上的高频干扰。具体操作原理如下:在TIMx_CR1中的CKD[1:0]可以由用户设置对输入信号的采样频率基准,有三种选择:1)采样频率基准fDTS=定时器输入频率fCK_INT2)采样频率基准fDTS=定时器输入频率fCK_INT/23)采样频率基准fDTS=定时器输入频率fCK_INT/4然后使用上述频率作为基准对输入信号进行采样,当连续采样到N次个有效电平时,认为一次有效的输入电平。实际的采样频率和采样次数可以由用户程序根据需要选择;外部触发输入通道的滤波参数在从模式控制寄存器(TI
发表于 2022-02-21
<font color='red'>STM32</font> timer input filter
关于STM32影子寄存器和预装载寄存器和TIM_ARRPreloadConfig
本文的说明依据STM32参考手册(RM0008)第10版:英文:http://www.st.com/stonline/products/literature/rm/13902.pdf中译文:http://www.stmicroelectronics.com.cn/stonline/mcu/images/STM32_RM_CH_V10_1.pdf在STM32参考手册的第13、14章中,都有一张定时器的框图,下面是第14章中定时器框图的局部,图中黄色框所示的是auto-reload register,在下面的第14.3.2节"Counter Modes"就解释了auto-reload register的用法。在图中可
发表于 2022-02-21
关于<font color='red'>STM32</font>影子寄存器和预装载寄存器和TIM_ARRPreloadConfig
stm32 Fdts
发表于 2022-02-21
<font color='red'>stm32</font> Fdts
STM32定时器输出比较模式
OCx与OCxREF和CCxP之间的关系初学STM32,我这个地方卡了很久,现在终于有些明白了,现在把我的理解写下与大家共享,如果有不对的地方,还请指出。-----------------------------------------------------------------------------------------------------------------------TIM_OCMode选择定时器模式。该参数取值见下表:TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //设置跳变值,当计数器计数到这个值时,电平发生跳变TIM_OC2PreloadConfig(TIM3, TI
发表于 2022-02-18
<font color='red'>STM32</font>定时器输出比较模式
stm32库函数学习篇
两天学习了一下stm32通用定时器的输入捕获功能。在网上看到很多网友说触发中断程序进不了,于是自己也测试了个小程序,还好能够进入中断。呵呵~ 实现功能:PA8随意延时驱动led灯闪烁,并且将PA8用杜邦线连接到PA7口,PA7是通用定时器TIM3的2通道,在TIM3_CH2触发中断程序中取反连接到PD2口的led灯,指示中断程序运行,并且每次进入中断后改变触发捕获的极性。实现两个led灯会交替闪烁。 先有必要了解stm32定时器的输入触发模块,如下图:需要注意的是,一眼望去一个定时器似乎有8个通道,左边四个,右边四个,但其实左边和右边是共用相同的IO引脚,所以名称标注是一模一样。也就是说,每个通用定时器都只有四个
发表于 2022-02-18
<font color='red'>stm32</font>库函数学习篇
小广播
实战 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved