马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
第三十一章 DS18B20实验
本章,我们将先容ESP32-P4怎样读取外部温度传感器的温度,来得到较为正确的情况温度。我们将学习单总线技能,通过它来实现ESP32-P4和外部温度传感器DS18B20的通讯,并把从温度传感器得到的温度表如今LCD上。
本章分为如下几个末节:
31.1 DS18B20先容
31.2 硬件计划
31.3 步伐计划
31.4 下载验证
31.1 DS18B20先容
31.1.1 DS18B20简介
DS18B20是由DALLAS半导体公司推出的一种“单总线”接口的温度传感器,实物图如下图所示。
图31.1.1.1 DS18B20实物图
与传统的热敏电阻等测温元件相比,它是一种新型的体积小、实用电压宽、与微处置惩罚器接口简朴的数字化温度传感器。单总线结构具有轻巧且经济的特点,可使用户轻松地组建传感器网络,从而为丈量体系的构建引入全新的概念,测试温度范围为-55+125℃,精度为±0.5℃。现场温度直接以单总线的数字方式传输,大大进步了体系的抗干扰性。它能直接读出被测温度,而且可根据实际要求通过简朴的编程实现912位的数字值读数方式。它工作在3~5.5V的电压范围,采取多种封装情势,从而使体系设置机动、方便,设定分辨率以及用户设定的报警温度存储在EEPROM中,掉电后依然生存。其内部结构如下图所示。
图31.1.1.2 DS18B20内部结构图
ROM中的64位序列号是出厂前被标志好的,它可以看作使该DS18B20的地点序列码,每个DS18B20的64位序列号均不雷同。64位ROM的分列是:前8位是产物家属码,接着48位是DS18B20的序列号,末了8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。ROM作用是使每一个DS18B20都各不雷同,如许计划可以允许一根总线上挂载多个DS18B20模块同时工作且不会引起辩说。
31.1.2 DS18B20时序先容
全部单总线器件要求采取严酷的信号时序,以包管数据的完备性。DS18B20共有6种信号范例:复位脉冲、应答脉冲、写0、写1、读0和读1。全部这些信号,除了应答脉冲以外,都是由主机发出同步信号。而且发送全部的下令和数据都是字节的低位在前。这里我们简朴先容这几个信号的时序。
1,复位脉冲和应答脉冲
图31.1.2.1 复位脉冲和应答脉冲时序图
单总线上的全部通讯都是以初始化序列开始。主机输出低电平,保持低电平常间至少要在480us,以产生复位脉冲。接着主机开释总线,4.7K的上拉电阻将单总线拉高,延时时间要在1560us,并进入吸收模式(Rx)。接着DS18B20拉低总线60240us,以产生低电平应答脉冲。
2,写时序
图31.1.2.2 写时序图
写时序包罗写0时序和写1时序。全部写时序至少须要60us,且在两次独立的写时序之间至少须要1us的规复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us,然后开释总线,延时60us。写0时序:主机输出低电平,延时60us,然后开释总线延时2us。
3,读时序
图31.1.2.3 读时序图
单总线器件仅在主机发出读时序时,才向主机传输数据,以是,在主机发出读数据下令后,必须立即产生读时序,以便从性可以大概传输数据。全部读时序至少须要60us,且在2次独立的读时序之间至少须要1us的规复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须开释总线,而且在时序起始后的15us之内采样总线状态。范例的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。
在相识单总线时序之后,我们来看一下DS18B20的范例温度读取过程,DS18B20的范例温度读取过程为:复位→发SKIP ROM(0xCC)→发开始转换下令(0x44)→延时→复位→发送SKIP ROM下令(0xCC)→发送存储器下令(0xBE)→连续读取两个字节数据(即温度)→竣事。
DS18B20的简介,我们就先容到这里,关于该传感器的具体分析,请各人参考其数据手册。
31.2 硬件计划
31.2.1 例程功能
DS18B20每隔100ms左右读取一次数据,并把温度表如今LCD上。LED0闪耀用于提示步伐正在运行。
31.2.2 硬件资源
1)LED灯
LED 0 - IO51
2)RGBLCD / MIPILCD(引脚太多,不摆列出来)
3)DS18B20
1WIRE_DQ - IO23
31.2.3 原理图
DS18B20器件干系原理图,如下图所示。
图31.2.3.1 DS18B20原理图
从上图可以看出,使用的是IO23来毗连U4的DQ引脚,图中U10为DHT11(数字温湿度传感器)和DS18B20共用的一个接口,DHT11将在下一章先容。
DS18B20只用到U4的3个引脚(U4的1、2和3脚),将DS18B20传感器插入到这个上面就可以通过ESP32-P4来读取DS18B20的温度了。毗连表示图如下所示。
图31.2.3.2 DS18B20与开辟板毗连图
从上图可以看出,DS18B20的平面部门(有字的那面)应该朝内,而曲面部门朝外。
31.3 步伐计划
本例程重要用到的是GPIO函数,GPIO函数已在11.3.1章节中具体叙述,为克制重复,此处不再赘述。发起读者查阅第十一章的函数分析章节,以获取更多关于GPIO函数的信息。
31.3.1 步伐流程图
图31.3.1.1 DS18B20实验步伐流程图
31.3.2 步伐分析
在22_ds18b20例程中,作者在22_ds18b20\components\BSP路径下新建在¥在¥在¥了1个文件夹DS18B20,而且须要更改CMakeLists.txt内容,以便在其他文件上调用。
1. DS18B20驱动代码
这里我们只讲授核心代码,具体的源码请各人参考光盘本实验对应源码。DS18B20驱动源码包罗两个文件:ds18b20.c和ds18b20.h。
下面先分析ds18b20.h的步伐。对DS18B20的数据引脚做了干系界说。- #define DS18B20_DQ_GPIO_PIN GPIO_NUM_23
复制代码 由于数据线会存在获取高低电平以及设置高低电平,以是为DS18B20_DQ_GPIO_PIN 做了干系宏函数供单总线时序函数调用。- #define DS18B20_DQ_IN gpio_get_level(DS18B20_DQ_GPIO_PIN) /* IO操作 */
- #define DS18B20_DQ_OUT(x) do { x ? \
- gpio_set_level(DS18B20_DQ_GPIO_PIN, 1): \
- gpio_set_level(DS18B20_DQ_GPIO_PIN, 0); \
- } while(0) /* DS18B20端口定义 */
复制代码 接下来,分析一下ds18b20.c的步伐,起首来看一下DS18B20的初始化函数ds18b20_init,代码如下:- /**
- * @brief 初始化DS18B20
- * @param 无
- * @retval 0, 正常; 1, 不存在/不正常
- */
- uint8_t ds18b20_init(void)
- {
- gpio_config_t gpio_init_struct;
- gpio_init_struct.intr_type = GPIO_INTR_DISABLE; /* 失能引脚中断 */
- gpio_init_struct.mode = GPIO_MODE_INPUT_OUTPUT_OD; /* 开漏的输入和输出 */
- gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE; /* 使能上拉 */
- gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE; /* 失能下拉 */
- gpio_init_struct.pin_bit_mask = 1ull << DS18B20_DQ_GPIO_PIN; /* 设置位掩码 */
- gpio_config(&gpio_init_struct); /* 配置DS18B20引脚 */
- ds18b20_reset(); /* 复位DS18B20 */
- return ds18b20_check(); /* 等待DS18B20回应 */
- }
复制代码 以上两个函数分别代表着前面所说的复位脉冲与应答信号,各人可以对比前面的时序图举行明白。由于复位脉冲比力简朴,以是这里不做睁开。如今看一下应答信号函数,函数重要是对于DS18B20传感器的回应信号举行检测,对此判定其是否存在。函数的实现也是依据时序图举行逻辑判定,比方当主机发送了复位信号之后,按照时序,DS18B20会拉低数据线60~240us,同时主机吸收最小时间为480us,我们就依据这两个硬性条件举行判定,起首须要设置一个时限期待DS18B20相应,背面也设置一个时限期待DS18B20开释数据线拉高,满意这两个条件即DS18B20乐成相应。
下面先容的是写函数,其界说如下:- /**
- * @brief 复位DS18B20
- * @param 无
- * @retval 无
- */
- void ds18b20_reset(void)
- {
- DS18B20_DQ_OUT(0); /* 拉低DQ,复位 */
- esp_rom_delay_us(750); /* 拉低至少750μs */
- DS18B20_DQ_OUT(1); /* DQ=1,释放复位 */
- esp_rom_delay_us(15); /* 主机拉高10~35us */
- }
- /**
- * @brief 等待DS18B20的回应
- * @param 无
- * @retval 0, DS18B20正常; 1, DS18B20异常/不存在
- */
- uint8_t ds18b20_check(void)
- {
- uint8_t retry = 0;
- uint8_t rval = 0;
- while (DS18B20_DQ_IN && retry < 200) /* DS18B20会拉低200us */
- {
- retry++;
- esp_rom_delay_us(1);
- }
- if (retry >= 200)
- {
- rval = 1;
- }
- else
- {
- retry = 0;
- while (!DS18B20_DQ_IN && retry < 240) /* DS18B20拉低后会再次拉高240us */
- {
- retry++;
- esp_rom_delay_us(1);
- }
- if (retry >= 240)
- {
- rval = 1;
- }
- }
-
- return rval;
- }
复制代码 通过形参决定是写1还是写0,按照前面临写时序的分析,我们可以很清晰知道写函数的逻辑处置惩罚。
有写函数肯定就有读函数,下面看一下读函数:
[code]/** * @brief 从DS18B20读取一个位 * @param 无 * @retval 读取到的位值: 0 / 1 */uint8_t ds18b20_read_bit(void){ uint8_t data = 0; DS18B20_DQ_OUT(0); esp_rom_delay_us(2); DS18B20_DQ_OUT(1); esp_rom_delay_us(12); if (DS18B20_DQ_IN) { data = 1; } esp_rom_delay_us(50); return data;}/** * @brief 从DS18B20读取一个字节 * @param 无 * @retval 读到的数据 */uint8_t ds18b20_read_byte(void){ uint8_t i, b, data = 0; for (i = 0; i < 8; i++) /* 循环读取8位数据 */ { b = ds18b20_read_bit(); /* DS18B20先输出低位数据,高位数据后输出 */ data |= b 7) { /* 温度为负,查察DS18B20的温度表现法与盘算机存储正负数据的原理同等: 正数补码为寄存器存储的数据自身,负数补码为寄存器存储值按位取反后+1 以是我们直接取它实际的负数部门,但负数的补码为取反后加一,但思量到 低位大概+1后有进位和代码冗余,我们这里先暂时没有作+1的处置惩罚,这里须要注意 */ TH = ~TH; TL = ~TL; flag = 0; /* 温度为负 */ } temp = TH; /* 得到高八位 */ temp |