目录
需要元器件准备
- 核心板:stm32F103C8T6
- DHT11 温湿度传感器
- BHT1750 光照度传感器
- ESP8266-01s WIFI模块
- 有源蜂鸣器低电平触发模块
原理图
学会白嫖正点原子的资源
有些代码是不需要自己写的,正所谓站在巨人的肩膀上看世界,修改别人的代码,实现快速开发
第一次碰见记录下哈哈哈白嫖链接http://47.111.11.73/docs/boards/stm32/zdyz_stm32f103_jingyingV2.html
Keil创建基于标准库的STM32工程
小助手不太需要,自己配置文件
添加工程需要的启动文件
添加文件路径
出现这个问题需要在项目文件创建所选的文件夹
在项目中添加相应模块的驱动
1.OLED驱动
OLED驱动模块:根据原理图需要修改引脚配置,SCL引脚连接PA5,SDA引脚连接PA7,在驱动文件修改宏定义,宏定义真的是方便扒代码的白嫖党
2.DHT11驱动
DHT11温湿度传感器模块,重要的是对一个陌生的模块要学会怎样使用
DHT11的引脚说明。DATA引脚采用串行传输模式,并且是单总线,需要把输出数据的引脚配置输入输出模式。由DHT11采集数据,向微控制器传输,传输的数据包由五个字节组成,数据格式如下:
数据包格式:
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位
其中校验位为前四个字节相加结果的末8位,根据校验位可以检测数据是否传输的正确
总的通信过程:
单片机作为主机,首先发送起始信号,将数据总线拉低,告诉DHT11,我准备接受数据了,然后将总线拉高,等待DHT11的响应。DHT11接收到单片机发送的起始信号后,将总线拉低,做出响应,之后再拉高,做好传输数据的准备。
具体通讯时序:
总线在默认的状态下为高电平,单片机将总线拉低的信号必须大于18ms,保证dht11能检测到。
当DHT检测到单片机的起始信号后,等待信号结束,发送80us的低电平信号表示响应,在单片机拉高的20us-40us内检测。
数据0的信号:
数据1的信号:
最后一个bit传输结束后的信号:
DHT11发送响应信号后,拉高总线为传输数据做准备。每一个bit数据都已50us的低电平作为起始,高电平的长度决定了传输的数据是1还是0。当最后一个bit传输结束后,由DHT拉低,在由单片机拉高。
不明白的是,主机起始信号结束后,为什么总线需要拉高,为什么还要延时等待20us-40us,为什么不在起始信号结束后读取响应结果?如果dht没有响应,在输入模式下端口默认输出高电平,直到读取,我倒是觉得retry这个参数是为了使while循环持续进行,直到检测到DHT11输出低电平,不然就是一直持续高电平,说明线路的问题
第二个while是为了检测到电平被拉高,如果在第二个while循环中未检测到高电平,说明什么问题呢?挠头
读取Bit位
判断读取的是0还是1主要是根据DHT11发送高电平之后的状态,数字0高电平持续性时间26us-28us,数字1信号高电平持续时间70us,选择40us左右的即可进行判断
//读取bit位
uint8_t DHT11_ReadBit(void)
{
uint8_t Retry=0;
while( (DHT11_ReadPin == 1) && Retry<100)//等待低电平
{
Retry++;
Delay_us(1);
}
Retry=0;
while((DHT11_ReadPin == 0) && Retry<100)//等待高电平
{
Retry++;
Delay_us(1);
}
Delay_us(40);//等待40us
if(DHT11_ReadPin)return 1;
else return 0;
}
读取一个字节
DHT11传输数据从高位开始传输,依据这个特点设置代码。Data每接收一个数据向左移位,一次循环8次,即可得到一个字节
uint8_t DHT11_ReadByte(void)
{
uint8_t i,Data;
Data=0;
for (i=0; i<8; i++)
{
Data<<=1;
Data|=DHT11_ReadBit();
}
return Data;
}
在keil中如何使用全局变量
1.在某个c文件里定义全局变量后,需要在其他c文件里使用,则在被用到的文件里使用extern声明,表示该变量的作用扩展到此文件
有两个源文件 test1.c test2.c,需要在test2.c中用到test1.c里面的变量
test1.c
//声明变量
uint8_t a;
test2.c
extern uint8_t a;
2.在test2.c文件中使用test1.c的.h文件
在test1.c中定义且初始化变量:uint8_t a=0;
再在test1.h中使用extern声明:extern uint8_t a;
最后在test2.c中使用test1.h:#include "test1.h";
读取数据包
uint8_t DHT11_ReadData(uint8_t * humih,uint8_t * humil,uint8_t * temph,uint8_t * templ)
{
uint8_t Buf[6];
uint8_t i;
DHT11_Res();
if(DHT11_Check()==0)
{
for(i=1;i<6;i++)
{
Buf[i]=DHT11_ReadByte();
}
if(Buf[1]+Buf[2]+Buf[3]+Buf[4]==Buf[5])
{
*humih=Buf[1];
*humil=Buf[2];
*temph=Buf[3];
*templ=Buf[4];
lable=1;
}
}else{
return 1;
}
return 0;
}