60.png
61.png
简单的说明(来自数据手册)
62.png

63.png
信号说明 很好理解就是通过计算高电平时间判断0和1 这里的时间要求还是挺精确的所以为开一个定时器专门用于这玩意,当然,不用定时器也能做。
65.png
66.png

在cubemx配置好一个定时器(图上是32M的单片机,配置出来就是一个10uS的中断)
67.png
68.png

配置好引脚 然后就可以开始写代码了:

long tim_time=0;                        //計時用的

struct                            
{
    unsigned char rh;        //濕度整數
    unsigned char rhdot;            //濕度小數
    unsigned char t;            //溫度整數
    unsigned char tdot;        //溫度小數
    unsigned char sum;        //用於驗證數據是否正確的
}dh11;    

定义一些变量,读取到的数据就放这

HAL_TIM_Base_Start_IT(&htim6);

注意!在初始化的时候一定要加上这一句!定时器才工作

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//10us
{    
    if (htim == (&htim6))
        {
            tim_time+=1;
        }    
}

中断服务函数,每10us进一次

#define set_dh11_pin(x)   HAL_GPIO_WritePin(dht11_GPIO_Port, dht11_Pin, x)  //設置引腳電平
#define read_dh11_pin    HAL_GPIO_ReadPin(dht11_GPIO_Port, dht11_Pin)       //讀取引腳電平

void dht11_in_or_out(char a)//0in  1out                                //設置引腳輸入輸出
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = dht11_Pin;
    if(a==0)
    {
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    }
    if(a==1)
    {
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    }
    HAL_GPIO_Init(dht11_GPIO_Port, &GPIO_InitStruct);
}

引脚的操作 准备工作已经完成,开始写驱动:(注意:一定先左移数据再进行或操作,否则数据最后会整体左移1位)

char get_dht11_data2() //返回1讀取成功,0失敗
{
    char b;
    long long_time=0;
    dht11_in_or_out(1);            //引腳設置為輸出
    set_dh11_pin(0);            //下拉引腳 使模塊進入高速模式
    HAL_Delay(20);                //數據手冊說明需要延時20ms
    set_dh11_pin(1);            //拉高引腳
    dht11_in_or_out(0);            //設置為輸入 開始接收數據
    long_time=HAL_GetTick()+10;        //設置10ms內完成讀取  否則超時報錯

    while(read_dh11_pin==1){if(HAL_GetTick()>long_time){return 0;}}     //等待模塊返回一個下降沿  如果等待超時會直接彈出函數 返回0
    while(read_dh11_pin==0){if(HAL_GetTick()>long_time){return 0;}}        //第一個數據是模塊的開始傳輸標誌  這個數據直接略過
    tim_time=0;
    while(read_dh11_pin==1){if(HAL_GetTick()>long_time){return 0;}}
    for(b=0;b<8;b++)                            //正式開始接收數據一共5個字節 第一個數據 8位
    {
        while(read_dh11_pin==0){if(HAL_GetTick()>long_time){return 0;}}    //等待總線被拉高
        tim_time=0;                                    //計時開始
        while(read_dh11_pin==1){if(HAL_GetTick()>long_time){return 0;}}    //總線被拉低
        dh11.rh<<=1;                            //先高位 所以向左移(就是这里,先左移)動
        if(tim_time>4)                            //讀取時間 如果時間大於40us 
        {
        dh11.rh|=0x01;                                //說明這一位數據是1  給到最低位(再或操作)
        }

    }
    for(b=0;b<8;b++)
    {
        while(read_dh11_pin==0){if(HAL_GetTick()>long_time){return 0;}}
        tim_time=0;
        while(read_dh11_pin==1){if(HAL_GetTick()>long_time){return 0;}}
            dh11.rhdot<<=1;
        if(tim_time>4)
            {
        dh11.rhdot|=0x01;
        }

    }
    for(b=0;b<8;b++)
    {
        while(read_dh11_pin==0){if(HAL_GetTick()>long_time){return 0;}}
        tim_time=0;
        while(read_dh11_pin==1){if(HAL_GetTick()>long_time){return 0;}}
            dh11.t<<=1;
        if(tim_time>4)
        {
        dh11.t|=0x01;
        }

    }
    for(b=0;b<8;b++)
    {
        while(read_dh11_pin==0){if(HAL_GetTick()>long_time){return 0;}}
        tim_time=0;
        while(read_dh11_pin==1){if(HAL_GetTick()>long_time){return 0;}}
            dh11.tdot<<=1;
        if(tim_time>4)
        {
        dh11.tdot|=0x01;
        }

        }
    for(b=0;b<8;b++)        //接收最後一個數據  這個是驗證字節
    {
        while(read_dh11_pin==0){if(HAL_GetTick()>long_time){return 0;}}
        tim_time=0;
        while(read_dh11_pin==1){if(HAL_GetTick()>long_time){return 0;}}
            dh11.sum<<=1;    
        if(tim_time>4)
        {
        dh11.sum|=0x01;
        }

    }
    if(dh11.sum==dh11.rh+dh11.rhdot+dh11.t+dh11.tdot)//根據數據手冊  最後一個字節如果等於前四個字節相加,數據就是正確的
    {
        return 1;
    }    
    return 0;
}

最后使用方法:

每1.5S调用一次上面的函数char get_dht11_data2()

如果返回1

进行数据处理

float rh,temp;
temp=dh11.t+(float)dh11.tdot/10;//温度最终结果
rh=dh11.rh+(float)dh11.rhdot/10;//湿度最终结果

69.png

最后修改:2020 年 06 月 28 日
声明:无闻风博客|版权所有,违者必究|如未注明,均为原创| 转载:转载请注明原文链接