前言
涵盖之前文章:
- Clion开发STM32之HAL库GPIO宏定义封装(最新版)
- Clion开发stm32之微妙延迟(采用nop指令实现)
- Clion开发STM32之日志模块(参考RT-Thread)
DSP18B20驱动文件
头文件
/*******************************************************************************
Copyright (c) [scl]。保留所有权利。
* 存储的温度是16 位的带符号扩展的二进制补码形式
* 当工作在12位分辨率时,其中5个符号位,7个整数位,4个小数位
* |---------整数----------|-----小数 分辨率 1/(2^4)=0.0625----|
* 低字节 | 2^3 | 2^2 | 2^1 | 2^0 | 2^(-1) | 2^(-2) | 2^(-3) | 2^(-4) |
* |-----符号位:0->正 1->负-------|-----------整数-----------|
* 高字节 | s | s | s | s | s | 2^6 | 2^5 | 2^4 |
* 温度 = 符号位 + 整数 + 小数*0.0625
******************************************************************************/
#ifndef F1XX_TEMPLATE_MODULE_DS18B20_H
#define F1XX_TEMPLATE_MODULE_DS18B20_H
#include "sys_core.h"
/**
* @memberof input_mode_set 输入模式配置
* @memberof out_mode_set 输出模式配置
* @memberof send_data 发送数据
* @memberof us_delay 微秒延迟
*/
typedef struct {
void (*input_mode_set)(void);
void (*out_mode_set)(void);
void (*send_data)(uint32_t status);
uint32_t (*read_data)(void);
void (*us_delay)(uint32_t us);
} DS18B20_conf_t;
void DS18B20_conf_set(DS18B20_conf_t *cnf);
bool DS18B20_Driver_Init(void);
void DS18B20_readId(uint8_t *ds18b20_id);
float DS18B20_GetTemp_SkipRom(void);
float DS18B20_GetTemp_MatchRom(const uint8_t *ds18b20_id);
#endif //F1XX_TEMPLATE_MODULE_DS18B20_H
源文件
/*******************************************************************************
Copyright (c) [scl]。保留所有权利。
******************************************************************************/
#include "ds18b20/module-ds18b20.h"
#define DBG_ENABLE
#define DBG_SECTION_NAME "ds18b20"
#define DBG_LEVEL DBG_LOG // DBG_LOG DBG_INFO DBG_WARNING DBG_ERROR
#include "sys_dbg.h"
static DS18B20_conf_t *conf_ptr = NULL;
#define DS18B20_DQ_0 conf_ptr->send_data(0)
#define DS18B20_DQ_1 conf_ptr->send_data(1)
static void DS18B20_WriteByte(uint8_t dat);
static uint8_t DS18B20_ReadByte(void);
static bool DS18B20_Presence(void);
void DS18B20_conf_set(DS18B20_conf_t *cnf) {
conf_ptr = cnf;
}
static void DS18B20_Rst(void) {
conf_ptr->out_mode_set();
DS18B20_DQ_0;
/* 主机至少产生480us的低电平复位信号 */
conf_ptr->us_delay(750);
/* 主机在产生复位信号后,需将总线拉高 */
DS18B20_DQ_1;
/*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/
conf_ptr->us_delay(15);
}
/**
* 驱动初始化
* @return
*/
bool DS18B20_Driver_Init(void) {
if (conf_ptr == NULL) return false;
conf_ptr->out_mode_set();
DS18B20_DQ_1;
DS18B20_Rst();
return DS18B20_Presence();
}
/**
* @brief 在匹配 ROM 情况下获取 DS18B20 温度值
* @param ds18b20_id :用于存放 DS18B20 序列号的数组的首地址
*/
void DS18B20_readId(uint8_t *ds18b20_id) {
if (conf_ptr == NULL) return;
uint8_t uc;
DS18B20_WriteByte(0x33); //读取序列号
for (uc = 0; uc < 8; uc++)
ds18b20_id[uc] = DS18B20_ReadByte();
}
/**
*
*
* @brief 在跳过匹配 ROM 情况下获取 DS18B20 温度值
* @return
*/
float DS18B20_GetTemp_SkipRom(void) {
uint8_t tpmsb = 0, tplsb = 0;
short s_tem = 0;
float f_tem = 0;
/* -------------跳过 ROM-START---------- */
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0XCC);
/* -------------跳过 ROM-END---------- */
DS18B20_WriteByte(0X44); /* 开始转换 */
/* -------------跳过 ROM-START---------- */
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0XCC); /* 跳过 ROM */
/* -------------跳过 ROM-END---------- */
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;
}
float DS18B20_GetTemp_MatchRom(const uint8_t *ds18b20_id) {
uint8_t tpmsb, tplsb, i;
short s_tem;
float f_tem;
/* -------------匹配 ROM-START---------- */
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0X55);
/* -------------匹配 ROM-END---------- */
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0X55); /* 匹配 ROM */
for (i = 0; i < 8; i++)
DS18B20_WriteByte(ds18b20_id[i]);
DS18B20_WriteByte(0X44); /* 开始转换 */
/* -------------匹配 ROM-START---------- */
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0X55);
/* -------------匹配 ROM-END---------- */
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;
}
static void DS18B20_WriteByte(uint8_t dat) {
uint8_t i, testb;
conf_ptr->out_mode_set();
for (i = 0; i < 8; i++) {
testb = dat & 0x01;
dat = dat >> 1;
/* 写0和写1的时间至少要大于60us */
if (testb) {
DS18B20_DQ_0;
/* 1us < 这个延时 < 15us */
conf_ptr->us_delay(8);
DS18B20_DQ_1;
conf_ptr->us_delay(58);
} else {
DS18B20_DQ_0;
/* 60us < Tx 0 < 120us */
conf_ptr->us_delay(70);
DS18B20_DQ_1;
/* 1us < Trec(恢复时间) < 无穷大*/
conf_ptr->us_delay(2);
}
}
}
/*
* 从DS18B20读取一个bit
*/
static uint8_t DS18B20_ReadBit(void) {
uint8_t dat;
/* 读0和读1的时间至少要大于60us */
conf_ptr->out_mode_set();
/* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
DS18B20_DQ_0;
conf_ptr->us_delay(10);
/* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
conf_ptr->input_mode_set();
//DHT11_DELAY_US(2);
if (conf_ptr->read_data() == 1)
dat = 1;
else
dat = 0;
/* 这个延时参数请参考时序图 */
conf_ptr->us_delay(45);
return dat;
}
/*
* 从DS18B20读一个字节,低位先行
*/
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;
}
static bool DS18B20_Presence(void) {
uint8_t pulse_time = 0;
/* 主机设置为上拉输入 */
conf_ptr->input_mode_set();
/* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
* 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
*/
while (conf_ptr->read_data() && pulse_time < 100) {
pulse_time++;
conf_ptr->us_delay(1);
}
/* 经过100us后,存在脉冲都还没有到来*/
if (pulse_time >= 100)
return 1;
else
pulse_time = 0;
/* 存在脉冲到来,且存在的时间不能超过240us */
while (!conf_ptr->read_data() && pulse_time < 240) {
pulse_time++;
conf_ptr->us_delay(1);
}
if (pulse_time >= 240)
return false;
else
return true;
}
测试配置
/*******************************************************************************
Copyright (c) [scl]。保留所有权利。
******************************************************************************/
#include "app_conf.h"
#define APP_CONF_ENABLE_DS18B20 (1)
#if APP_CONF_ENABLE_DS18B20
#include "ds18b20/module-ds18b20.h"
#define DBG_ENABLE
#define DBG_SECTION_NAME "DS18B20"
#define DBG_LEVEL DBG_LOG // DBG_LOG DBG_INFO DBG_WARNING DBG_ERROR
#include "sys_dbg.h"
/*-********************************************DS18B20变量定义******************************************-*/
static DS18B20_conf_t ds18b20_conf;
static stm_pin_define_t *ds18b20_pin_ptr = NULL;
static void out_mode_set(void) { stm32_pin_define_mode_set(ds18b20_pin_ptr, pin_mode_output); }
static void input_mode_set(void) { stm32_pin_define_mode_set(ds18b20_pin_ptr, pin_mode_input); }
static void send_data(uint32_t status) { stm32_pin_define_set(ds18b20_pin_ptr, status); }
static uint32_t read_data(void) { return stm32_pin_define_read(ds18b20_pin_ptr); }
/*-********************************************DS18B20_pre_init******************************************-*/
static void DS18B20_pre_init() {
ds18b20_pin_ptr = stm_get_pin(PE6);
ds18b20_conf.us_delay = bsp_us_delay_nop;
ds18b20_conf.out_mode_set = out_mode_set;
ds18b20_conf.input_mode_set = input_mode_set;
ds18b20_conf.send_data = send_data;
ds18b20_conf.read_data = read_data;
DS18B20_conf_set(&ds18b20_conf);
}
sys_pre_init_export(DS18B20, DS18B20_pre_init);
/*-********************************************DS18B20_init******************************************-*/
static void DS18B20_init() {
while (!DS18B20_Driver_Init()) {
};
LOG_D("DS18B20_Driver_Init ok");
}
sys_init_export(DS18B20, DS18B20_init);
/*-***********************************************DS18B20_after_init***************************************-*/
static void DS18B20_after_init() {
uint8_t uc, ucDs18b20Id[8];
DS18B20_readId(ucDs18b20Id); // 读取 DS18B20 的序列号
os_ps("DS18B20_readId:");
for (int i = 0; i < 8; ++i) {
os_ps("%X", ucDs18b20Id[i]);
}
os_ps("\r\n");
while (true) {
float temp = DS18B20_GetTemp_MatchRom(ucDs18b20Id);
LOG_D("TEMP is %0.3f", temp);
HAL_Delay(1000);
}
}
sys_after_init_export(DS18B20, DS18B20_after_init);
/*-**************************************DS18B20内部使用************************************************-*/
#endif //APP_CONF_ENABLE_DS18B20
结果
文章来源地址https://www.toymoban.com/news/detail-611230.html
文章来源:https://www.toymoban.com/news/detail-611230.html
到了这里,关于Clion开发Stm32之温湿度传感器(DS18B20)驱动编写和测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!