简介:STM32F103C8T6驱动DS18B20温度传感器源码介绍。
开发平台:KEIL ARM
MCU型号:STM32F103C8T6
传感器型号:DS18B20
特别提示:驱动内可能使用了某些其他组件,比如delay等,在文末外设模板下载地址内有。
1积分源码下载地址在文末!!!
接口图:
使用举例:
#include <stdio.h>
#include "DS18B20.h"
int main()
{
float tem;
DS18B20.Init(); // 初始化
while(1) {
tem = DS18B20.GetTemp_SkipRom(); // 获取温湿度
printf("tem:%f\n", tem);
delayMs(1000);
}
}
驱动源码:
DS18B20.c
/* include ---------------------------------------------------------*/
#include "main.h"
/* private define -------------------------------------------------*/
#define DS18B20_DQ_SCK_APBxClock_FUN RCC_APB2PeriphClockCmd
#define DS18B20_DQ_GPIO_CLK RCC_APB2Periph_GPIOA
#define DS18B20_DQ_GPIO_PORT GPIOA
#define DS18B20_DQ_GPIO_PIN GPIO_Pin_7
#define DS18B20_DQ_0 GPIO_ResetBits(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN )
#define DS18B20_DQ_1 GPIO_SetBits(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN )
#define DS18B20_DQ_IN() GPIO_ReadInputDataBit( DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN)
/* private variables ----------------------------------------------*/
/* private function prototypes ------------------------------------*/
static void DS18B20_Mode_IPU(void);
static void DS18B20_Mode_Out_PP(void);
static void DS18B20_Rst(void);
static uint8_t DS18B20_Presence(void);
static uint8_t DS18B20_ReadBit(void);
static uint8_t DS18B20_ReadByte(void);
static void DS18B20_WriteByte(uint8_t dat);
static void DS18B20_SkipRom(void);
static void DS18B20_MatchRom(void);
static uint8_t Init(void);
static void ReadId(uint8_t * ds18b20_id);
static float GetTemp_SkipRom(void);
static float GetTemp_MatchRom( uint8_t * ds18b20_id );
/* public variables -----------------------------------------------*/
DS18B20_t DS18B20 =
{
Init,
ReadId,
GetTemp_SkipRom,
GetTemp_MatchRom
};
/**
* @brief 初始化
* @param None
* @retval None
* @note None
*/
static uint8_t Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DS18B20_DQ_SCK_APBxClock_FUN ( DS18B20_DQ_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init ( DS18B20_DQ_GPIO_PORT , &GPIO_InitStructure );
DS18B20_DQ_1;
DS18B20_Rst();
return DS18B20_Presence ();
}
/**
* @brief 使DS18B20-DATA引脚变为输入模式
* @param None
* @retval None
* @note None
*/
static void DS18B20_Mode_IPU(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief 使DS18B20-DATA引脚变为输出模式
* @param None
* @retval None
* @note None
*/
static void DS18B20_Mode_Out_PP(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief 主机给从机发送复位脉冲
* @param None
* @retval None
* @note None
*/
static void DS18B20_Rst(void)
{
/* 主机设置为推挽输出 */
DS18B20_Mode_Out_PP();
DS18B20_DQ_0;
/* 主机至少产生480us的低电平复位信号 */
DelayClass.DelayUs(750);
/* 主机在产生复位信号后,需将总线拉高 */
DS18B20_DQ_1;
/*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/
DelayClass.DelayUs(15);
}
/**
* @brief 检测从机给主机返回的存在脉冲
* @param None
* @retval 0 成功 1 失败
* @note None
*/
static uint8_t DS18B20_Presence(void)
{
uint8_t pulse_time = 0;
/* 主机设置为上拉输入 */
DS18B20_Mode_IPU();
/* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
* 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
*/
while( DS18B20_DQ_IN() && pulse_time<100 )
{
pulse_time++;
DelayClass.DelayUs(1);
}
/* 经过100us后,存在脉冲都还没有到来*/
if( pulse_time >=100 )
return 1;
else
pulse_time = 0;
/* 存在脉冲到来,且存在的时间不能超过240us */
while( !DS18B20_DQ_IN() && pulse_time<240 )
{
pulse_time++;
DelayClass.DelayUs(1);
}
if( pulse_time >=240 )
return 1;
else
return 0;
}
/**
* @brief 从DS18B20读取一个bit
* @param None
* @retval None
* @note None
*/
static uint8_t DS18B20_ReadBit(void)
{
uint8_t dat;
/* 读0和读1的时间至少要大于60us */
DS18B20_Mode_Out_PP();
/* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
DS18B20_DQ_0;
DelayClass.DelayUs(10);
/* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
DS18B20_Mode_IPU();
if( DS18B20_DQ_IN() == SET )
{
dat = 1;
}
else
{
dat = 0;
}
/* 这个延时参数请参考时序图 */
DelayClass.DelayUs(45);
return dat;
}
/**
* @brief 从DS18B20读一个字节,低位先行
* @param None
* @retval None
* @note None
*/
static uint8_t DS18B20_ReadByte(void)
{
uint8_t i, j, dat = 0;
for(i=0; i<8; i++)
{
j = DS18B20_ReadBit();
dat = (dat) | (j<<i);
}
return dat;
}
/**
* @brief 写一个字节到DS18B20,低位先行
* @param None
* @retval None
* @note None
*/
static void DS18B20_WriteByte(uint8_t dat)
{
uint8_t i, testb;
DS18B20_Mode_Out_PP();
for( i=0; i<8; i++ )
{
testb = dat&0x01;
dat = dat>>1;
/* 写0和写1的时间至少要大于60us */
if (testb)
{
DS18B20_DQ_0;
/* 1us < 这个延时 < 15us */
DelayClass.DelayUs(8);
DS18B20_DQ_1;
DelayClass.DelayUs(58);
}
else
{
DS18B20_DQ_0;
/* 60us < Tx 0 < 120us */
DelayClass.DelayUs(70);
DS18B20_DQ_1;
/* 1us < Trec(恢复时间) < 无穷大*/
DelayClass.DelayUs(2);
}
}
}
/**
* @brief 跳过匹配 DS18B20 ROM
* @param None
* @retval None
* @note None
*/
static void DS18B20_SkipRom(void)
{
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0XCC);/* 跳过 ROM */
}
/**
* @brief 执行匹配 DS18B20 ROM
* @param None
* @retval None
* @note None
*/
static void DS18B20_MatchRom(void)
{
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0X55); /* 匹配 ROM */
}
/**
* @brief 在跳过匹配 ROM 情况下获取 DS18B20 温度值
* @param None
* @retval None
* @note None
*/
static float GetTemp_SkipRom(void)
{
uint8_t tpmsb, tplsb;
short s_tem;
float f_tem;
DS18B20_SkipRom ();
DS18B20_WriteByte(0X44); /* 开始转换 */
DS18B20_SkipRom ();
DS18B20_WriteByte(0XBE); /* 读温度值 */
tplsb = DS18B20_ReadByte();
tpmsb = DS18B20_ReadByte();
s_tem = tpmsb<<8;
s_tem = s_tem | tplsb;
if( s_tem < 0 ) /* 负温度 */
{
f_tem = (~s_tem+1) * 0.0625;
}
else
{
f_tem = s_tem * 0.0625;
}
return f_tem;
}
/**
* @brief 在匹配 ROM 情况下获取 DS18B20 ID
* @param ds18b20_id 用于存放 DS18B20 序列号的数组的首地址
* @retval None
* @note None
*/
static void ReadId(uint8_t * ds18b20_id)
{
uint8_t uc;
DS18B20_WriteByte(0x33); //读取序列号
for ( uc = 0; uc < 8; uc ++ )
{
ds18b20_id [ uc ] = DS18B20_ReadByte();
}
}
/**
* @brief 在匹配 ROM 情况下获取 DS18B20 温度值
* @param ds18b20_id 存放 DS18B20 序列号的数组的首地址
* @retval None
* @note None
*/
static float GetTemp_MatchRom( uint8_t * ds18b20_id )
{
uint8_t tpmsb, tplsb, i;
short s_tem;
float f_tem;
DS18B20_MatchRom (); //匹配ROM
for(i=0;i<8;i++)
{
DS18B20_WriteByte ( ds18b20_id [i]);
}
DS18B20_WriteByte(0X44); /* 开始转换 */
DS18B20_MatchRom (); //匹配ROM
for(i=0;i<8;i++)
{
DS18B20_WriteByte (ds18b20_id [i]);
}
DS18B20_WriteByte(0XBE); /* 读温度值 */
tplsb = DS18B20_ReadByte();
tpmsb = DS18B20_ReadByte();
s_tem = tpmsb<<8;
s_tem = s_tem | tplsb;
if( s_tem < 0 ) /* 负温度 */
{
f_tem = (~s_tem+1) * 0.0625;
}
else
{
f_tem = s_tem * 0.0625;
}
return f_tem;
}
DS18B20.h
#ifndef __Ds18b20_H_
#define __Ds18b20_H_
#include "main.h"
typedef struct
{
uint8_t (*Init)(void);
void (*ReadID)(uint8_t*);
float (*GetTemp_SkipRom)(void);
float (*GetTemp_MatchRom)(uint8_t*);
}DS18B20_t;
extern DS18B20_t DS18B20;
#endif
驱动下载地址:
https://download.csdn.net/download/m0_50669075/87672770
STM32工程模板、外设模板、模块模板下载地址: