娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

基于stm32的多功能時鐘2——DHT11測量溫濕度

發布者:SparklingSun最新更新時間:2025-01-14 來源: jianshu關鍵字:stm32  多功能時鐘  DHT11 手機看文章 掃描二維碼
隨時隨地手機看文章

1.模塊介紹

DHT11溫濕度傳感器

        DHT11溫濕度傳感器是數字式的,包括1個電阻式感濕元件和1個NTC測溫元件,內部自帶AD轉換功能,采用單總線,具有響應快、抗干擾能力強、性價比高等特點。該模塊總共4個引腳,其中兩個是電源引腳VCC和GND,一個是數據引腳,還有一個為空引腳。

DHT11外部引腳

        目前流行的數據傳輸總線有II2C總線,SPI總線,單總線等,而DHT11則采用單總線傳輸數據。單總線,顧名思義,就是采用單根信號線,即可傳輸時鐘,又能傳輸數據,而且數據傳輸是雙向的,從而有主機和從機之別。在這里,stm32作為核心控制器,所以是主機,而DHT11為從機。           采用單總線進行數據傳輸,我們需要查看數據手冊的時序圖。                                                     

DHT11時序圖

        總線空閑狀態為高電平,主機把總線拉低等待 DHT11 響應,主機把總線拉低必須大于 18 毫秒,保證 DHT11 能檢測到起始信號。DHT11 接收到主機的開始信號后, 等待主機開始信號結束,然后發送 80us 低電平響應信號.主機發送開始信號結束后,延時等待 20-40us 后, 讀取 DHT11 的響應信號,主機發送開始信號后,可以切換到輸入模式,或者輸出高電平均可, 總線由上拉電阻拉高。

DHT11啟動轉換時序圖

        根據時序圖,單片機需要先將總線拉低至少18ms,然后拉高總線20~40us,此時主機的開始信號結束,檢測DHT11的響應信號。如果檢測到低電平,則DHT11響應,并且低電平時間維持80us,然后DHT11拉高總線80us。此時DHT11準備傳輸數據,傳輸的數據間隙為50us低電平,傳輸的數據通過高電平的時間長短來區分'0'和'1'。數據傳輸完畢,DHT11將總線拉低50us,最后主機再拉高總線。

數據'0'

數據'1'

2.軟件編程

(1)編寫延時函數

        由于DHT11的時序比較嚴格,需要毫秒級別和微妙級別的延時。這里我們采用Systick去做延時。在之前按鍵掃描函數里也用到延時的,在此我敘述一下。

        我們需要配置系統時鐘,然后把Systick設置成72,這樣就能產生1us時間基準,其次編寫Systick中斷處理函數,讓變量自減,從而達到延時的效果,最后編寫延時函數,也就是對自減的變量賦初始值。

__IO uint32_t TimingDelay;

/*配置SysTick函數*/

void systick_init(void)

{

    /*配置Systick重載值,系統時鐘為72MHz*/

    /*設置72,中斷時間:72*(1/72000000) = 1us*/

    if(SysTick_Config(72)==1)    //若SysTick_Config函數返回產生中斷信號,返回值為0

    {

        while(1);                   //SysTick_Config函數返回值為1,則等待

    }

}

/*時間變量自減函數*/

void TimingDelay_Decrement(void)

{

    if(TimingDelay!=0x00)

    {

        TimingDelay--;

    }

}

/*SysTick中斷處理函數*/

void SysTick_Handler(void)

{

    TimingDelay_Decrement();

}

/*延時函數,時間基準為1ms*/

void delay_ms(__IO uint32_t nTime)

{

    TimingDelay = nTime*1000;

    while(TimingDelay!=0);

}

/*延時函數,時間基準為1us*/

void delay_us(__IO uint32_t nTime)

{

    TimingDelay = nTime;

    while(TimingDelay!=0);

}

(2)配置相應的GPIO口作為單總線數據端

/*配置DHT11數據引腳,設置成浮空輸入模式*/

