一.温湿度传感器介绍
1.主要参数
供电电压:3.3 - 5.5V直流电
输出为单总线数字信号
温度测量范围0-50度(精度正负2度,分辨率1度)
湿度测量范围为20-90%RH(精度为正负5%,分辨率1%)
2.硬件连接 模块的VCC 接单片机的5V 模块的GND 接单片机的GND 模块的DAT 接单片机任意引脚 vcc和gnd之间可以加一个电容,用于去耦滤波
3.温湿度采集原理 采用单总线双向串行通信协议,每次采集都要由单片机发起开始信号,然后DHT11会向单片机发送响应并开始传输40位数据帧,高位在前。
(1)数据格式为:
第一二个字节: 8bit湿度整数数据+8bit湿度小数数据 第三四个字节: 8bit温度整数数据+8bit温度小数数据 第五个字节 : 8bit校验位(它是前四个数据相加后八位的数值) 温湿度小数部分默认为0,即单片机采集的数据都是整数,校验位为4个字节的数据相加取结果的低8位数据作为校验和;
示例: 0011 0101 0000 0000 0001 1000 0000 0000 0100 1001 湿度高八位 湿度低八位 温度高八位 温度低八位 检验位 计算 : 0011 0101 + 0001 1000 结果: 0100 1101 若不等于 01001101 ,则本次接收数据不正确,重新接收数据
(2)温湿度传感器时序介绍 总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号,主机发送开始信号结束后,延时等待20
二.代码示例
DHT11.h头文件
#ifndef __DHT11_H
#define __DHT11_H
#include "stm32f10x.h"
#define DHT11_IO_IN() {GPIOB->CRL&=0XFFFFFFF0;GPIOB->CRL|=0x08;}
#define DHT11_IO_OUT() {GPIOB->CRL&=0XFFFFFFF0;GPIOB->CRL|=0x03;}
#define DHT11_DQ_OUT PBout(0)
#define DHT11_DQ_IN PBin(0)
u8 DHT11_Init(void);
u8 DHT11_Read_Data(void);
u8 DHT11_Read_Byte(void);
u8 DHT11_Read_Bit(void);
u8 DHT11_Check(void);
void DHT11_Rst(void);
#endif
DHT11.c文件
#include "dht11.h"
#include "delay.h"
#include "oled.h"
void DHT11_Rst(void)
{
DHT11_IO_OUT();
DHT11_DQ_OUT=0;
delay_ms(20);
DHT11_DQ_OUT=1;
delay_us(30);
}
u8 DHT11_Check(void)
{
u8 retry=0;
DHT11_IO_IN();
while (DHT11_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
else retry=0;
while (!DHT11_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
};
if(retry>=100)return 1;
return 0;
}
u8 DHT11_Read_Bit(void)
{
u8 retry=0;
while(DHT11_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
}
retry=0;
while(!DHT11_DQ_IN&&retry<100)
{
retry++;
delay_us(1);
}
delay_us(40);
if(DHT11_DQ_IN)return 1;
else return 0;
}
u8 DHT11_Read_Byte(void)
{
u8 i,dat;
dat=0;
for (i=0;i<8;i++)
{
dat<<=1;
dat|=DHT11_Read_Bit();
}
return dat;
}
u8 DHT11_Read_Data()
{
u8 buf[5];
u8 i;
DHT11_Rst();
if(DHT11_Check()==0)
{
for(i=0;i<5;i++)
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
OLED_ShowNum(74,2,buf[2],2);
OLED_ShowNum(96,2,buf[3],1);
OLED_ShowNum(74,5,buf[0],2);
OLED_ShowNum(96,5,buf[1],1);
}
}else return 1;
return 0;
}
u8 DHT11_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_0);
DHT11_Rst();
return DHT11_Check();
}
OLED.h头文件
#ifndef _OLED_H
#define _OLED_H
#include "stm32f10x.h"
#define OLED_SCL_Set() GPIO_SetBits(GPIOA,GPIO_Pin_6);
#define OLED_SCL_CLr() GPIO_ResetBits(GPIOA,GPIO_Pin_6);
#define OLED_SDA_Set() GPIO_SetBits(GPIOA,GPIO_Pin_7);
#define OLED_SDA_CLr() GPIO_ResetBits(GPIOA,GPIO_Pin_7);
#define OLED_SDA_RCV() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)
#define OLED_CMD 1
#define OLED_DATA 0
void IIC_config(void);
void IIC_Start(void);
void IIC_Stop(void);
char OLED_Wait_ACK(void);
void IIC_Send(uint8_t Write_Byte);
void OLED_WR_CMD(uint8_t cmd);
void OLED_WR_DATA(uint8_t data);
void OLED_WR_Byte(uint8_t data,uint8_t cmd);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_Init(void);
void OLED_Clear(void);
void OLED_ShowChar(uint8_t x,uint8_t y, uint8_t ch,uint8_t temp);
void OLED_ShowStr(uint8_t x,uint8_t y,char *ch,uint8_t temp);
int OLED_Getpos(unsigned char length);
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int Num,unsigned char length);
void OLED_WriteCF(uint8_t x,uint8_t y,uint8_t m,uint8_t server);
void OLED_WriteCN(uint8_t x,uint8_t y,uint8_t m,uint8_t count);
void OLED_ShowBMP(uint8_t x0,uint8_t y0, uint8_t x1,uint8_t y1,uint8_t* BMP);
#endif
fontstr.h头文件 OLED.c文件
#include "stm32f10x.h"
#include "oled.h"
#include "delay.h"
#include "fontstr.h"
void IIC_config()
{
GPIO_InitTypeDef GPIO_Initstrue;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_Initstrue.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Initstrue.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
GPIO_Initstrue.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_Initstrue);
OLED_SCL_Set();
OLED_SDA_Set();
}
void IIC_Start()
{
OLED_SCL_Set();
OLED_SDA_Set();
delay_us(1);
OLED_SDA_CLr();
delay_us(1);
OLED_SCL_CLr();
delay_us(1);
}
void IIC_Stop()
{
OLED_SDA_CLr();
delay_us(1);
OLED_SCL_Set();
delay_us(1);
OLED_SDA_Set();
delay_us(1);
}
char OLED_Wait_ACK()
{
OLED_SCL_CLr();
delay_us(1);
OLED_SDA_CLr();
delay_us(1);
OLED_SCL_Set();
delay_us(1);
if(OLED_SDA_RCV())
{
return 1;
}
else
{
OLED_SCL_CLr();
return 0;
}
}
void IIC_Send(uint8_t Write_Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
OLED_SCL_CLr();
delay_us(1);
if(Write_Byte & 0x80)
{
OLED_SDA_Set();
}else{
OLED_SDA_CLr();
}
delay_us(1);
OLED_SCL_Set();
delay_us(1);
Write_Byte <<= 1;
delay_us(1);
}
while(OLED_Wait_ACK());
}
void OLED_WR_CMD(uint8_t cmd)
{
IIC_Start();
IIC_Send(0x78);
IIC_Send(0x00);
IIC_Send(cmd);
IIC_Stop();
}
void OLED_WR_DATA(uint8_t data)
{
IIC_Start();
IIC_Send(0x78);
IIC_Send(0x40);
IIC_Send(data);
IIC_Stop();
}
void OLED_WR_Byte(uint8_t data,uint8_t mount)
{
if(mount)
{
OLED_WR_CMD(data);
}else{
OLED_WR_DATA(data);
}
}
void OLED_SetPos(uint8_t x,uint8_t y)
{
OLED_WR_Byte(0xb0+y,OLED_CMD);
OLED_WR_Byte(0x0f&x,OLED_CMD);
OLED_WR_Byte((0xf0&x)>>4|0x10,OLED_CMD);
}
void OLED_ON()
{
OLED_WR_Byte(0x8D,OLED_CMD);
OLED_WR_Byte(0x14,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
}
void OLED_OFF()
{
OLED_WR_Byte(0x8D,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
OLED_WR_Byte(0xAE,OLED_CMD);
}
void OLED_Init()
{
delay_init();
delay_ms(200);
OLED_WR_CMD(0xAE);
OLED_WR_CMD(0x20);
OLED_WR_CMD(0x10);
OLED_WR_CMD(0xb0);
OLED_WR_CMD(0xc8);
OLED_WR_CMD(0x00);
OLED_WR_CMD(0x10);
OLED_WR_CMD(0x40);
OLED_WR_CMD(0x81);
OLED_WR_CMD(0xff);
OLED_WR_CMD(0xa1);
OLED_WR_CMD(0xa6);
OLED_WR_CMD(0xa8);
OLED_WR_CMD(0x3F);
OLED_WR_CMD(0xa4);
OLED_WR_CMD(0xd3);
OLED_WR_CMD(0x00);
OLED_WR_CMD(0xd5);
OLED_WR_CMD(0xf0);
OLED_WR_CMD(0xd9);
OLED_WR_CMD(0x22);
OLED_WR_CMD(0xda);
OLED_WR_CMD(0x12);
OLED_WR_CMD(0xdb);
OLED_WR_CMD(0x20);
OLED_WR_CMD(0x8d);
OLED_WR_CMD(0x14);
OLED_WR_CMD(0xaf);
}
void OLED_Clear()
{
uint8_t m,n;
for(m=0;m<8;m++)
{
OLED_SetPos(0,m);
for(n=0;n<128;n++)
{
OLED_WR_Byte(0x00,OLED_DATA);
}
}
}
void OLED_ShowChar(uint8_t x,uint8_t y, uint8_t ch,uint8_t temp)
{
unsigned char i = 0,c = 0;
if(ch != '\0')
{
c = ch - 32;
OLED_SetPos(x,y);
if(temp == 6)
{
for(i=0;i<temp;i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA);
}else if(temp == 8){
for(i=0;i<temp;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_SetPos(x,++y);
for(i=0;i<temp;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
}
}
void OLED_ShowStr(uint8_t x,uint8_t y,char *ch,uint8_t temp)
{
unsigned char j = 0;
while(ch[j] != '\0')
{
if(temp == 6)
{
if(x>=122)
{
x = 0;
y++;
}
}else if(temp == 8){
if(x>=120)
{
x = 0;
y+=2;
}
}
OLED_ShowChar(x,y,ch[j],temp);
x += temp;
j++;
}
}
int OLED_Getpos(unsigned char length)
{
unsigned int pos = 1;
while(length--)
{
pos *= 10;
}
return pos;
}
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int Num,unsigned char length)
{
unsigned char i;
for(i=length;i>0;i--)
{
OLED_ShowChar(x,y,'0'+Num/OLED_Getpos(--length)%10,8); x+=8;
}
}
void OLED_WriteCF(uint8_t x,uint8_t y,uint8_t m,uint8_t server)
{
uint8_t i;
if(x>112)
{
x = 0;
y+=2;
}
OLED_SetPos(x,y);
for(i=0;i<16;i++)
OLED_WR_Byte(F16x16[m][i+(server-1)*32],OLED_DATA);
OLED_SetPos(x,++y);
for(i=0;i<16;i++)
OLED_WR_Byte(F16x16[m][i+(server-1)*32+16],OLED_DATA);
}
void OLED_WriteCN(uint8_t x,uint8_t y,uint8_t m,uint8_t count)
{
uint8_t i,j = 0;
while(count--)
{
if(x>112)
{
x = 0;
y+=2;
}
OLED_SetPos(x,y);
for(i=0;i<16;i++)
OLED_WR_Byte(F16x16[m][i+j*32],OLED_DATA);
OLED_SetPos(x,++y);
for(i=0;i<16;i++)
OLED_WR_Byte(F16x16[m][i+16+j*32],OLED_DATA);
x += 16;
OLED_SetPos(x,--y);
j++;
}
}
void OLED_ShowBMP(uint8_t x0,uint8_t y0, uint8_t x1,uint8_t y1,uint8_t* BMP)
{
uint8_t x,y;
for(y=y0;y<y1;y++)
{
OLED_SetPos(x0,y);
for(x=x0;x<x1;x++)
{
OLED_WR_Byte(BMP[x+(x1-x0)*y],OLED_DATA);
}
}
}
main.c文件
#include "stm32f10x.h"
#include "oled.h"
#include "delay.h"
#include "dht11.h"
int main()
{
delay_init();
IIC_config();
OLED_Init();
OLED_ON();
delay_ms(2000);
OLED_Clear();
delay_ms(2000);
OLED_WriteCN(0,2,0,5);
OLED_WriteCF(90,2,2,3);
OLED_WriteCF(112,2,2,1);
OLED_WriteCN(0,5,1,5);
OLED_WriteCF(90,5,2,3);
OLED_WriteCF(112,5,2,2);
while( DHT11_Init() )return 1;
while(1)
{
DHT11_Read_Data();
delay_ms(500);
}
}
|