使用STM32编写DS18B20温度传感器代码

起因是制作恒温箱,csdn现有的温度传感器代码在使用中都或多或少有问题,现分享一下。(32版本!!!) 

使用的是DS18B20温度传感器模块,三根线直接连接到最小核心系统板,再加上显示屏就能读取显示温度了。本人亲测并使用的代码,完美运行,代码逻辑很简单,看懂不难。

以下为运行代码,可自己更改一下引脚配置,在这我的DQ线连接的PB14口。

DS18B20.c:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

#define DS18B20_GPIO    GPIOB
#define DS18B20_Pin     GPIO_Pin_14

#define DQ_H     GPIO_SetBits(DS18B20_GPIO,DS18B20_Pin)        			//PB14拉高
#define DQ_L     GPIO_ResetBits(DS18B20_GPIO,DS18B20_Pin)				    //PB14拉低
#define DQ_Read  GPIO_ReadInputDataBit(DS18B20_GPIO,DS18B20_Pin)           //PB14读取

uint8_t flag=0;

void DS18B20_Init(void) 																		//PB1初始化
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = DS18B20_Pin;             
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DS18B20_GPIO, &GPIO_InitStructure);
}

void DS18B20_Output(void)      //输出模式            
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = DS18B20_Pin;             
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DS18B20_GPIO, &GPIO_InitStructure);
}

void DS18B20_Input(void)      //输入模式
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = DS18B20_Pin;             
	GPIO_Init(DS18B20_GPIO, &GPIO_InitStructure);
}

uint8_t DS18B20_Reset(void)      //复位
{
	uint8_t flag;
	DS18B20_Output();
	DQ_H;
	Delay_us(5);
	
	DQ_L;
	Delay_us(480);
	DQ_H;
	Delay_us(60);
	DS18B20_Input();
	flag=DQ_Read;
	Delay_us(480);
	DS18B20_Output();
	DQ_H;
	return flag;
}

void DS18B20_WriteData(uint8_t data)     // 写数据
{
	for(uint8_t i=0;i<8;i++)
	{
		DS18B20_Output();  //输出状态
		DQ_L;
		Delay_us(2);
		if(data&0x01)     //低位开始
		{
			DQ_H;
		}
		else
		{
			DQ_L;
		}
		Delay_us(60);
		DQ_H;
		data = data>>1;
	}
	
}

uint8_t DS18B20_ReadData(void)      //读数据
{
	uint8_t data =0;
	
	for(uint8_t i=0;i<8;i++)
	{
		data=data>>1;
		DS18B20_Output();   //输出状态
		DQ_L;
		Delay_us(2);
		DQ_H;
		Delay_us(2);
		DS18B20_Input();   //输入状态
		if(DQ_Read)
			data|=0x80;     //放入高位,再移位到低位
		Delay_us(60);
	}
	return data;
}

uint16_t DS18B20_ReadTemp(void)   //读取温度
{
	uint8_t DL,DH;
	uint16_t data;	
	uint16_t Temperature=0;
	flag=0;
	DS18B20_Reset();              //复位
	DS18B20_WriteData(0XCC);      //跳过ROM检测
	DS18B20_WriteData(0X44);      //启动温度转换
	Delay_ms(750);                //延时,等待转换完成
	DS18B20_Reset();              //复位
	DS18B20_WriteData(0XCC);      //跳过ROM检测
	DS18B20_WriteData(0XBE);      //读取暂存器指令
	DL=DS18B20_ReadData();        //读温度低位
	DH=DS18B20_ReadData();        //读温度高位
	data=DH;
	data=data<<8;
	data|=DL;
	if((data&0XF800)==0XF800)    
	{
		data=~data+0X01;
		flag=1;
	}
		
	Temperature=data * 0.0625*10; //数据格式的问题 扩大了10倍没有小数
	return Temperature;           //例如返回225 要处理为22.5度
}

 尤其需要注意最后的数据读取格式,本人出错就在这(读取到的全是0)。

DS18B20.h:

#ifndef __DS18B20_H
#define __DS18B20_H

void DS18B20_Init(void);
unsigned char DS18B20_Reset(void);
extern unsigned char flag;
uint16_t DS18B20_ReadTemp(void);

#endif

 main.c:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "DS18B20.h"

int Temp;          //读取的温度参数
int FLAG=1;        //标志位

int main(void)
{
    OLED_Init( );
    DS18B20_Init();
    FLAG=DS18B20_Reset();
    Delay_s(1);

    while(1)
    {
        if(FLAG==0)
        {
            OLED_ShowChinese(1,1,0);
            OLED_ShowChinese(1,2,1);
            Temp=DS18B20_ReadTemp();
           if(flag==1)
			{
				OLED_ShowString(1, 5, ":-");
				OLED_ShowString(1, 10, ".");
				OLED_ShowNum(1,7,Temp/10%100,3);
				OLED_ShowNum(1,11,Temp%10,1);
			}
			else
			{
				OLED_ShowString(1, 5, ":+");
				OLED_ShowString(1, 10, ".");
				OLED_ShowNum(1,7,Temp/10%100,3);
				OLED_ShowNum(1,11,Temp%10,1);
			}
        }
        else
        {
           OLED_ShowString(1,1,"No   sensor  ");
		   Delay_ms(5);
        }
    }
        
        
       
}
   

需要注意的还是数据格式的问题,在显示的时候要对数据进行处理,oled显示就自己按需求配置一下。 

若还需要在别处用到读取到的温度参数,同样的要进行数据处理后再传参等。简单的就是Temp/10.0

作者:森森森1

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32编写DS18B20温度传感器代码

发表评论