void dht11_gpio_portIn(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/*配置DHT11數據引腳,設置成推挽輸出模式*/

void dht11_gpio_portOut(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

}

        由于DHT11采用單總線通信協議,所以數據傳輸是雙向的,所以分別將數據端口設置成浮空輸入模式和推挽輸出模式。并且將數據口的輸入和輸出定義成宏定義的形式。

#define DHT11_OUT_H GPIO_SetBits(GPIOA, GPIO_Pin_4)

#define DHT11_OUT_L GPIO_ResetBits(GPIOA, GPIO_Pin_4)

#define DHT11_IN    GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_4)

(3)根據DHT11時序圖,編寫時序函數

        現在,我們開始編寫總線的驅動函數,根據時序圖,主機發送命令啟動轉換,接著,等待DHT11轉換響應并且輸出數據,最后讀取數據。

/*啟動總線函數*/

void dht11_reset(void)

{

    dht11_gpio_portOut();         //設置成輸出模式

    DHT11_OUT_L;                  //主機將總線拉低至少18ms

    delay_ms(18);

    DHT11_OUT_H;                  //主機拉高保持20~40us

    delay_us(30);

    dht11_gpio_portIn();          //設置成輸入模式,等待DHT11響應

}

/*DHT11響應函數*/

u8 dht11_scan(void)

{

    return DHT11_IN;              //返回值為DHT11的響應信號

}

實時監控DHT11的數據線,直至其產生出低電平,表示DHT11響應主機請求,開始傳輸數據。

/*DHT11讀取位函數*/

u8 dht11_read_bit(void)

{

    while(DHT11_IN==RESET);             //傳輸數據位前存在50us低電平   

    delay_us(40);                       //根據高電平的時間長短決定電平是1還是0

    if(DHT11_IN==SET)                   //'0'電平持續時間為26~28us,'1'電平持續時間為70us

    {

        while(DHT11_IN==SET);

        return 1;                       //若檢測到高電平,返回值為1

    }

    else

    {

        return 0;                       //若檢測到高電平,返回值為0

    }

}

/*DHT11讀取字節函數*/

//注:數據最高位先傳輸

u8 dht11_read_byte(void)

{

    u8 i,dat = 0x00;

    for(i=0; i<8; i++)

    {

        dat = dat<<1;

        dat = dat|dht11_read_bit();//將串行數據讀取出來

    }

    return dat;

}

        當DHT11響應后,就開始通過單總線傳輸數據,在讀取位函數里,通過高電平的時間長短來判斷輸出的是'1'還是'0',在讀取字節函數里,調用讀取位函數,將傳輸的每8位整合出字節,并讀取出來。

        我們查閱DHT11數據手冊,得知數據傳輸的結構(依次順序):濕度整數部分(1字節)、濕度小數部分(1字節)、溫度整數部分(1字節)、溫度小數部分(1字節)、校驗和(1字節)。這里,其實就是一個簡單的通信協議。校驗和就是源數據所有字節之和的低8位,確保傳輸數據的正確與穩定。

/*DHT11讀取數據函數*/

u8 dht11_read_data(void)

{

    u8 i;

    dht11_reset();

    if(dht11_scan()==RESET)             //DHT11發出響應信號

    {

        while(DHT11_IN==RESET);         //DHT11拉低總線80us

        while(DHT11_IN!=RESET);         //DHT11拉高總線80us

        for(i=0; i<5; i++)

        {

            buffer[i] = dht11_read_byte();

        }

        while(DHT11_IN==RESET);         //發送完最后1bit數據后,等待50us低電平結束

        dht11_gpio_portOut();

        DHT11_OUT_H;                    //主機拉高總線

        if(buffer[0]+buffer[1]+buffer[2]+buffer[3]==buffer[4])

        {

            return 1;                   //校驗成功

        }

        else

        {

            return 0;                   //校驗失敗

        }

    }

    else

    {

        return 0;                       //DHT11未發出響應信號

    }

}

        在讀取字節里,先等待DHT11響應,然后開始接收數據,并且連續讀取5次,存放在事先定義好的數組里,主機發出結束信號,最后對讀取的數據進行校驗。

(4)測量顯示溫濕度

主函數調用DHT11讀數據函數,并調用lcd顯示函數,將溫度和濕度顯示出來即可。

        if(dht11_read_data()==1)//讀取數據,前提是DHT11響應,并且數據校驗成功

        {

            humidity = buffer[0];//buffer[0]存放的是濕度整數部分

            temperature = buffer[2];//buffer[2]存放的是溫度整數部分

        }

        lcd_display_string(2,0,'溫度');

        lcd_display_num_m(2,32,temperature/10);

        lcd_display_num_m(2,40,temperature%10);

        lcd_display_string(4,0,“濕度”);

        lcd_display_num_m(4,32,humidity/10);

        lcd_display_num_m(4,40,humidity%10);

DHT11測量溫濕度

        至此,通過本章的講解,我相信,大家應該對于DHT11模塊有了大致的了解,當然,如果你只是看看文章的話,可能效果不怎么理想。這些東西,都需要親自動手的,正所謂'實踐出真知'。所以,你可以在網上買開發板,再買一些模塊,不一定要和我的一樣。當然,想要挑戰自己的話,可以買塊最小系統板,這樣,外圍的硬件電路可以由自己搭建(功能自定義),靈活性強的同時,也鍛煉了自己的動手能力。如果你是會設計PCB的大佬,那更好,估計你的水平,就瀏覽一下我的文章即可。


關鍵字:stm32  多功能時鐘  DHT11 引用地址:基于stm32的多功能時鐘2——DHT11測量溫濕度

上一篇:零基礎入門stm32選擇最多的stm32f103中斷學習總結
下一篇:STM32串口打印亂碼

0
添点儿料...
无论热点新闻、行业分析、技术干货……
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 峨山| 伊宁市| 韶山市| 横山县| 皮山县| 鄂伦春自治旗| 衡阳市| 台中市| 嘉鱼县| 本溪市| 确山县| 图木舒克市| 永靖县| 龙海市| 巩留县| 中西区| 手游| 阜宁县| 雷山县| 九龙城区| 和顺县| 内江市| 同仁县| 临猗县| 奉化市| 秭归县| 息烽县| 乌兰县| 教育| 航空| 民乐县| 嘉峪关市| 安新县| SHOW| 甘德县| 新龙县| 甘孜县| 安阳市| 枝江市| 黑龙江省| 仙游县|