DHT11模块 温湿度模块
一次完成的数据传输伟40bit 高位先出 单片机一次接收到完整的数据是5个字节
数据格式
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验
单片机一次取5个字节 取第一个字节和第三个字节
取之前要校验
DHT11时序图

根据时序进行代码的编写
DHT11初始化(MCU的复位和DHT11响应)MCU:主机 DHT11:从机

首先 主机拉低18ms 然后再拉高总线(释放总线) 然后延迟20~40us 这样复位信号就发送完毕
(这里释放总线是因为 当释放总线的 会有上拉电阻 所以主机会拉高)
这样的话单片机就由输出变成输入
DHT11检测到MCU复位信号后,拉低总线80us表示响应 在拉高总线80us后开始传输数据

根据时序分析完成后 开始对应时序对程序的一种编写

根据主机MCU初始化 首先定义输出引脚 然后令输出引脚拉低 然后进行延迟至少18ms 然后再把输出引脚拉高 再20-30us范围内 在定义引脚配置输入 进入从机就是DHT11模块
检查从机低电平时间长度(蓝色程序代码)
蓝色程序的作用就是 检测从机低电平的响应时间
while中当 从机低电平时 取反 就为真 并判断cnt是否小于100us
符合条件就自加cnt
当cnt为81的时候 从机的会拉高电平 再取反就为假 那么就会跳出while循环 令cnt为0 这样就起到了 主机监听从机 拉低电平的时间了

这里蓝色程序的作用 是检测从机高电平的响应时间
就是把输入的引脚 为DHT11_READ 这样就能够检测从机的高电平时时间了
整体DHT11的初始化部分 (MCU的复位和DHT11响应)
初始化主要包括三部分 一 主机的复位 二 从机的低电平响应 三从机的高电平响应

这里第一块 是主机初始化 第二部分 返回cnt0 表示从机低电平初始化成功 当返回值为0 表示 DHT11初始化成功 返回1 表示不成功。
**初始化成功后怎么传输数据 **

由于DHT11模块的时序 从机接收数据时根据高电平持续时间长短来定义 是0,还是1 所以因为输入信号刚开始是低电平 所以刚开始检测低电平while(DHT11_READ) 然后再检测高电平 这样就到达了高电平的点 高电平到来 由于该模块是根据高电平持续时间长短来判断 1、0 的 所以可以根据延迟时间35us (因为26-28us是0 70us是1 根据这个条件设置一个中间值就可以判断返回值是1还是0)设置35us后根据当时的DHT11_READ信号进行判断 看看返回的值得什么。
那怎么读取模块得字节呢

这里是每个字节读取得情况
假如接收得1010 1100这个数据 (从高位到低位) 设置dat为0 然后mask为0x80 1000 0000 根据mask不等于0 右移一位 如果接收得第一个字节为1 就令dat与mask或 在赋值 如果接收的字节不是0 就令dat与取反后的mask相与 经过循环后就会发现得到接收的数据了 这里明确一点就是mask一位(0000 0001在右移 结果是 0000 0000 并不会循环移位)

这个函数就是读取字节的代码

这里设置数组 一个容器装载到容器中 这样单片机收到的5个字节就都装载到这个数组容器中 下边在进行校验。

首先判断这个模块是否是初始化成功 把读到的数据放入数组buf中 因为DHT11模块是5个字节一次 所以这里设置的循环为5次 然后对数据在进行校验 如果成功那就把对应的温湿度数据拿出来

补充下 因为DHT11模块用的是PA5引脚 这里设置该引脚 为输入输出 可以立即为对DHT11模块的写入和读取 并且这个模块应该有上拉电阻 可以把这个引脚设置成上拉模式
IIC通信协议
usart 是板间进行通信 比如和上位机
IIC是多用板内通信 比如EEPROM OLED进行通信


IIC的起始信号 是时钟总线SCL为高电平时SDA数据总线为低电平的时候为起始信号 当时钟总线为SCL为高电平时数据总线SDA为低电平的时为停止信号
ACK为什么应答位在低电平的时候是有效的 在高电平是无效的 这个跟上拉电阻有关

这里IIC的协议主要用来实现与OLED模块进行通信 只需要发送命令或者数据


