本实验是按照流程图的顺序去写的文章
据说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 }
浙公网安备 33010602011771号