DHT11頭文件:
#ifndef _DHT11_H_
#define _DHT11_H_
#include "stm32f10x.h"
#include "bitband_cm3.h" // 位帶操作頭文件
#define DHT11_REV_DATA PBin(6)
#define DHT11_SEND_DATA PBout(6)
void DHT11_Init(void);
int DHT11_Read_Data(uint8_t *Temp_H,uint8_t* Temp_L,uint8_t* RH_H,uint8_t* RH_L);
#endif
DHT11源文件:
#include "dht11.h"
#include "systick.h"
#if 0 //0---庫函數 1---寄存器
// DTH11 ---> PB6
// 輸出模式
void DHT11_OUT(void)
{
GPIOB->CRL &=~ (0xf<<24);
GPIOB->CRL |= (3<<24);//通用推挽輸出模式 50M
}
// 輸入模式
void DHT11_IN(void)
{
GPIOB->CRL &=~ (0xf<<24);
GPIOB->CRL |= (4<<24);//配置浮空輸入(外接上拉電阻)
}
//DHT11初始化
void DHT11_Init(void)
{
RCC->APB2ENR |= (1<<3); // 開啟PB端口時鐘
DHT11_IN( );// DHT11 的DATA 引腳處于輸入狀態,時刻檢測外部信號
delay_ms(500);
delay_ms(500);//DHT11 上電后要等待 1S 以越過不穩定狀態在此期間不能發送任何指令
}
#else
// DTH11 ---> PB6
// 輸出模式
void DHT11_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//通用推挽輸出
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//50M
GPIO_Init(GPIOB, &GPIO_InitStruct);//PB6
}
// 輸入模式
void DHT11_IN(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//配置浮空輸入(外接上拉電阻)
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//50M
GPIO_Init(GPIOB, &GPIO_InitStruct);//PB6
}
//DHT11初始化
void DHT11_Init(void)
{
RCC->APB2ENR |= (1<<3); // 開啟PB端口時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//開啟PB端口時鐘.
DHT11_IN( );// DHT11 的DATA 引腳處于輸入狀態,時刻檢測外部信號
delay_ms(500);
delay_ms(500);//DHT11 上電后要等待 1S 以越過不穩定狀態在此期間不能發送任何指令
}
#endif
//起始信號
void DHT11_Start(void)
{
DHT11_SEND_DATA=0;
delay_ms(18);
DHT11_SEND_DATA=1;
delay_us(20);//釋放總線
}
//應答信號
//返回值 0--無應答 1--有應答
u8 DHT11_Ack(void)
{
if(DHT11_REV_DATA!=0)
{
return 0;
}
while(DHT11_REV_DATA==0);//等待80us低電平應答結束
while(DHT11_REV_DATA==1);//等待80us高電平應答結束
return 1;
}
//讀取一個字節數據
u8 DHT11_Read_Byte(void)
{
u8 data=0;
u8 i;
//接受數據,每個數據以50us低電平開始
for(i=0;i<8;i++)
{
data <<= 1;
while(!DHT11_REV_DATA);//等待發送數據的時序變為高電平
delay_us(40);//23~27u為數據0,68~74us為u數據1
if(DHT11_REV_DATA==1)
{
data |=1;//數據1
while(DHT11_REV_DATA);//等待高電平應答結束
}
}
return data;
}
//讀取溫濕度
int DHT11_Read_Data(u8 *Temp_H,u8* Temp_L,u8* RH_H,u8* RH_L)
{
u8 check;
DHT11_OUT( );
DHT11_Start( );
DHT11_IN( );//切換為輸入
if( DHT11_Ack( )==0 )
{
return -1;
}
//讀取數據
*RH_H=DHT11_Read_Byte( );
*RH_L=DHT11_Read_Byte( );
*Temp_H=DHT11_Read_Byte( );
*Temp_L=DHT11_Read_Byte( );
check=DHT11_Read_Byte( );
//結束讀取
delay_ms(50);
DHT11_OUT( );//切換為輸出
DHT11_SEND_DATA=1;//釋放總線
//校驗數據
if(check !=(*Temp_H+*Temp_L+*RH_H+*RH_L) )
{
return -2;
}
return 0;
}
|