十DHT11

Posted on 2016-09-26 11:37  不信邪  阅读(331)  评论(0)    收藏  举报

本实验是按照流程图的顺序去写的文章

据说DHT11没有小数部分,规格书是错误的。不过我验证的程序确实是没有小数

一.硬件连接:DHT11的数据线接到了PB10

二.实验代码

1.开始

2.初始化——串口,Systick,GPIO

2.1GPIO初始化

void DHT11_GPIO_Config(void) //连接DHT11的数据口初始化
{		
	
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 
														   
  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;	
	
  	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_10);	 
}

2.2串口初始化

 1 void USART_Config(void)  //串口初始化
 2 {
 3     GPIO_InitTypeDef GPIO_InitStructure;
 4     USART_InitTypeDef USART_InitStructure;
 5     
 6     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
 7     
 8         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 9         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
10     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
11     GPIO_Init(GPIOA, &GPIO_InitStructure);
12     
13     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
14     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
15     GPIO_Init(GPIOA, &GPIO_InitStructure); 
16     
17     USART_InitStructure.USART_BaudRate = 115200;
18     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
19     USART_InitStructure.USART_StopBits = USART_StopBits_1;
20     USART_InitStructure.USART_Parity = USART_Parity_No ;
21     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
22     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
23     USART_Init(USART1, &USART_InitStructure); 
24     USART_Cmd(USART1, ENABLE);
25         
26 }

2.3Systick初始化

static u8 fac_us=0;
static u16 fac_ms=0;

void SysTick_Init(void)
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);  //选择外部系统时钟,为系统时钟72MHz的1/8
    fac_us=72000000/8000000;                                                                     //在上面的时钟情况下,滴答时钟为9MHz,即1S来9M个周期,每来一个周期减少1个数字,这样1个数字是1/9微妙,9个数字正好是1us。fac_us正好是9,是1us。
    fac_ms=(u16)fac_us*1000;        //这是定时1ms所需的数字
}

三.发送起始信号

 1 void DHT11_Start(void) //起始信号
 2 {
 3     GPIO_Config_PP(); //推挽输出
 4      GPIO_SetBits(GPIOA,GPIO_Pin_1);  //拉高
 5     GPIO_ResetBits(GPIOB,GPIO_Pin_10);  //拉低
 6     Delay_ms(20);   //延时最少18ms    
 7     GPIO_SetBits(GPIOB,GPIO_Pin_10);  //拉高
 8     Delay_us(30);   //延时30us    
 9      //发送完起始信号要改变为接受模式 
10     //延时等待从机响应
11     //从机先为低电平响应,后为高电平响应
12 }
13 
14 void GPIO_Config_PP()  //推完输出
15 {
16     GPIO_InitTypeDef  GPIO_InitStruct;
17     GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
18     GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
19     GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
20     GPIO_Init(GPIOB,&GPIO_InitStruct);
21 }

1 void GPIO_Config_IPU()  //上拉输入
2 {
3     GPIO_InitTypeDef  GPIO_InitStruct;
4     GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
5     GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
6     GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
7     GPIO_Init(GPIOB,&GPIO_InitStruct);
8 }

 

这个往下有两种情况,一个就是发送完信号后收到了应答型号,另一个就是发送完后没有收到应答信号,都要有对应的处理

 1 //数据处理
 2 u8 DHT11_Collect(DHT11_Data_TypeDef *DHT11_Data)   //指针形式确实是好用
 3 {
 4     DHT11_Start();
 5     GPIO_Config_IPU();   //模式改为接收模式
 6     if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==Bit_RESET)   
 7     {
 8     while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==Bit_RESET);  //等待从机响应为低,一直循环
 9     while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==Bit_SET);  //等待从机响应为高,一直循环
10     
11         //数据读取,处理
12     DHT11_Data->humi_int=Read_Byte(); //字节读
13     DHT11_Data->humi_deci=Read_Byte();
14     DHT11_Data->temp_int=Read_Byte();
15     DHT11_Data->temp_deci=Read_Byte();
16     DHT11_Data->check=Read_Byte();
17     
18         //数据接收完成
19     GPIO_Config_PP(); //推挽状态输出
20     GPIO_SetBits(GPIOB,GPIO_Pin_10);  //拉高
21     //数据校验
22     if(DHT11_Data->check==DHT11_Data->humi_int+DHT11_Data->humi_deci+DHT11_Data->temp_int+DHT11_Data->temp_deci)
23         return SUCCESS;
24     else
25         return ERROR;  //数据校验出错
26    }
27     else
28         return ERROR; //没有响应
29 }     
 1 //字节读数据
 2 u8 Read_Byte(void)
 3 {
 4     u8 i ,temp;
 5     for(i=0;i<8;i++)
 6     {
 7         while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0);  //等待从机响应为低,一直循环
 8         Delay_us(40);   //延时40us    
 9         if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0)  //表示电平是0
10         {
11             temp&=~(0x01<<(7-i));
12         }
13         else
14         {
15             while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1);  //说明电平是高电平
16             temp|=(0x01<<(7-i));
17         }
18     }
19     return temp;
20 }

主函数

1 typedef struct   //温湿度结构体
2 {
3     u8 humi_int;
4     u8 humi_deci;
5     u8 temp_int;
6     u8 temp_deci;
7     u8 check;
8 }DHT11_Data_TypeDef;

 

 1 DHT11_Data_TypeDef dht11_data_time; 
 2 int main(void)
 3 {
 4     SysTick_Init();  
 5      USART_Config();
 6      DHT11_GPIO_Config();
 7          printf("\r\n温湿度实验\r\n");
 8         while(1)
 9             {
10                 if(DHT11_Collect(&dht11_data_time)==SUCCESS)
11                 {
12                 printf("\r\n连接成功\r\n");
13                 DHT11_Collect(&dht11_data_time);
14                     printf("\r\n当前湿度为:%d.%d%RH,当前温度为:%d.%d℃\r\n",dht11_data_time.humi_int,dht11_data_time.humi_deci,dht11_data_time.temp_int,dht11_data_time.temp_deci);
15                 Delay_ms(1000); //1s显示一次
16                 }
17                 else
18                 {
19                     printf("Read DHT11 ERROR!\r\n");
20                 }
21             }