把mask 1000 0000 与接收的数据进行相与然后接收到数据 8次循环后 还会有个ack应答模式
IIC通讯功能实现



三部分 起始位 一个字节 应答位
其中一个字节中包括从机id 和一个读写位

具体程序如下
包括OLED屏幕初始化 将时钟总线SCL SDA都拉高
定义IIC得起始状态和停止状态

这里就是iic得起始状态(起初都是拉高得 scl拉高 sda拉低) 为什么延迟4us是因为手册规定最小时间是0.6us所以这里设置得是4us

这里就是iic得停止状态 SCL 为高电平 然后当SDA拉高后就为停止状态

然后就是字节得写入 通过mask0x80与接收到得数据进行相与 判断SDA是高电平还是低电平从而判断接收到得数据是0or1 ack主要判断是0还是1 看应答位是否有效

还要对从机进行验证 看从机是否存在
OLED屏幕学习

从机地址 包括 前6位得id地址后最后一位的读写位 0写1是读
control byte控制位为000000
后一部分就是从机给主机传递应答位后 开始传输1btye控制字节
如果co位是0 那后边包括后边的数据字节 databyte

D/C为0表示下一个数据为命令 D/C为1 表示下一个数据是数据 数据存储在GDDRAM

这是单片机给oled发送数据
先是 iic初始化起始信号 然后i发送从机地址 0x40 就是Co为0 D/C为1 control byte为000000 所以是01000000 就是0x40 然后 当D/C为1的时候 下一位就是数据IIC_data 在发送停止就结束了

这里是单片机给oled发送命令 起始信号 确定从机地址 0x00 Co为0 D/C为0 表示下一个数据发送的是命令
OLED屏幕显示数字 要进行取模 PClcd2002的类似工具

三种GDDRAM寻址模式
页寻址 水平寻址 垂直寻址
页寻址

这里是y坐标表示page页数 0xb0就是表示第0页 也就是页地址 x坐标表示位置 18 就是0x12 但是oled要求 把数据分成两部分传递给它 因为18 是0x12 对应二进制就是0001 0010 要分成两部分传数据那高4为就是0001 也就是0x01 但是如何表示高四位呢 那就规定是0x11 这就是高四位

这里因为是高位 所以为10h
OLED屏幕是由SSD1306这款芯片控制的


清屏的函数 因为页地址为8页 所以循环8次

显示数据代码分析
WIFI模块初始化
配置esp8266 wifi微控制芯片 AT指令

串口学习

stm32自动向wifi模块进行发送信息
但是单片机怎么判断收到了ready这条指令呢
memset函数 清空数组中的内容 参数有三个 (数组名字 清空0 数组的大小)
strstr 检查一个字符串中是否包含一个字符串(代替人眼作用)

多个源文件可能都需要进行中断进行控制
中断功能 NVIC()配置 一定要分组
WIFI功能的初步实现
单片机代替人工工作
wifi配置 第一步
重启wifi

第二步
配置WiFi模式
一清理数组 并且重新计数
二发送模式指令
三是等待响应 ok 完成配置

第三步
完成配置wifi重启
一清空数组内容
二发送具体指令
三用strstr等待响应指令 ready 判断是否配置成功

配置wifi路由模块
一清空数据内容
二发送具体指令 这里设置成参数 进行宏定义 进行路由配置 密码配置
三 等待响应

根据以上的代码可以写一个模板

设置这个函数 参数 时间 命令 和响应结果

这里是主函数直接调用该通用函数就可以了实现了 这样就完成了 0 重启wifi 1配置wifi模式 2完成配置重启 3取消自动连接 4连接路由器 5配置单路连接模式 6开启透传模式
建立tcp连接和透传模式
tcp连接


这样进行tcp连接的建立 第7步 第8步透传
但是这样还是比较繁琐这简化下

通过这个函数对这几种情况进行整体得设置 这样直观明确
Mqtt协议
mqtt是在wifi得协议下 建立一条通路 mqtt是实时连接
mqtt得通讯
拿微博举例

用单片机与手机进行举例

connect报文

用16进制表示

00010000 转制 10






