STM32温湿度测量与显示-单总线协议学习
本文最后更新于:2023年5月25日 凌晨
STM32温湿度测量与显示-单总线协议学习
为了验收个小玩意用一晚上搓了一个,比较氵。 那就氵篇博客算了。
手头正好有个ST的板子,型号是STM32G431KBT6,主频170M。刚好拿过来用了。(真好用啊,就是做这个有点浪费。
温湿度传感器使用 DHT11 (单总线协议),屏幕是个IIC的小OLED,还用到了串口来看数据是否正确。(没了,确实氵。
效果图:
准备
首先去官网下载 STM32G4xx 的包。(Keil.STM32G4xx_DFP.1.5.0.pack)。官网直连下载很慢,很慢……
然后去CubeMX里面新建工程,因为是官方的板子,所以可以直接选择这块板子的模板创建。时钟设置170M(默认的)。选择一个没有中文的路径生成工程。
接下来的流程是:
- 设置串口
- 驱动OLED屏幕
- 重新配置延时函数
- 添加软件IIC
- 添加OLED驱动
- 驱动DHT11温湿度传感器(单总线协议的学习)
因为使用的OLED驱动比较特殊,添加之后无法使用原来的 HAL_Dealy()
函数,需要按照该驱动的要求重新配置延时函数,之后使用其提供的 delay_ms()
和 delay_us()
两个函数代替 HAL_Dealy()
函数,当然实际上是方便不少的,因为 HAL_Dealy()
是毫秒级延时,所以直接使用上面两个函数可以让自己少写一个微秒的延时函数,具体原理可以参考之前的一篇博客。
具体实现
串口设置
串口的具体实现参考我之前的博客步骤:STM32&UART串口通信(使用CubeMX) 。因为这次没有用到收的功能,所以只需要设置好发送功能即可。
本次使用USART1。其实 更推荐 使用USART2的,因为官方的板子上本身就有串口芯片,使用的USART2,这样用一根USB线连电脑上就可以同时供电,下载和查看串口数据了,不用自己再连一个USB转串口的模块了,还能腾出来两个引脚,这STM32G431KBT6的引脚是真的少。 (还是官方板子好用,就是贵
)晚上要去重庆,剩下的具体流程就等下周回来再写了。
回来了,发现实习二面寄了,悲)
驱动OLED屏幕
这一节可以略过。
本次的驱动选自 LCD wiki 。
因为 LCD wiki 的驱动为gb2312编码,为了以后写的舒服,我先转换为了utf-8,具体可以参考:
批量转换文件编码gb2312转utf-8 。但是注意,代码里有中文的地方,比如 test.c
,oledfont.h
等文件需要保持原来的gb2312。(看见编译时候的编码报错真是心累呐
LCD wiki 的驱动使用标准库编写,放入HAL库的项目中会狠狠报错,所以要进行修改)我自己修改了一下,以后写一下修改过程emmm(咕咕
重新配置延时函数
添加 sys.h
, sys.c
, delay.h
, delay.c
,注意修改里面包含的头文件为对应的 #include "stm32g4xx.h"
之后在 main.c
里面进行初始化: delay_init();
初始化完成后以后的延时就用 delay_ms()
和 delay_us()
。
添加软件IIC
添加 iic.c
, iic.h
,注意修改里面 SCL
与 SDA
的引脚。本次分别使用 PA1
, PA0
。
添加OLED驱动
添加 bmp.h
, gui.h
, gui.c
, oled.c
, oled.h
, oledfont.h
, test.c
, test.h
。
这次所用的汉字取模保存至 oledfont.h
内,注意为gb2312编码。
取模使用 PCtoLCD2002
,为逐行式,顺向。考虑到屏幕大小,取模的大小为16×16。添加在 const typFNT_GB16 cfont16[]
的后面。如:
显示汉字使用 GUI_ShowCHinese(uint8_t x,uint8_t y,uint8_t hsize,uint8_t *str,uint8_t mode)
,使用实例如 GUI_ShowCHinese(40,2,16,"康师傅",1);
该函数说明:
显示其他内容可以 结合test.c
中的实例与 gui.c
里的函数说明学习。
为了分开gb2312与utf-8,我将显示中文的地方全部写在了一个文件里,我在 main.c
用到的时候直接调用。
驱动DHT11温湿度传感器(单总线协议的学习)
)当时大二赶广和通项目的时候用的是 DS18B20
来着,是个单总线协议的温度传感器,网上找了段代码糊了一个,这次用 DHT11
学习学习单总线协议。
DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC
测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够
实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一
个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式
进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大
电流 0.5mA。DHT11 的技术参数:工作电压范围:3.3V-5.5V;工作电流 :平均 0.5mA;输出:单总线数字信号;测量范围:湿度 2090%RH,温度 050℃;精度 :湿度±5%,温度±2℃;分辨率 :湿度 1%,温度 1℃;
DHT11 数据传输格式
DHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由 40Bit 组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。
DHT11 的数据格式为:8bit 湿度整数数据 + 8bit 湿度小数数据 + 8bit 温度整数数据 + 8bit 温度小数数据 + 8bit 校验和。其中校验和数据为前四个字节相加。
传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。例如,某次从 DHT11 读到的数据如下表所示:
byte4 | byte3 | byte2 | byte1 | byte0 |
---|---|---|---|---|
0010 1101 | 0000 0000 | 0001 1100 | 0000 0000 | 0100 1001 |
湿度 整数 部分 | 湿度 小数 部分 | 温度 整数 部分 | 温度 小数 部分 | 校验和 |
由以上数据就可得到湿度和温度的值,计算方法:
湿度= byte4 . byte3=45.0 (%RH)
温度= byte2 . byte1=28.0 ( ℃)
校验= byte4+ byte3+ byte2+ byte1=73(=湿度+温度)(校验正确)
DHT11 的数据格式是十分简单,DHT11 和 MCU 的一次通信最大为 3ms 左右,建议主机连续读取时间间隔不要小于 100ms。 下面,我们介绍一下 DHT11 的传输时序。
提前准备
本次使用数据传输脚:
设置数据传输脚为输出:
设置数据传输脚为输入:
DHT11 的数据发送流程
DHT11 的数据发送流程如下图所示:
开始信号
首先主机发送 开始信号,即:拉低数据线,保持 t1(至少 18ms)时间,然后 拉高数据线 t2(20~ 40us)时间,然后读取 DHT11 的响应。
复位DHT11 :
响应信号
DHT11的 响应 :正常的话,DHT11 会 拉低 数据线,保持 t3(40~50us)时间,作为响应信号,然后 DHT11 拉高 数据线,保持 t4(40 ~50us)时间后,开始输出数据。
检测DHT11的回应
DHT11 发送数据
总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据。
每一bit数据都以50us低电平时隙 开始 ,高电平的长短 定了数据位是0还是1。
如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常。当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
DHT11 发送 0
高电平是26-28us就表示0。
DHT11 发送1
高电平是70us表示1。
接收数据
主机只要读取等待50us低电平过去,然后再判断高电平长短就能收集数据了。
从DHT11读取一个位:
读取8次为一个字节:
一共5个字节:
)不过为了显示的更精确可以小数位也传过去。
完成
到此,完成了串口通信,OLED屏幕驱动,温湿度数据的获取。之后在OLED屏幕上的显示布局可以自己设计~