stm32l476rg和ds18b20

本人使用的板子为stm32l476rg,但是测出来的温度一直出现错误,想问问有没有符合ds18b20在keil中编译符合的头文件和相关文件

是不是读写延时太短,导致温度传感器反应不过来?以下程序我使用过,没有问题,可直接复制:

//温度采集模块    
/******************************************************************************/
void Init_DS18B20()//初始化ds1820
{
    unsigned char x=0;
    DQ = 1;    //DQ复位
    tmpDelay(8);  //稍做延时
    DQ = 0;    //单片机将DQ拉低
    tmpDelay(80); //精确延时 大于 480us
    DQ = 1;    //拉高总线
    tmpDelay(14);
    x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
    tmpDelay(20);
}
   unsigned char ReadOneChar()//读一个字节
{
    unsigned char i=0;
    unsigned char dat = 0;
    for (i=8;i>0;i--)
    {
        DQ = 0; // 给脉冲信号
        dat>>=1;
        DQ = 1; // 给脉冲信号
        if(DQ)
        dat|=0x80;
        tmpDelay(4);
    }
    return(dat);
}
void WriteOneChar(unsigned char dat)//写一个字节
{
    unsigned char i=0;
    for (i=8; i>0; i--)
    {
        DQ = 0;
        DQ = dat&0x01;
        tmpDelay(5);
        DQ = 1;
        dat>>=1;
    }
}

 unsigned int Readtemp()//读取温度
{
    unsigned char a=0;
    unsigned char b=0;
    unsigned int t=0;
    float tt=0;    
    Init_DS18B20();
    WriteOneChar(0xCC); // 跳过读序号列号的操作
    WriteOneChar(0x44); // 启动温度转换
    Init_DS18B20();
    WriteOneChar(0xCC); //跳过读序号列号的操作
    WriteOneChar(0xBE); //读取温度寄存器
    a=ReadOneChar();   //连续读两个字节数据   //读低8位
    b=ReadOneChar();                          //读高8位
    t=b;
    t<<=8;
    t=t|a; //两字节合成一个整型变量。
    tt=t*0.0625;  //得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度
    t= tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。
    return(t);
}

看下面的头文件是否符合你的要求:

#include"reg52.h"

#include"intrins.h"

#include"absacc.h"

#define uint unsigned int

#define uchar unsigned char

uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳管0~9

uchar code tab_motor_1[]={0x03,0x06,0x0c,0x09}; //电机正转 向上

uchar code tab_motor_2[]={0x09,0x0c,0x06,0x03}; //电机反转 向下本文引用地址:http://www.eepw.com.cn/article/201611/315460.htm

sbit ds18b20_in=P2^4; //温度传感器数据线位定义

sbit dht11=P2^2; //温湿度传感器 数据线位定义

sbit SPEAKER=P2^3; //报警器

//sbit FAN=P2^5; //电风扇

sbit HEATERS=P3^1;

sbit FAN=P3^0;

//******************全局变量定义**********************************

uchar tempL=0,tempH=0; //ds18b20读取值

uchar Set_Temp_H=30,Set_Temp_L=24;//温度边界值设定值

uchar Set_Humi_H,Set_Humi_L;

uchar Set_Illu_H,Set_Illu_L;

uchar flag_judge_temp,flag_judge_humi,flag_judge_illu; //标志位定义

float temperature,illumination,humidity; //温度值、光照值、湿度值?

//**********************延时子程序************************

void delay(uint time)

