前言
涵盖之前文章:
- Clion开发STM32之HAL库GPIO宏定义封装(最新版)
- Clion开发stm32之微妙延迟(采用nop指令实现)
- Clion开发STM32之日志模块(参考RT-Thread)
DSP18B20驱动文件
头文件
#ifndef F1XX_TEMPLATE_MODULE_DS18B20_H
#define F1XX_TEMPLATE_MODULE_DS18B20_H
#include "sys_core.h"
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
源文件
#include "ds18b20/module-ds18b20.h"
#define DBG_ENABLE
#define DBG_SECTION_NAME "ds18b20"
#define DBG_LEVEL DBG_LOG
#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;
conf_ptr->us_delay(750);
DS18B20_DQ_1;
conf_ptr->us_delay(15);
}
bool DS18B20_Driver_Init(void) {
if (conf_ptr == NULL) return false;
conf_ptr->out_mode_set();
DS18B20_DQ_1;
DS18B20_Rst();
return DS18B20_Presence();
}
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();
}
float DS18B20_GetTemp_SkipRom(void) {
uint8_t tpmsb = 0, tplsb = 0;
short s_tem = 0;
float f_tem = 0;
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0XCC);
DS18B20_WriteByte(0X44);
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0XCC);
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;
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0X55);
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0X55);
for (i = 0; i < 8; i++)
DS18B20_WriteByte(ds18b20_id[i]);
DS18B20_WriteByte(0X44);
DS18B20_Rst();
DS18B20_Presence();
DS18B20_WriteByte(0X55);
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;
if (testb) {
DS18B20_DQ_0;
conf_ptr->us_delay(8);
DS18B20_DQ_1;
conf_ptr->us_delay(58);
} else {
DS18B20_DQ_0;
conf_ptr->us_delay(70);
DS18B20_DQ_1;
conf_ptr->us_delay(2);
}
}
}
static uint8_t DS18B20_ReadBit(void) {
uint8_t dat;
conf_ptr->out_mode_set();
DS18B20_DQ_0;
conf_ptr->us_delay(10);
conf_ptr->input_mode_set();
if (conf_ptr->read_data() == 1)
dat = 1;
else
dat = 0;
conf_ptr->us_delay(45);
return dat;
}
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();
while (conf_ptr->read_data() && pulse_time < 100) {
pulse_time++;
conf_ptr->us_delay(1);
}
if (pulse_time >= 100)
return 1;
else
pulse_time = 0;
while (!conf_ptr->read_data() && pulse_time < 240) {
pulse_time++;
conf_ptr->us_delay(1);
}
if (pulse_time >= 240)
return false;
else
return true;
}
测试配置
#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
#include "sys_dbg.h"
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); }
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);
static void DS18B20_init() {
while (!DS18B20_Driver_Init()) {
};
LOG_D("DS18B20_Driver_Init ok");
}
sys_init_export(DS18B20, DS18B20_init);
static void DS18B20_after_init() {
uint8_t uc, ucDs18b20Id[8];
DS18B20_readId(ucDs18b20Id);
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);
#endif
结果