OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2502|回复: 1

DHT11的问题·

[复制链接]

1

主题

2

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2018-3-23
在线时间
5 小时
发表于 2018-3-23 23:50:10 | 显示全部楼层 |阅读模式
10金钱
代码和原子哥的有写不同,用串口显示的,但时序感觉对的,但用printf来dbug,发现模块输出起始信号后一直未响应,不知道是什么原因,求大佬解答,谢谢大家
/******************************************总线初始化.h**************************************************************************************/
#ifndef __GPIO_H
#define __GPIO_H

#include "stm32f10x.h"
                                                                                                                                       
#define GPIOG_11_IPU()    {GPIOG->CRH&=0xFFFF0FFF;GPIOG->CRH|=8<<12;GPIOG->ODR|=1<<11);}//设置GPIOG11为上拉输入
#define GPIOG_11_Out_PP() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}//设置GPIOG11为推挽输出*/

void DQ_Init(void);//单总线初始化

#endif
/*******************************************************************************************************************************************/

/*****************************************总线初始化.c***************************************************************************************/
#include "gpio.h"

void DQ_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;//定义包涵GPIOG有关参数的结构体
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);//使能GPIOG的时钟
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11;//第11引脚
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOG,&GPIO_InitStruct);//GPIOG初始化

        GPIO_SetBits(GPIOG,GPIO_Pin_11);//初始化输出高电平
}
/*******************************************************************************************************************************************/


/*****************************************************DHT11.h*******************************************************************************/
#include "gpio.h"

void DQ_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;//定义包涵GPIOG有关参数的结构体
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);//使能GPIOG的时钟
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11;//第11引脚
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOG,&GPIO_InitStruct);//GPIOG初始化

        GPIO_SetBits(GPIOG,GPIO_Pin_11);//初始化输出高电平
}
/*********************************************************************************************************************************************/


/***************************************************DHT11.c***********************************************************************************/
#include "dht11.h"
#include "gpio.h"
#include "usart.h"

#include "sys.h"

extern u8 Data[5];

void DHT11_Rst(void)//复位信号
{
        GPIOG_11_Out_PP();//推挽输出,发送模式
        GPIO_ResetBits(GPIOG,GPIO_Pin_11);//主机将信号线拉低
        delay_ms(20);//延时20ms,要求持续低电平至少18ms
        GPIO_SetBits(GPIOG,GPIO_Pin_11);//主机将信号线拉高
        delay_us(30);//延时30us,要求延时20-40us,主机进入接受模式,等待DHT11响应
}



u8 DHT11_Check(void)//检测信号
{
        u8 num=0;
        GPIO_InitTypeDef GPIO_InitStruct;
       
        GPIO_ResetBits(GPIOB,GPIO_Pin_5);                                                 //PB.5 输出低
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//上拉输入
        GPIO_Init(GPIOG,&GPIO_InitStruct);//GPIOG初始化
       
        //GPIOG_11_IPU();//上拉输入,接收模式
        while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)&&num<=100)//读到低电平且num<=100 或 读到高电平且num>100 跳出循环
        {
                num++;
                delay_us(1);
        }//相当于给了100us的时间,超出100us还未检测到DHT11传回的低电平,判定设备不存在
        printf("%d\r\n",num);
        GPIO_SetBits(GPIOB,GPIO_Pin_5);                                                 //PB.5 输出高
        if(num>100) return 1;//超出100,返回1,判定设备不存在
        else num=0;//将num置0,便于下面程序使用
        while(!GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11)&&num<=100)//读到高电平且num<=100 或 读到电平且num>100 跳出循环
        {
                num++;
                delay_us(1);
        }//相当于给了100us的时间,超出100us检测到低电平还未结束,判定设备不存在
        if(num>100) return 1;//超出100,返回1,判定设备不存在
        return 0;//说明设备存在
}


u8 DHT11_Read_Bit(void)//读一位
{
        u8 num=0;
        while(!GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11));//高电平跳出循环
        while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_11))//检测高电平时间
        {
                delay_us(1);
                num++;
        }
        if(num<70) return 0;
        else return 1;
}

u8 DHT11_Read_Byte(void)//读一字节
{
        u8 Data=0,i,j;
        for(i=1;i<=8;i++)
        {
                Data=Data<<1;//左移一位
                j=DHT11_Read_Bit();//保存读到电平
                Data|=j;//或上j的值
        }
        return Data;
}

u8 DHT11_Start(void)//开始
{                                                         
    DHT11_Rst();//复位信号          
    if(DHT11_Check())//检测信号,如果得到值为1,说明设备不存在,返回1
                return 1;//设备不存在返回1         
        else
                return 0;//设备存在返回0
}

u16 DHT11_Get_TandH(void)
{
        u8 i;
        u16 data=0;
        if(DHT11_Start())return 0;//设备不存在
    //DHT11_Rst();//复位信号
    //DHT11_Check();//检测信号                     
        for(i=0;i<5;i++)
                Data[i]=DHT11_Read_Byte();//读取返回的五位数据
        for(i=0;i<4;i++)
                data=data+Data[i];//前四位和
        if(data!=Data[4]) return 1;//数据传输错误
        data=Data[0];//湿度保存在高八位
        data=data<<8;
        data=data|Data[2];//温度保存在低八位
        return data;
}
/**********************************************************************************************************************************************************/


/***************************************************主函数*************************************************************************************************/
#include "stm32f10x.h"

#include "delay.h"
#include "usart.h"

#include "gpio.h"
#include "dht11.h"
#include "led.h"

u8 Data[5];

int main(void)
{                                     
        u16 TEM,HUM,data=0;//温度 湿度 返回值          

        delay_init();                     //延时函数初始化          
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(115200);                 //串口初始化为 115200
        DQ_Init();//信号线初始化
         
        LED_Init();
         
        delay_ms(1000);
       
        while(1)
        {
                data=DHT11_Get_TandH();//获取温度值
                printf("%d",data);
                if(data==0)
                        printf("ERROR:CAN NOT FIND DHT11!\r\n\r\n");
                else if(data==1)
                        printf("ERROR:Transport Error!\r\n\r\n");
                else
                {
                        HUM=(data&0xff00)/0x100;
                        TEM=data&0xff;
                        printf("HUM=%d\r\nTEM=%d\r\n",HUM,TEM);
                }
                GPIO_SetBits(GPIOG,GPIO_Pin_11);//主机将信号线拉高
                delay_ms(1000);
        }
}

/*************************************************************************************************************************************************/
















正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

882

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3071
金钱
3071
注册时间
2018-2-7
在线时间
285 小时
发表于 2018-3-24 14:02:49 | 显示全部楼层
延时时间估计不对,有示波器的话可以用示波器看看延时时间对不对。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 04:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表