00. 目录
文章目录
- 00. 目录
- 01. DS18B20简介
- 02. DS18B20引脚及电路
- 03. DS18B20内部结构框图
- 04. DS18B20内存映射
- 05. 硬件设计
- 06. 软件设计
- 07. 实验现象
- 08. 附录
01. DS18B20简介
DS18B20 是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高,多点组网的特点。
DS18B20 数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样。
主要根据应用场合的不同而改变其外观。封装后的 DS18B20 可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测
温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温
和控制领域。温度范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃;电压范围:3.0~5.5V;DS18B20 支持多点组网功能,多个
DS18B20 可以并联在唯一的三线上,实现组网多点测温。
DS18B20 不同封装外观实物如下图所示:
02. DS18B20引脚及电路
03. DS18B20内部结构框图
parasite power circuit:是寄生电路部分,也就是说DS18B20可以不用通过VDD来进行供电,通过DQ口接电源也可以进行供电。DQ为高电平时,会对电容CPP进行充电,DQ为低电平时,电容会进行供电。
64-BIT ROM:作为器件地址,用于总线通信的寻址
MEMORY CONTROL LOGIC: 存储控制逻辑,用于控制数据的传输
SCRATCHPAD(暂存器):用于总线的数据交互(RAM)
TEMPERATURE SENSOR:模拟温度传感器
ALARM HIGH TRIGGER REGISTER:报警高位触发寄存器,存储温度上限阈值
ALARM LOW TRIGGER REGISTER: 报警低位触发寄存器,存储温度下限阈值
CONFIGURATION REGISTER:配置寄存器,用于设置分辨率(精度)
EEPROM: 用于保存温度触发阈值和配置参数
8-BIT CRC GENERATOR: 8位CRC生成器(CRC,循环冗余码,一种校验码)
04. DS18B20内存映射
05. 硬件设计
由图可知,P1 端子的 DS18B20 脚为 DS18B20 温度传感器控制口,可将该引脚与芯片的 GPIO 连接。
06. 软件设计
bsp_ds18b20.h
#ifndef BSP_DS18B20_H
#define BSP_DS18B20_H#include "cmsis_os2.h"
#include "hi_io.h"
#include "hi_gpio.h"//管脚定义
#define DS18B20_PIN HI_IO_NAME_GPIO_7
#define DS18B20_GPIO_FUN HI_IO_FUNC_GPIO_7_GPIO#define DS18B20_DQ_OUT(a) hi_gpio_set_ouput_val(DS18B20_PIN,a)//函数声明
void ds18b20_io_out(void);
void ds18b20_io_in(void);
void ds18b20_reset(void);
uint8_t ds18b20_check(void);
uint8_t ds18b20_read_bit(void);
uint8_t ds18b20_read_byte(void);
void ds18b20_write_byte(uint8_t dat);
void ds18b20_start(void);
uint8_t ds18b20_init(void);
float ds18b20_gettemperture(void);#endif
bsp_ds18b20.c
#include "bsp_ds18b20.h"
#include <unistd.h>
#include "hi_time.h"//DS18B20输出配置
void ds18b20_io_out(void)
{hi_gpio_init(); // GPIO初始化hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_UP); // 设置GPIO上拉hi_io_set_func(DS18B20_PIN, DS18B20_GPIO_FUN); // 设置IO为GPIO功能hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式
}//DS18B20输入配置
void ds18b20_io_in(void)
{hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_NONE); // 设置GPIO浮空hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_IN); // 设置GPIO为输入模式
}/******************************************************* 函数名 :GPIO_GetInputValue* 功能 :获取GPIO输入状态* 输入 :id, *val* 输出 :0/1*******************************************************/
hi_gpio_value DS18B20_DQ_IN = {0};
uint8_t GPIO_GetInputValue(hi_gpio_idx id,hi_gpio_value *val)
{hi_gpio_get_input_val(id,val);return *val;
}//ds18b20复位
void ds18b20_reset(void)
{ hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式DS18B20_DQ_OUT(0); //拉低DQhi_udelay(750); //拉低750usDS18B20_DQ_OUT(1); //DQ=1 hi_udelay(15); //15US
}/*******************************************************************************
* 函 数 名 : ds18b20_check
* 函数功能 : 检测DS18B20是否存在
* 输 入 : 无
* 输 出 : 1:未检测到DS18B20的存在,0:存在
*******************************************************************************/
uint8_t ds18b20_check(void)
{ uint8_t retry=0;ds18b20_io_in(); while (GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN)&&retry<200){retry++;hi_udelay(1);};if(retry>=200)return 1;else retry=0;while ((!GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN))&&retry<240){retry++;hi_udelay(1);};if(retry>=240)return 1; return 0;
}/*******************************************************************************
* 函 数 名 : ds18b20_read_bit
* 函数功能 : 从DS18B20读取一个位
* 输 入 : 无
* 输 出 : 1/0
*******************************************************************************/
uint8_t ds18b20_read_bit(void) // read one bit
{uint8_t data;hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT);DS18B20_DQ_OUT(0); hi_udelay(2);DS18B20_DQ_OUT(1); ds18b20_io_in();hi_udelay(12);if(GPIO_GetInputValue(DS18B20_PIN,&DS18B20_DQ_IN))data=1;else data=0; hi_udelay(50); return data;
}/*******************************************************************************
* 函 数 名 : ds18b20_read_byte
* 函数功能 : 从DS18B20读取一个字节
* 输 入 : 无
* 输 出 : 一个字节数据
*******************************************************************************/
uint8_t ds18b20_read_byte(void) // read one byte
{ uint8_t i,j,dat;dat=0;for (i=0;i<8;i++) {j=ds18b20_read_bit();dat=(j<<7)|(dat>>1);} return dat;
}/*******************************************************************************
* 函 数 名 : ds18b20_write_byte
* 函数功能 : 写一个字节到DS18B20
* 输 入 : dat:要写入的字节
* 输 出 : 无
*******************************************************************************/
void ds18b20_write_byte(uint8_t dat)
{ uint8_t j;uint8_t testb;hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT);for (j=1;j<=8;j++) {testb=dat&0x01;dat=dat>>1;if (testb) {DS18B20_DQ_OUT(0);// Write 1hi_udelay(2); DS18B20_DQ_OUT(1);hi_udelay(60); }else {DS18B20_DQ_OUT(0);// Write 0hi_udelay(60); DS18B20_DQ_OUT(1);hi_udelay(2); }}
}/*******************************************************************************
* 函 数 名 : ds18b20_start
* 函数功能 : 开始温度转换
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void ds18b20_start(void)// ds1820 start convert
{ ds18b20_reset(); ds18b20_check(); ds18b20_write_byte(0xcc);// skip romds18b20_write_byte(0x44);// convert
} //DS18B20初始化
uint8_t ds18b20_init(void)
{hi_gpio_init(); // GPIO初始化hi_io_set_pull(DS18B20_PIN, HI_IO_PULL_UP); // 设置GPIO上拉hi_io_set_func(DS18B20_PIN, DS18B20_GPIO_FUN); // 设置IO为GPIO功能hi_gpio_set_dir(DS18B20_PIN, HI_GPIO_DIR_OUT); // 设置GPIO为输出模式ds18b20_reset();return ds18b20_check();
}/*******************************************************************************
* 函 数 名 : ds18b20_gettemperture
* 函数功能 : 从ds18b20得到温度值
* 输 入 : 无
* 输 出 : 温度数据
*******************************************************************************/
float ds18b20_gettemperture(void)
{uint16_t temp;uint8_t a,b;float value;ds18b20_start(); // ds1820 start convertds18b20_reset();ds18b20_check(); ds18b20_write_byte(0xcc);// skip romds18b20_write_byte(0xbe);// convert a=ds18b20_read_byte(); // LSB b=ds18b20_read_byte(); // MSB temp=b;temp=(temp<<8)+a;if((temp&0xf800)==0xf800){temp=(~temp)+1;value=temp*(-0.0625);}else{value=temp*0.0625; }return value;
}
template.c
#include <stdio.h>
#include <unistd.h>#include "ohos_init.h"
#include "cmsis_os2.h"#include "bsp_led.h"
#include "bsp_ds18b20.h"//LED任务
osThreadId_t LED_Task_ID; //led任务IDvoid LED_Task(void)
{led_init();//LED初始化while (1) {LED(1); usleep(200*1000); //200msLED(0);usleep(200*1000); //200ms}
}
//LED任务创建
void led_task_create(void)
{osThreadAttr_t taskOptions;taskOptions.name = "LEDTask"; // 任务的名字taskOptions.attr_bits = 0; // 属性位taskOptions.cb_mem = NULL; // 堆空间地址taskOptions.cb_size = 0; // 堆空间大小taskOptions.stack_mem = NULL; // 栈空间地址taskOptions.stack_size = 1024; // 栈空间大小 单位:字节taskOptions.priority = osPriorityNormal; // 任务的优先级LED_Task_ID = osThreadNew((osThreadFunc_t)LED_Task, NULL, &taskOptions); // 创建任务1if (LED_Task_ID != NULL){printf("ID = %d, Create LED_Task_ID is OK!\n", LED_Task_ID);}
}//控制任务
osThreadId_t DS18B20_Task_ID; //任务IDvoid DS18B20_Task(void)
{static uint8_t i=0;float temper;while(ds18b20_init()){printf("DS18B20检测失败,请插好!\r\n");usleep(500*1000); //500ms}printf("DS18B20检测成功!\r\n");while (1) {i++;if(i%50==0){temper=ds18b20_gettemperture();if(temper<0){printf("检测的温度为:-");}else{printf("检测的温度为: ");}printf("%.1f°C\r\n",temper);}usleep(10*1000); //10ms}
}
//任务创建
void ds18b20_task_create(void)
{osThreadAttr_t taskOptions;taskOptions.name = "ds18b20Task"; // 任务的名字taskOptions.attr_bits = 0; // 属性位taskOptions.cb_mem = NULL; // 堆空间地址taskOptions.cb_size = 0; // 堆空间大小taskOptions.stack_mem = NULL; // 栈空间地址taskOptions.stack_size = 1024; // 栈空间大小 单位:字节taskOptions.priority = osPriorityNormal1; // 任务的优先级DS18B20_Task_ID = osThreadNew((osThreadFunc_t)DS18B20_Task, NULL, &taskOptions); // 创建任务if (DS18B20_Task_ID != NULL){printf("ID = %d, Task Create OK!\n", DS18B20_Task_ID);}
}/*** @description: 初始化并创建任务* @param {*}* @return {*}*/
static void template_demo(void)
{printf("-Hi3861开发板--DS18B20温度传感器实验\r\n");led_task_create();ds18b20_task_create();//任务创建
}
SYS_RUN(template_demo);
07. 实验现象
下载程序前,按照如下接线
注意:DS18B20 温度传感器不要插反,否则电源短路,容易烧坏开发板。方
向参考下图:
实验现象:读取 DS18B20 温度数据,并在串口助手上显示。
08. 附录
参考:【51单片机系列】DS18B20温度传感器模块
参考:【51单片机】DS18B20