{

uint n=0;

while(n {n++;}

return;

}

void delay1()

{

int k;

for(k=0;k<600;k++);

}

void delay20ms(void) //误差 0us

{

unsigned char a,b;

for(b=215;b>0;b--)

for(a=45;a>0;a--);

_nop_; //if Keil,require use intrins.h

_nop_; //if Keil,require use intrins.h

}

//*******************显示子程序**************************

void display(float k)

{

int t;

t=k*100;

P1=0xfe;

P0=tab[t/1000];//十位

delay1();

P1=0xfd;

P0=tab[t%1000/100]-0x80;//个位+小数点

delay1();

P1=0xfb;

P0=tab[t%100/10];//十分位

delay1();

P1=0xf7;

P0=tab[t%10];//百分位

delay1();

P1=0xff;

}

//*****************ds18b20的初始化程序*********************

init_ds18b20()

{

uchar x=0;

ds18b20_in=1; //ds18b20_in先置高

delay(8);

ds18b20_in=0; //发送复位脉冲

delay(85); //延时>480ms

ds18b20_in=1; //拉高数据线

delay(14); //等待15~60ms

x=ds18b20_in; //用x的值来判断初始化是否成功

//ds18b20存在的话x=0,否则x=1

delay(20);

}

/**************************读取字符子程序******************/

ReadOneChar()

{

uchar i=0; //主机数据线先从高电平拉低1ms以上,在拉高,从而产生读信号

uchar dat=0; //每个读取周期最短持续时间为60ms,各个读取周期之间必须有1ms以上的高电平恢复??

for(i=8;i>0;i--) //一个字节8位

{

ds18b20_in=1;delay(1);

ds18b20_in=0;dat>>=1;ds18b20_in=1;

if(ds18b20_in)

dat|=0x80;

delay(4);

}

return(dat);

}

//****************向写一个字节子程序*********************/

WriteOneChar(uchar dat)

{

uchar i; //数据从高电平拉至低电平,产生写起始信号

for(i=8;i>0;i--)

{

ds18b20_in=0;

ds18b20_in=dat&0x01;

delay(5);

ds18b20_in=1;

dat>>=1;

}

delay(4);

}

/*********************************************************

向ds18b20度温度值

出口参数temprature

*********************************************************/

ReadTemperature()

{

init_ds18b20(); //初始化

WriteOneChar(0xcc); //跳过读序列号的操作

WriteOneChar(0x44); //启动温度转换

delay(125); //转换延时

init_ds18b20(); //初始化

WriteOneChar(0xcc); //跳过读序列号的操作

WriteOneChar(0xbe); //读温度寄存器(头两个值分别是温度的低位和高位)

tempL=ReadOneChar(); //读出温度的低位LSB

tempH=ReadOneChar(); //读出高位的高位MSB

//tempL=0X91;tempH=0X01;

if(tempH&0x80)

temperature=(~((tempH*256)+tempL)+1)*0.0625; //零度以下

//温度转换,把高位低位做相应的运算转换为实际的温度

else

temperature=((tempH*256)+tempL)*0.0625; //零度以上

delay(200);

return(temperature);

}

//*************************************************************************************************************************************

//**************报警子程序****************

sounder_H()

{

SPEAKER=1;

delay1();delay1();delay1();

SPEAKER=0;

}

sounder_L() //蜂鸣器 低电平响

{

SPEAKER=1;

delay1();delay1();delay1();

delay1();delay1();delay1();

delay1();delay1();delay1();

delay1();delay1();delay1();

SPEAKER=0;

}

//*************步进电机子程序**************

void motor_up()

{

int m,n;

for(m=0;m<24;m++)

for(n=0;n<4;n++)

{ P3=tab_motor_1[n];delay20ms();}

}

void motor_down()

{

int m,n;

for(m=0;m<288;m++)

for(n=0;n<4;n++)

{ P3=tab_motor_2[n];delay20ms();}

}

/*************电风扇开启子程序 **************

**************由直流电机 控制 *************/

void fan()

{

FAN=0; //开启继电器 打开电动机

}

//**************加热器*********************

void heaters()

{

HEATERS=0;

}

/*************温度判断***************

正常返回“1 否则返回0?

*************************************/

judge_temp(float i)

{

int k;

k=(int)(i*100);

if( k<=Set_Temp_H*100 && k>=Set_Temp_L*100 ) //正常范围内

{ return 1;}

if(k {

flag_judge_temp=0; return 0;}

else

{

flag_judge_temp=1; return 0;} //高于最大值

}

/*************湿度判断***************

正常返回“1 否则返回0

*************************************/

judge_humi(float ii)

{}

/*************光照判断***************

正常返回“1 否则返回0

*************************************/

judge_illu(float iii)

{}

//********************主程序****************

void main()

{

float i;

while(1)

{

i=ReadTemperature();

display(i);

/**********判断******/

{

if(!judge_temp(i))

{

if(flag_judge_temp) //温度高

{sounder_H(); fan();HEATERS=1;//motor_up();

}

else

{sounder_L(); heaters();FAN=1;//motor_down();

} //温度低

}

else {SPEAKER=1;FAN=1;HEATERS=1;}//关闭相应调节功能

}

/*********处理**********/

}

}


1.主函数

#include"key.h"
#include"led.h"
#include"lcd.h"
#include"stdio.h"
#include"ds18b20.h"

unsigned int uiDsb_Val;
unsigned char ucSec , ucSec1;
unsigned char pucStr[21];
unsigned long ulTick_ms;

void DSB_Proc(void);

int main(void)
{
    SysTick_Config(72000);    //定时1ms(HCLK = 72MHz)
    KEY_Init();
    LED_Init();
    
    STM3210B_LCD_Init();
    LCD_Clear(Blue);
    LCD_SetBackColor(Blue);
    LCD_SetTextColor(White);
    
    ds18b20_init_x();
    while(1)
    {
        LED_Disp(ucSec);
        DSB_Proc();
    }
}
void DSB_Proc(void)
    {
        if(ucSec != ucSec1)
        {
            ucSec1 = ucSec;
            uiDsb_Val = dsp_read();
            sprintf((char*)pucStr,"  Temp:%5.2fC",uiDsb_Val/16.0);
            LCD_DisplayStringLine(Line5,pucStr);
        }
    }
    
//SysTick 中断处理程序
    void SysTick_Handler(void)
    {
        ulTick_ms++;
        if(ulTick_ms % 1000 ==0)
        ucSec++;
    }
    

  1. .c文件


#include "stm32f10x.h"
#include "ds18b20.h"

#define delay_us(X)  delay((X)*72/5)

void delay(unsigned int n)
{
    while(n--);
}

void ds18b20_init_x(void)
{
      GPIO_InitTypeDef GPIO_InitStructure;
      /* Enable  clock */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  , ENABLE);
  
      /* Configure Ports */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//
void mode_input1(void )
{
      GPIO_InitTypeDef GPIO_InitStructure;

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void mode_output1(void )
{
      GPIO_InitTypeDef GPIO_InitStructure;

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//
uint8_t ow_reset(void)
{ 
    uint8_t err;

       OW_DIR_OUT(); // pull OW-Pin low for 480us
       OW_OUT_LOW(); // disable internal pull-up (maybe on from parasite)

       delay_us(400);      //about 480us
   
       // set Pin as input - wait for clients to pull low
       OW_DIR_IN(); // input

       delay_us(66);
       err = OW_GET_IN();        // no presence detect
       // nobody pulled to low, still high


       // after a delay the clients should release the line
      // and input-pin gets back to high due to pull-up-resistor
       delay_us(480-66);
       if( OW_GET_IN() == 0 )        // short circuit
      err = 1;

       return err;
 }

uint8_t ow_bit_io( uint8_t b )
{ 
     OW_DIR_OUT(); // drive bus low
     OW_OUT_LOW();    
     delay_us(1); // Recovery-Time wuffwuff was 1

     if ( b ) OW_DIR_IN(); // if bit is 1 set bus high (by ext. pull-up)
    
#define  OW_CONF_DELAYOFFSET  5
     delay_us(15-1-OW_CONF_DELAYOFFSET);
      
     if( OW_GET_IN() == 0 ) b = 0;  // sample at end of read-timeslot
    
     delay_us(60-15);
     OW_DIR_IN();

     return b;
}

uint8_t ow_byte_wr( uint8_t b )
{     
    uint8_t i = 8, j;
       do 
    { 
        j = ow_bit_io( b & 1 );
          b >>= 1;
          if( j ) b |= 0x80;
    } 
       while( --i );
       return b;
}

//
uint8_t ow_byte_rd( void )
{
       return ow_byte_wr( 0xFF ); 
}

//获取DS18B20温度传感器
unsigned int dsp_read(void)
{
    unsigned char th,tl;
    
    ow_reset();                            //复位
    ow_byte_wr(0xCC);                    //跳过Rom
    ow_byte_wr(0x44);                    //转换温度
    
    ow_reset();
    ow_byte_wr(0xCC);
    ow_byte_wr(0xBE);                    //读暂存器
    tl = ow_byte_wr(0xFF);                //读温度值低8位
    th = ow_byte_wr(0xFF);                //读温度值高8位
    return (th<<8) + tl;
}






  1. .h文件
#ifndef __DS18B20_H
#define __DS18B20_H

#include "stm32f10x.h"

#define OW_DIR_OUT()     mode_output1()
#define OW_DIR_IN()     mode_input1()
#define OW_OUT_LOW()     (GPIO_ResetBits(GPIOA,GPIO_Pin_6))
#define OW_GET_IN()      (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6))

#define OW_SKIP_ROM         0xCC
#define DS18B20_CONVERT     0x44
#define DS18B20_READ         0xBE


void ds18b20_init_x(void);
unsigned int dsp_read(void);

#endif




STM32 DS18B20温度传感器实验(HAL库)
https://blog.csdn.net/liuyy_2000/article/details/113754150