本人使用的板子为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++;
}
#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;
}
#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