strlen sizeof 相同点字符串长度 不同点 是否包含结束标志‘\0’
strlen 是不包含结束标志‘\0’的
sizeof 是包含结束标志‘\0’

memcpy 就是把一部分区域内容复制到另一部的区域中
用c语言实现控制报文
connect控制报文主要包括三部分 固定报文+可变报文+有效载荷
固定报文是10 ?? 可变报文包括 协议名 协议级别 连接标志 保持连接
有效载荷包括 客服端标识符 用户名 密码

客户端标识符 58 -7c 00 27标识符的长度 39
用户名就是58-35 00 11 表示用户名长度 00 11 是16进制也就是10进制的17 长度为17
密码是32-65 00 28 表示密码的长度40
固定报文和可变报文
这里插一句 具体的阿里云服务哪里
小伙伴门可以登录阿里云官网 去找阿里云物联网平台产品呢 如果找不到可以直接问客服 怎么申请阿里云物联网平台 免费试用 客服会给你连接的
然后

开通后的界面

这这里新添加你的产品

因为要添加温湿度 所以这里要加个这个标准化功能模块

通过串口模拟单片机 单片机类似客户端 而远程主机地址就是阿里云的地址 阿里云的地址是 Productkey+.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883 这里Productkey+

在你的阿里云服务器平台上进行查看 每个人的ProductKey是不同的
怎么用c语言去实现呢 用c语言实现剩余长度的计算


c语言通过除法和取余把结果算出来 比如剩余长度300 先除128 在取余 得到的数 要判断是否是高位 如果高位 比如44 对应二进制是0010 1100 但是是高位 所以要高位加1 也就是 1010 1100 对应的数就是172 在进行16进制转换也就是AC 以此类推


这里应该 先写取余然后在除 要不然后第二次循环的结果不正确

printf函数打印输出到屏幕上 sprintf函数打印到数组容器中
(使用数组之前 要先把数组清空)

第一步对数组进行清空
第二步 把客户端di的内容写入到clientid的数组当中
第三步 客户端的id长度

数组 数组长度 密码 设备密钥 密钥长度 输入这几个参数就会得到第三个参数密码
以上主要实现了
单片机代替人工发送报文 最终实现的是以下的效果

以下就是wifi模块连接上阿里云 发送报文 服务器响应
WiFi模块连接阿里云
之前的wifi模块建立了tcp服务 通过tcp协议与阿里云进行连接 把阿里云的ip地址 与端口进行修改就可以直接连接到阿里云了

数据接收和发送机制概述
发送报文到阿里云服务器
发送数据面临的问题就是 数据阻塞 一般用环形队列

一般把发送的数据放置某个数据的空区域中 在进行扫描当中找到这些区域内的数据 然后立即取出发送

定义一个7行400列的数组 定义单片机发给容器的数据 在定义一个容易给服务器的数据
这一部分是单片机到容器(unsigned char *mqtt_TxInPtr)

高8位放置第0位 低8位放置第1位 定义一个数组的最后一位的数值 根据TxInPtr与TxEndPtr进行判断然后进行循环 重新移到第一行
容器到阿里云服务器 (unsign *mqtt_OutPtr)


WIFI的连接

为了检验每一个步骤是否执行成功 如果返回0 就是执行成功 返回非0就是失败

判断是否连接阿里云 连上了做什么

判断是否连接阿里云服务 如果连上了判断容器中是否有数据
数据接收
建立容器
通过串口中断接收一次完整的数据放到容器中
再主函数中通过查询方式再容器中找到所需信息
发送数据和接受数据都要先建立容器
mqtt协议通信中 如果没有长时间信息的接收和发送 就会掉线
所以就要一直保持连接 传输完成一个报文的时候一定要在100ms内传递下一个数据 要不然会掉线
发送ping报文 发送C0 00
收到D0 00 表示连接正常
publish控制报文是指从客户端向服务端 或者服务端向客户端传输一个应用消息
publish报文是如何构成的

DHT11模块 温湿度模块
单片机采集模块的数据 然后把数据上传到云平台

30时固定的 下一位就是剩余长度 分别时09 0B的长度 在两位就是数据的长度 然后是命令的长度
publish报文实现


8万+

被折叠的 条评论
为什么被折叠?



