一、前期准备
单片机:STM32F103C8T6
开发环境:MDK5.14
库函数:标准库V3.5
DS18B20模块:淘宝有售
二、实验效果
三、驱动原理
看数据手册。
需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。
四、驱动代码
ds18b20.h
#ifndef __DS18B20_H__
#define __DS18B20_H__
#include "stm32f10x.h"
#include "gpio.h"
#include "delay.h"
#define DS18B20_Direction_I {GPIOA->CRL &= 0XFFFFFFF0; GPIOA->CRL |= 8;}
#define DS18B20_Direction_O {GPIOA->CRL &= 0XFFFFFFF0; GPIOA->CRL |= 3;}
#define DS18B20_DQ_O PAout(0)
#define DS18B20_DQ_I PAin(0)
extern uint8_t DS18B20_IsOnline(void) ;
extern void DS18B20_StartConversion(void);
extern uint8_t DS18B20Configuration(void);
extern int16_t DS18B20_GetTemperature(void);
#endif
ds18b20.c
#include "ds18b20.h"
//复位DS18B20
void DS18B20_Reset(void)
{
DS18B20_Direction_O; //SET PG11 OUTPUT
DS18B20_DQ_O = 0; //拉低DQ
DelayUs(750); //拉低750us
DS18B20_DQ_O = 1; //DQ=1
DelayUs(15); //15US
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
uint8_t DS18B20_IsOnline(void)
{
uint16_t retry = 0;
DS18B20_Direction_I; //SET PA0 INPUT
while (DS18B20_DQ_I && retry < 200)
{
retry++;
DelayUs(1);
};
if(retry >= 200)
{
return 1;
}
else
{
retry = 0;
}
while (!DS18B20_DQ_I && retry < 240)
{
retry ++;
DelayUs(1);
};
if(retry >= 240)
{
return 1;
}
return 0;
}
//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_ReadBit(void)
{
uint8_t data;
DS18B20_Direction_O;
DS18B20_DQ_O = 0;
DelayUs(2);
DS18B20_DQ_O = 1;
DS18B20_Direction_I;
DelayUs(12);
if(DS18B20_DQ_I)
{
data = 1;
}
else
{
data = 0;
}
DelayUs(50);
return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t DS18B20_ReadByte(void)
{
uint8_t i, j, dat;
dat = 0;
for (i = 1; i <= 8; i ++)
{
j = DS18B20_ReadBit();
dat = (j << 7) | (dat >> 1);
}
return dat;
}
//写一个字节到DS18B20
//dat:要写入的字节
void DS18B20_WriteByte(uint8_t dat)
{
uint8_t j;
uint8_t testb;
DS18B20_Direction_O; //SET PG11 OUTPUT;
for (j = 1; j <= 8; j ++)
{
testb = dat & 0x01;
dat >>= 1;
if (testb)
{
DS18B20_DQ_O = 0; // Write 1
DelayUs(2);
DS18B20_DQ_O = 1;
DelayUs(60);
}
else
{
DS18B20_DQ_O = 0; // Write 0
DelayUs(60);
DS18B20_DQ_O = 1;
DelayUs(2);
}
}
}
//开始温度转换
void DS18B20_StartConversion(void)
{
DS18B20_Reset();
DS18B20_IsOnline();
DS18B20_WriteByte(0xcc); // skip rom
DS18B20_WriteByte(0x44); // convert
}
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
uint8_t DS18B20Configuration(void)
{
GPIO_InitTypeDef MyGPIO;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PORTA口时钟
MyGPIO.GPIO_Pin = GPIO_Pin_0; //PORTA.00 推挽输出
MyGPIO.GPIO_Mode = GPIO_Mode_Out_PP;
MyGPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &MyGPIO);
DS18B20_DQ_O = 1; //输出1
DS18B20_Reset();
return DS18B20_IsOnline();
}
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值 (-550~1250)
int16_t DS18B20_GetTemperature(void)
{
uint8_t temp;
uint8_t TL,TH;
int16_t tem;
DS18B20_StartConversion(); // ds1820 start convert
DS18B20_Reset();
DS18B20_IsOnline();
DS18B20_WriteByte(0xCC); // skip rom
DS18B20_WriteByte(0xBE); // convert
TL = DS18B20_ReadByte(); // LSB
TH = DS18B20_ReadByte(); // 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;
}
}
由于作者能力有限,有不妥之处欢迎指正,邮箱alex_hua@foxmail.com