基于STM32的DS18B20驱动

发布者:huanguu最新更新时间: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驱动 引用地址:基于STM32的DS18B20驱动

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

推荐阅读最新更新时间:2024-03-16 16:24

STM32用定时器精确延时的方法(非SysTick)
用TIM2来做延时,延时基准时间1ms,最大可延时65535ms。 系统基础频率是8MHz*4=32MHz。 先配置定时器: TIM_TimeBaseInitTypeDef timInitStruct; timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 定时器基准频率32MHz timInitStruct.TIM_Prescaler = 32000; // 计数频率为1KHz timInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数 timInitStruct.TIM_Rep
[单片机]
STM32_TIM定时-中断
今天讲解STM32F103定时器定时-中断功能,在昨天定时器延时的软件工程上添加TIM3定时的功能,自己也可以试着将昨天的工程添加修改得到。 今天的软件工程下载地址(360云盘): https://yunpan.cn/cPnJ9KYcXbPsP 访问密码 acd8 工程现象:间隔(定时器定时)500ms LED变化一次, 并且串口打印 STM32F103ZE有8个定时器(TIM1 – TIM8), 改工程以TIM3定时为例。 STM32F10x的资料可以在我360云盘下载: https://yunpan.cn/crBUdUGdYKam2 访问密码 ca90 关于TIM延时,我把重要的几点在下面分别讲述,工程中
[单片机]
STM32_TIM定时-中断
JLINK 与STM32的SWD连接接线方式
有些开发板只能用Jlink烧写程序,但是没有提供标准Jlink接口,我们可以使用下面的办法,烧写:
[单片机]
JLINK 与<font color='red'>STM32</font>的SWD连接接线方式
STM32用DMA实现多路ADC通道数据采集
  今天尝试了下STM32的ADC采样,并利用DMA实现采样数据的直接搬运存储,这样就不用CPU去参与操作了。   找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的操作,保证自己对各部分设置的理解。   我这里用了3路的ADC通道,1路外部变阻器输入,另外两路是内部的温度采样和Vrefint,这样就能组成连续的采样,来测试多通道ADC自动扫描了,ADC分规则转换和注入转换,其实规则转换就是按照既定的设定来顺序转换,而注入转换就是可以在这顺序队列中插队一样,能够提前转换了。   初始化设置: 1 //PC0 FOR ANAGLE SAMPLE 2 static void Prote
[单片机]
STM32 | 分享自定义协议的一些典型例子
上次分享的《分享一个很酷的上位机软件》中,有如下协议: 有位读者朋友问数据为什么要按这样的格式来发。其实这是个自定义协议,这是上位机开发者定义的一个数据交互协议。 我们下位机往伏特加上位机发送数据需要遵循这样的协议数据,才能保证上位机能正确识别这些数据。 关于自定义协议,对于会的人很简单,对于不会的人就摸不着头脑。下面分享一些关于自定义协议的笔记,希望能对初学者有帮助,也希望大神们能多多指出不足。 什么是协议? 协议这个概念我觉得挺杂的。就像嵌入式的概念一样,说法不一,比如大家常常争论FPGA是不是嵌入式、单片机是不是属于嵌入式等等。下面简单看一下嵌入式中协议这个概念。 在互联网领域,协议常常指的是网络协议。
[单片机]
<font color='red'>STM32</font> | 分享自定义协议的一些典型例子
STM32低功耗状态的引脚配置
在STM32进入低功耗状态时,如果闲置||或者是其他的IO没有配置好。也将会增加不必要的功耗;所以在做低功耗设计的时候需要将闲置(保证系统稳定,其他的引脚据情况而定)全部设置为模拟输入配置。具体如下图所示,由此可以实现IO零消耗。
[单片机]
<font color='red'>STM32</font>低功耗状态的引脚配置
获取STM32代码运行时间的技巧
前言 测试代码的运行时间的两种方法: 1、使用单片机内部定时器,在待测程序段的开始启动定时器,在待测程序段的结尾关闭定时器。为了测量的准确性,要进行多次测量,并进行平均取值。 2、借助示波器的方法是:在待测程序段的开始阶段使单片机的一个GPIO输出高电平,在待测程序段的结尾阶段再令这个GPIO输出低电平。用示波器通过检查高电平的时间长度,就知道了这段代码的运行时间。显然,借助于示波器的方法更为简便。 借助示波器方法的实例 Delay_us函数使用STM32系统滴答定时器实现: #include systick.h /* SystemFrequency / 1000 1ms中断一次 * SystemFrequency /
[单片机]
基于STM32的电池管理系统触摸屏设计
0 引 言 电动车一直以清洁环保而备受关注,加上能源危机加剧、油价不断上涨,电动车也越来越受到用户的青睐。电动车一般采用锂电池供电,由多个单体电池串联成电池组作为动力电源。但由于各个串联单体电池特性不能保证完全一致,因此相同的电流下充电放电速度也会不同,如果不进行均衡干预,电池寿命会大大缩短,因此需要实时监控各个单体电池的状态、总电压、总电流,根据状态适时进行电池充放电均衡,并且充放电均衡时,均衡状态也要实时进行检测,所以就有了电动车电池能量管理系统(EMS)。实践证明EMS可以有效延长电动车电池使用寿命,是电动车中十分重要的管理系统。 EMS主要包括:信息采集模块、充放电均衡模块、信息集中处理模块以及显示模块。图1为自
[汽车电子]
基于<font color='red'>STM32</font>的电池管理系统触摸屏设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

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