在完成所有项目后会开源,目前初步是想做一个通过DHT11采集信息,OLED显示,ESP8266上传,可通过小程序查看的简易智能家居事例。
MindSDK环境准备
使用sdk里的hello_work作为模板
DHT11工作原理
简单来说就是
/*
数据格式:
湿度整数 湿度小数 温度整数 温度小数 校验位
00000000 00000000 00000000 00000000 00000000
1 看原理图确认GPIO引脚
2、 输出模式, 输出起始信号 :输出低电平18~30ms, 20ms
3、 IO口配置浮空输入模式,准检测响应信号
传感器把数据总线( SDA)拉低 83μs,再接高 87μs 以响应主机的起始信号。
4、 40 个位的数据,高位先发;
一位一位的收,数据0: 54us低电平 + 23~27高电平数据1: 54us低电平 + 68~74高电平 注意高位先发的(每个字节)
5、校验数据
前4个字节,求和,把和值的末八位和校验位对比 相同数据正确、否则数据异常
*/
接下来就开始写代码了
由于我在MindSDK里找不到延时函数就只能手动操作一波寄存器写个延时函数了
delay.cvoiddelay_us(uint32_t nus) { uint32_t temp; SysTick->LOAD= nus *15;SysTick->VAL=0x00;SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;do{ temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16)));SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;SysTick->VAL =0X00;}voiddelay_ms(uint16_t nms) { uint32_t temp; SysTick->LOAD= nms *15*1000;SysTick->VAL=0x00;SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;do{ temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16)));SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;SysTick->VAL =0X00;}
接下来开始写DHT11的代码了,主要是调用SDK代码,开发难度很低
dht11.c#include"dht11.h"voiddht11_gpio_input(void){ GPIO_Init_Type g;g.Pins = DHT11_GPIO_PIN; g.Speed = GPIO_Speed_50MHz; g.PinMode = GPIO_PinMode_In_Floating;GPIO_Init(DHT11_GPIO_TYPE, &g); }voiddht11_gpio_output(void){ GPIO_Init_Type g;g.Pins = DHT11_GPIO_PIN; g.Speed = GPIO_Speed_50MHz; g.PinMode = GPIO_PinMode_Out_PushPull;GPIO_Init(DHT11_GPIO_TYPE, &g); }voiddht11_reset(void){dht11_gpio_output(); DHT11_OUT_L;delay_us(19000); DHT11_OUT_H;delay_us(30);dht11_gpio_input(); }uint16_tdht11_scan(void){returnDHT11_IN; }uint16_tdht11_read_bit(void){while(DHT11_IN == RESET);delay_us(40);if(DHT11_IN == SET) {while(DHT11_IN == SET);return1; }else{return0; } }uint16_tdht11_read_byte(void){uint16_ti;uint16_tdata =0;for(i =0; i <8; i++) { data <<=1; data |=dht11_read_bit(); }returndata; }uint8_tchecksum;uint16_tdht11_read_data(uint8_tbuffer[5]){uint16_ti =0;dht11_reset();if(dht11_scan() == RESET) {while(dht11_scan() == RESET);while(dht11_scan() == SET);for(i =0; i <5; i++) { buffer[i] =dht11_read_byte(); }while(dht11_scan() == RESET);dht11_gpio_output(); DHT11_OUT_H; checksum = buffer[0] + buffer[1] + buffer[2] + buffer[3];if(checksum != buffer[4]) {return1; } }return0; }
dht11.h#ifndef__DHT11_H__#define__DHT11_H__#include"board_init.h"#include"delay.h"#include"hal_gpio.h"#include"hal_rcc.h"#include"pin_init.h"#defineDHT11_GPIO_TYPE GPIOB#defineDHT11_GPIO_PIN GPIO_PIN_11#defineDHT11_RCC RCC_APB2Periph_GPIOB#defineDHT11_OUT_H GPIO_SetBits(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)#defineDHT11_OUT_L GPIO_ClearBits(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)#defineDHT11_IN GPIO_ReadInDataBit(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)#defineRESET 0#defineSET 1voiddht11_gpio_input(void);voiddht11_gpio_output(void);uint16_tdht11_scan(void);uint16_tdht11_read_bit(void);uint16_tdht11_read_byte(void);uint16_tdht11_read_data(uint8_tbuffer[4]);#endif
写完了DHT11的代码,接下来验证下
在main里调用下
while(1) {if(dht11_read_data(buffer) ==0) { hum = buffer[0] + buffer[1] /10.0; temp1 = buffer[2] + buffer[3] /10.0;printf("hum:%f,temp:%f\r\n",hum,temp1); } delay_ms(100); }
看下结果
总结
MindSDK使用体验还行,有些还是得自己写,要是api更完善点会更好,现在以及完成了DHT11,下一步是OLED。
原作者:四季的温度