国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FPGA—DHT11數(shù)字溫濕度傳感器

這篇具有很好參考價值的文章主要介紹了FPGA—DHT11數(shù)字溫濕度傳感器。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

1. 理論學(xué)習(xí)

2.實操

2.1 頂層模塊

2.1.1 整體模塊框圖

2.1.2 頂層代碼

2.2?DHT11 控制模塊

2.2.1 模塊框圖

2.2.2 狀態(tài)轉(zhuǎn)換圖繪制

2.2.3?波形圖繪制

2.2.4?RTL代碼

2.3?上板驗證

3. 總結(jié)

1. 理論學(xué)習(xí)

DHT11簡介

? ? ? ?DHT11數(shù)字溫濕度傳感器是一款含有已校準數(shù)字信號輸出的溫濕度復(fù)合傳感器。它應(yīng)用專用的數(shù)字模塊采集技術(shù)和溫濕度傳感技術(shù),確保產(chǎn)品具有 具有成本低、抗干擾力強、長期穩(wěn)定等優(yōu)點。

FPGA—DHT11數(shù)字溫濕度傳感器

?實物圖

? ? ?如上圖為DHT11的實物圖,有四個引腳,各引腳說明如下表格所示:

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ??DHT11的性能參數(shù):

? ? ? 濕度的量程為 5%RH—95%RH,誤差為±5%RH。溫度的量程為-20℃—60℃,誤差為±2℃。需要注意的是采樣周期要大于2S/次,也就是要大于 2S 才能讀取一次溫濕度。

? ?DHT11通信方式

1.單總線說明

? ? ? DHT11器件采用簡化的單總線通信。單總線即只有一根數(shù)據(jù)線,系統(tǒng)中的數(shù)據(jù)交換、控制均由單總線完成。設(shè)備(主機或從機)通過一個漏極開路或三態(tài)端口連至該數(shù)據(jù)線,以允許設(shè)備在不發(fā)送數(shù)據(jù)時能夠釋放總線。,F(xiàn)PGA與傳感器是主從結(jié)構(gòu)只有主機呼叫從機時,從機才能應(yīng)答,因此主機訪問器件都必須嚴格遵循單總線序列。

2.單總線傳送數(shù)據(jù)位定義

? ? ??主機與 DHT11 之間的通訊和同步采用單總線數(shù)據(jù)格式,一次傳送 40 位數(shù)據(jù),高位先出

? ? ? ?數(shù)據(jù)格式為: 8bit 濕度整數(shù)數(shù)據(jù)+8bit 濕度小數(shù)數(shù)據(jù)+8bit 溫度整數(shù)數(shù)據(jù)+8bit 溫度小數(shù)數(shù)據(jù)+8bit 校驗位。(其中濕度小數(shù)部分為 0)

? ? ? ?校驗位數(shù)據(jù)定義: “8bit 濕度整數(shù)數(shù)據(jù)+8bit 濕度小數(shù)數(shù)據(jù)+8bit 溫度整數(shù)數(shù)據(jù)+8bit 溫度小數(shù)數(shù)據(jù)”8bit 校驗位等于所得結(jié)果的末 8 位。

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ? ? 如上圖所示為各個信號的定義圖。首先濕度的小數(shù)部分為 0,所以輸出的濕度為整數(shù)。而溫度數(shù)據(jù)是可以顯示小數(shù)部分的,如:接收到的 40位數(shù)據(jù)為: 00110101(濕度高八位) +00000000(濕度低八位) +00011000(溫度高八位)+00000100(溫度低八位) +010110001(校驗位)。通過計算: 00110101+00000000+00011000+00000100=01010001 與校驗位相同,結(jié)果正確。所以其濕度溫度分別為:
濕度=整數(shù)+小數(shù)=00110101+0=35H=53.0%RH
溫度=整數(shù)+小數(shù)=00011000+00000100=18H+04H=24℃+0.4℃=24.4℃。

? ? ? 需注意濕度是沒有負數(shù)的,但是溫度有。溫度的高八位與低八位的最高位都為符號位,不計入校驗和中。經(jīng)實際的測量發(fā)現(xiàn),目前 DHT11 溫度只能精確到0.1℃,我們應(yīng)用時用小數(shù)數(shù)據(jù)的低四位來表示溫度的小數(shù)值即可。

3. 數(shù)據(jù)時序圖

? ? ? ?主機發(fā)送一次開始信號后, DHT11 從低功耗模式轉(zhuǎn)換到高速模式,待主機發(fā)送的開始信號結(jié)束后, DHT11 發(fā)送響應(yīng)信號,送出 40bit 的數(shù)據(jù)。信號發(fā)送如下圖所示:

FPGA—DHT11數(shù)字溫濕度傳感器

主機讀取 DHT11 溫濕度數(shù)據(jù)的步驟:

step1: DHT11準備狀態(tài)

? ? ?DHT11 上電后(DHT11 上電后要等待 1S 以越過不穩(wěn)定狀態(tài)在此期間不能發(fā)送任何指令),測試環(huán)境溫濕度數(shù)據(jù),并記錄數(shù)據(jù),同時 DHT11 的 DATA 數(shù)據(jù)線由上拉電阻拉高一直保持高電平;此時 DHT11 的單總線引腳處于輸入狀態(tài),時刻檢測外部信號。

step2: 主機發(fā)送開始信號,傳感器發(fā)出應(yīng)答信號

? ? ? 主機發(fā)送開始信號輸出低電平,持續(xù)時間不小于 18ms 且不超過 30ms。發(fā)送完之后釋放總線等待 DHT11 應(yīng)答。起始信號時序圖如下。

? ? ? DHT11 的 DATA 引腳檢測到外部信號有低電平時,等待外部信號低電平結(jié)束,延遲后DHT11 的 DATA 引腳輸出 83us 的低電平作為應(yīng)答信號,緊接著輸出 87us 的高電平通知外設(shè)準備接收數(shù)據(jù)。DHT11 響應(yīng)信號時序圖如下。

FPGA—DHT11數(shù)字溫濕度傳感器step3: 傳送數(shù)據(jù)位

40位數(shù)據(jù)位:

? ? ? ?由 DHT11 的 DATA 引腳輸出 40 位數(shù)據(jù), 主機根據(jù) I/O 電平的變化接收 40 位數(shù)據(jù),位數(shù)據(jù) “0” 的格式為: 54us 的低電平后 23~27us 的高電平,位數(shù)據(jù) “1” 的格式為: 54us 的低電平后68~74us 的高電平。位數(shù)據(jù)“0”、 “1”格式信號如下圖所示:

FPGA—DHT11數(shù)字溫濕度傳感器

結(jié)束信號:
? ? ? ? DHT11 的 DATA 引腳輸出 40 位數(shù)據(jù)后,繼續(xù)輸出低電平 54us 后轉(zhuǎn)為輸入狀態(tài),由上拉電阻變?yōu)楦唠娖?,又開始再一次檢測,等待開始信號的到來。

2.實操

? ? ? ?實驗?zāi)繕耍嚎刂艱HT11,讀出濕度溫度數(shù)據(jù)并顯示在數(shù)碼管中,通過按鍵使?jié)穸群蜏囟仍跀?shù)碼管中切換顯示。

硬件資源:

? ? ??需使用到開發(fā)板上的按鍵、數(shù)碼管及 DHT11 接口,其中按鍵和數(shù)碼管硬件資源之前說過不再詳細說明。

FPGA—DHT11數(shù)字溫濕度傳感器

?DHT11 接口

FPGA—DHT11數(shù)字溫濕度傳感器

?DHT11 接口原理圖

? ? ? 其接線圖和原理圖如上圖所示,該接口是單總線接口,之前也接過DS18B20(溫度傳感器),兩者相似。

2.1 頂層模塊

2.1.1 整體模塊框圖

FPGA—DHT11數(shù)字溫濕度傳感器

?DHT11 溫濕度顯示實驗整體框圖

? ? ? ?通過上圖可以看到,該工程共分四個模塊。各模塊簡介見下表。

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ? 其中按鍵消抖模塊和數(shù)碼管動態(tài)顯示模塊已經(jīng)有學(xué)習(xí)過,直接調(diào)用其模塊。重點是學(xué)習(xí)DHT11 控制模塊。

2.1.2 頂層代碼

`timescale  1ns/1ns

module  dht11
(
    input   wire    sys_clk     ,  
    input   wire    sys_rst_n   ,  
    input   wire    key_in      ,   //按鍵信號

    inout   wire    dht11       ,   //數(shù)據(jù)總線
    output  wire    [5:0]   sel,    //數(shù)碼管位選信號
    output  wire    [7:0]   seg    //數(shù)碼管段選信號
    );

wire    [19:0]  data_out;   //需要顯示的數(shù)據(jù)
wire            key_flag;   //按鍵消抖后輸出信號
wire            sign    ;   //輸出符號

dht11_ctrl  dht11_ctrl_inst
(
    .sys_clk     (sys_clk  ),   
    .sys_rst_n   (sys_rst_n),   
    .key_flag    (key_flag ),   

    .dht11       (dht11    ),   

    .data_out    (data_out ),   
    .sign        (sign     )    
);

key_filter  key_filter_inst
(
    .sys_clk      (sys_clk  )   , 
    .sys_rst_n    (sys_rst_n)   , 
    .key_in       (key_in   )   , 

    .key_flag     (key_flag )     

);

seg_dynamic seg_dynamic_inst
(
    .sys_clk     (sys_clk  ),
    .sys_rst_n   (sys_rst_n),
    .data        (data_out ), //數(shù)碼管要顯示的值
    .point       (6'b000010), //小數(shù)點顯示,高電平有效
    .seg_en      (1'b1     ), //數(shù)碼管使能信號,高電平有效
    .sign        (sign     ), //符號位,高電平顯示負號

    .sel         (sel      ),   //數(shù)碼管位選信號
    .seg         (seg      )    //數(shù)碼管段選信號

);
endmodule

2.2?DHT11 控制模塊

2.2.1 模塊框圖

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ? 模塊作用是將實時的環(huán)境濕度,溫度轉(zhuǎn)換出來,然后將轉(zhuǎn)換出來的溫濕度讀出來,通過按鍵切換顯示在數(shù)碼管上。

2.2.2 狀態(tài)轉(zhuǎn)換圖繪制

? ? ? ?根據(jù) DHT11 的數(shù)據(jù)時序圖可以畫出狀態(tài)跳轉(zhuǎn)圖來進一步了解如何控制 DHT11,以及讀出 DHT11 的濕度溫度值。

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ? ? ?各個狀態(tài)的時間以下表提供的范圍進行設(shè)計。
FPGA—DHT11數(shù)字溫濕度傳感器

2.2.3?波形圖繪制

1. 產(chǎn)生單位時鐘為 1us 的時鐘

? ? ??在整個時序過程中無論是發(fā)送開始信號,還是“1”,“0”的時序組成我們都需要用到時間信號,而這些時間信號的最小單位為 us,所以我們先產(chǎn)生單位時鐘為 1us 的時鐘來作為 DHT11 的控制時鐘。如下波形圖所示,產(chǎn)生方法為分頻法。

FPGA—DHT11數(shù)字溫濕度傳感器

2.? 提取dht11信號的上升沿和下降沿

? ? ? 直接對dht11信號延時兩拍。

3. 處理dht11信號

? ? ? ?dht11:單總線,其類型為輸入輸出型,定義為 wire 型變量,所以我們將借助dht11_out(總線輸入)和 dht11_en(總線使能信號)來給 dht11 賦值。由時序圖可知,只需要控制總線發(fā)送開始信號( 18ms 的低電平),其他狀態(tài)釋放即可。如圖中的dht11_out 與 dht11_en 信號所示,當 dht11_en 信號為 1 時 dht11 的值等于 dht11_out 的值(輸出),當 dht11_en 為 0 時釋放總線(輸入)。?

FPGA—DHT11數(shù)字溫濕度傳感器

4. 各個狀態(tài)間的跳轉(zhuǎn)?

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ? ?state:狀態(tài)機的狀態(tài)。初始狀態(tài)為 S_WAIT_1S,上電后需要等待 1S 以越過不穩(wěn)定狀態(tài)。所以我們需要一個計數(shù)器(cnt_us)去進行產(chǎn)生 1S 的時間信號。當計數(shù)器計到 1S 時跳到下一個狀態(tài)。
? ? ? ?S_LOW_18MS:發(fā)送開始信號狀態(tài)。開始信號是由 18ms 的低電平組成,又需要用到計器,而且在發(fā)送時需要從 0 開始計數(shù)。當計數(shù)器計到 18ms 時(0-17999),狀態(tài)機跳轉(zhuǎn)計數(shù)器清零。
? ? ? ?S_DLY1:拉高等待狀態(tài)。等待 10us 后跳轉(zhuǎn)到下一狀態(tài),等待回應(yīng)信號的到來。

? ? ? ?S_REPLY: DHT11 回應(yīng)狀態(tài)(DHT11 響應(yīng)低電平 81~85us)。跳到這個狀態(tài)后計數(shù)器開始持續(xù)計數(shù),但是此無法判斷有沒有此時回應(yīng)信號開始發(fā)送。需要一個新的計數(shù)器( cnt_low)進行對響應(yīng)信號計數(shù),當檢測到 dht11 為低電平時,說明響應(yīng)信號開始發(fā)送了,我們就可以讓 cnt_low 計數(shù)器開始計數(shù)。同時 dht11 的上升沿到來時說明響應(yīng)信號發(fā)送完畢。響應(yīng)這個值協(xié)議 規(guī)定為81~85us是可以視情況而設(shè),將范圍改大如 70us 可使有些沒有嚴格按照協(xié)議發(fā)送的 DHT11 也可以兼容。

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ??若在這個狀態(tài)一直沒有檢測到響應(yīng)信號,則在 cnt_us 計到 1ms 時跳回S_LOW_18MS 狀態(tài),重新發(fā)送開始信號(這里應(yīng)該是要滿足最小測量時間2s左右的特點),波形圖如上圖所示。

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ? S_DLY2: DHT11 拉高等待輸出狀態(tài)。當下降沿到來時,若此時的值滿足其發(fā)送時間則跳轉(zhuǎn)到下一狀態(tài)。

5. 數(shù)據(jù)處理
? ? ? S_RD_DATA: DHT11 輸出數(shù)據(jù)狀態(tài)。從時序圖可以看到,數(shù)據(jù)“ 0”和數(shù)據(jù)“1”的時序都是由低電平開始的,而且持續(xù)時間相同,不同的地方在于高電平的持續(xù)時間。所以只需要判斷高電平的持續(xù)時間即可判斷其輸出的是 0 還是 1。當上升沿到來時計數(shù)器清零開始計數(shù),當下降沿到來時說明 1bit 的數(shù)據(jù)發(fā)送完畢,此時對計數(shù)器采樣。我們知道數(shù)據(jù)“0”是維持 23-27us 的高電平,數(shù)據(jù)“1”是維持 68-74us 的高電平。我們取一個中間值(50us)去判斷輸出的是“0”還是“1”,若下降沿到來 cnt_us 小于等于 50 則判斷為0,若大于 50 則判斷為 1。

? ? ? BIT_CNT:判斷傳輸了采了幾個數(shù)據(jù)。其初始值為 0,當下降沿到來時 bit_cnt 加 1,當其加到 39 時說明發(fā)送到了最后一個數(shù)據(jù)。所以當其為 40 的時候表示數(shù)據(jù)發(fā)送完畢,同時 dht11 會發(fā)送結(jié)束信號(拉低一段時間)。當 dht11 上升沿到來時表示整個時序結(jié)束。狀態(tài)跳回 S_LOW_18MS狀態(tài)發(fā)送開始信號開始新一輪的數(shù)據(jù)讀取,同時 bit_cnt 清零。

FPGA—DHT11數(shù)字溫濕度傳感器

? ? ? ??上圖為數(shù)據(jù)采集波形圖。當在 S_RD_DATA 狀態(tài)時,每來一個下降沿,采集一次數(shù)據(jù)。因為數(shù)據(jù)是從高位開始發(fā)送的 ,所以第一個采集的數(shù)據(jù)放在數(shù)據(jù)寄存器(data_tmp)的最高位即 data_tmp[39],依次類推最后一位放在最低位即 data_tmp[0]??梢钥吹较陆笛貭顟B(tài)到來時 bit_cnt 的值應(yīng)為上一狀態(tài)的值,所以 bit_cnt 與寄存器賦值位數(shù)的關(guān)系為 data_tmp[39-bit_cnt]。當 40 位數(shù)據(jù)發(fā)送完之后發(fā)現(xiàn)檢驗位與“ 8bit 濕度整數(shù)數(shù)據(jù)+8bit 濕度小數(shù)數(shù)據(jù)+8bit 溫度整數(shù)數(shù)據(jù)+8bit 溫度小數(shù)數(shù)據(jù)”所得結(jié)果的末 8 位相等時,則將濕度溫度數(shù)據(jù)值賦給 data。

FPGA—DHT11數(shù)字溫濕度傳感器

6.數(shù)據(jù)切換

? ? ? 當按鍵按下時, data_flag 取反為 1,此時顯示的是溫度值,溫度小數(shù)部分用低四位計算即可;按鍵沒有按下data_flag 為 0,此時顯示的是濕度值,無小數(shù)部分,顯示在第二第三個數(shù)碼管,而第二三個數(shù)碼管顯示的是十分位和百分位,所以讀出的整數(shù)值要乘以 10。

? ? ? 需要注意的是應(yīng)使用系統(tǒng)時鐘對 key_flag 進行采樣,而不能使用 clk_1us,因為我們產(chǎn)生 key_flag 用的是系統(tǒng)時鐘,而且 key_flag只維持了一個系統(tǒng)時鐘的高電平,所以如果用分頻的時鐘去采的話是幾乎采不到這個信號的。

2.2.4?RTL代碼

`timescale  1ns/1ns

module  dht11_ctrl
(
    input   wire        sys_clk     ,   
    input   wire        sys_rst_n   ,   
    input   wire        key_flag    ,   //按鍵消抖后標志信號

    inout   wire        dht11       ,   //控制總線,采用wire型

    output  reg [19:0]  data_out    ,   //輸出顯示的數(shù)據(jù)
    output  reg         sign            //輸出符號位,高電平顯示負號

);

parameter   S_WAIT_1S  = 3'd1   ,   //上電等待1s狀態(tài)
            S_LOW_18MS = 3'd2   ,   //主機拉低18ms,發(fā)送開始信號狀態(tài)
            S_DLY1     = 3'd3   ,   //等待20-40us狀態(tài)
            S_REPLY    = 3'd4   ,   //DHT11響應(yīng)80us狀態(tài)
            S_DLY2     = 3'd5   ,   //拉高等待80us狀態(tài)
            S_RD_DATA  = 3'd6   ;   //接收數(shù)據(jù)狀態(tài)

parameter   T_1S_DATA    = 999999 ; //1s時間計數(shù)值
parameter   T_18MS_DATA  = 17999  ; //18ms時間計數(shù)值

reg         clk_1us     ;   //1us時鐘,用于驅(qū)動整個模塊
reg [4:0]   cnt         ;   //時鐘分頻計數(shù)器
reg [2:0]   state       ;   //狀態(tài)機狀態(tài)
reg [20:0]  cnt_us      ;   //us計數(shù)器
reg         dht11_out   ;   //總線輸出數(shù)據(jù)
reg         dht11_en    ;   //總線輸出使能信號
reg [5:0]   bit_cnt     ;   //字節(jié)計數(shù)器
reg [39:0]  data_tmp    ;   //讀出數(shù)據(jù)寄存器
reg         data_flag   ;   //數(shù)據(jù)切換標志信號
reg         dht11_d1    ;   //總線信號打一拍
reg         dht11_d2    ;   //總線信號打兩拍
reg [31:0]  data        ;   //校驗位數(shù)據(jù)
reg [6:0]   cnt_low     ;   //低電平計數(shù)器

wire            dht11_fall; //總線下降沿
wire            dht11_rise; //總線上升沿

//cnt:分頻計數(shù)器
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt <=  5'b0;
    else    if(cnt == 5'd24)
        cnt <=  5'b0;
    else
        cnt <=  cnt + 1'b1;
//clk_1us:產(chǎn)生單位時鐘為1us的控制時鐘
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        clk_1us <=  1'b0;
    else    if(cnt == 5'd24)
        clk_1us <=  ~clk_1us;
    else
        clk_1us <=  clk_1us;
		
//檢測總線信號的上升沿下降沿
assign  dht11_rise =   (~dht11_d2) & (dht11_d1)    ;
assign  dht11_fall =   (dht11_d2)  & (~dht11_d1)   ;
//對dht11信號打拍
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            dht11_d1  <=  1'b0 ;
            dht11_d2  <=  1'b0 ;
        end
    else
        begin
            dht11_d1  <=  dht11    ;
            dht11_d2  <=  dht11_d1 ;
        end
		
//當使能信號為1是總線的值為dht11_out的值,為0時值為高阻態(tài)(釋放總線)
assign  dht11  =   (dht11_en == 1 ) ? dht11_out : 1'bz;

//狀態(tài)機狀態(tài)跳轉(zhuǎn)
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        state   <=  S_WAIT_1S   ;
    else
        case(state)
        S_WAIT_1S:
            if(cnt_us == T_1S_DATA) //上電1s后跳入起始狀態(tài)
                state   <=  S_LOW_18MS  ;
            else
                state   <=  S_WAIT_1S   ;
        S_LOW_18MS:
            if(cnt_us == T_18MS_DATA)
                state   <=  S_DLY1     ;
            else
                state   <=  S_LOW_18MS  ;
        S_DLY1:
            if(cnt_us == 10)    //等待10us后進入下一狀態(tài)
                state   <=  S_REPLY     ;
            else
                state   <=  S_DLY1     ;
        S_REPLY:  //上升沿到來且低電平保持時間大于70us,則跳轉(zhuǎn)到下一狀態(tài)
            if(dht11_rise == 1'b1 && cnt_low >= 70)
                state   <=  S_DLY2     ;
                 //若1ms后,dht11還沒響應(yīng),則回去繼續(xù)發(fā)送起始信號
            else    if(cnt_us >= 1000)
                state   <=  S_LOW_18MS ;
            else
                state   <=  S_REPLY    ;
        S_DLY2: //下降沿到來且計數(shù)器值大于70us,則跳轉(zhuǎn)到下一狀態(tài)
            if(dht11_fall == 1'b1 && cnt_us >= 70)
                state   <=  S_RD_DATA   ;
            else
                state       <=  S_DLY2  ;
        S_RD_DATA:  //讀完數(shù)據(jù)后,回到起始狀態(tài)
            if(bit_cnt == 40 && dht11_rise == 1'b1)  //結(jié)束位
                state   <=  S_LOW_18MS  ;
            else
                state   <=  S_RD_DATA   ;
        default:
                state   <=  S_WAIT_1S   ;
        endcase

//各狀態(tài)下的計數(shù)器賦值
//cnt_us:每到一個新的狀態(tài)就讓該計數(shù)器重新計數(shù)
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            cnt_low <=  7'd0      ;
            cnt_us   <=  21'd0    ;
        end
    else
        case(state)
        S_WAIT_1S:
            if(cnt_us == T_1S_DATA) 
                cnt_us   <=  21'd0  ;
            else
                cnt_us   <=  cnt_us + 1'b1;
        S_LOW_18MS:
            if(cnt_us == T_18MS_DATA)
                cnt_us   <=  21'd0  ;
            else
                cnt_us   <=  cnt_us + 1'b1;
        S_DLY1:
            if(cnt_us == 10)
                cnt_us   <=  21'd0  ;
            else
                cnt_us   <=  cnt_us + 1'b1;
        S_REPLY: 
		    if(dht11 == 1'b0) //當dht11發(fā)送低電平回應(yīng)時,計算其低電平的持續(xù)時間
                begin
                    cnt_low  <=  cnt_low + 1'b1 ;
                    cnt_us   <=  cnt_us + 1'b1  ;
                end
			else  if(dht11_rise == 1'b1 && cnt_low >= 70) //在規(guī)定范圍內(nèi)產(chǎn)生響應(yīng)
                begin
                    cnt_low <=  7'd0    ;
                    cnt_us   <=  21'd0  ;
                end
            else    if(cnt_us <= 1000)   //若1ms前,dht11沒響應(yīng)
                begin
                    cnt_low <=  cnt_low        ;
                    cnt_us  <=  cnt_us + 1'b1  ;
                end
            else     //若1ms后,dht11還沒響應(yīng),則回去繼續(xù)發(fā)送起始信號
				begin
                    cnt_low <=  7'd0   ;
                    cnt_us  <=  21'd0  ;
                end
        S_DLY2:
            if(dht11_fall == 1'b1 && cnt_us >= 70)
                cnt_us   <=  21'd0  ;
            else
                cnt_us   <=  cnt_us + 1'b1;
        S_RD_DATA:
            if(dht11_fall == 1'b1 || dht11_rise == 1'b1)
                cnt_us   <=  21'd0  ;
            else
                cnt_us   <=  cnt_us + 1'b1;
        default:
            begin
                cnt_low  <=  7'd0   ;
                cnt_us   <=  21'd0  ;
            end
        endcase

//各狀態(tài)下的單總線賦值
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
               dht11_out <=  1'b0    ;
               dht11_en  <=  1'b0    ;
        end
    else
        case(state)
        S_WAIT_1S:
                begin
                    dht11_out    <=  1'b0    ;
                    dht11_en     <=  1'b0    ;
                end
        S_LOW_18MS: //拉低總線18ms
                begin
                    dht11_out    <=  1'b0    ;
                    dht11_en     <=  1'b1    ;
                end
    //后面狀態(tài)釋放總線即可,由DHT11操控總線
        S_DLY1:
                begin
                    dht11_out    <=  1'b0    ;
                    dht11_en     <=  1'b0    ;
                end
        S_REPLY:
                begin
                    dht11_out    <=  1'b0    ;
                    dht11_en     <=  1'b0    ;
                end
        S_DLY2:
                begin
                    dht11_out    <=  1'b0    ;
                    dht11_en     <=  1'b0    ;
                end
        S_RD_DATA:
                begin
                    dht11_out    <=  1'b0    ;
                    dht11_en     <=  1'b0    ;
                end
        default:;
        endcase

//bit_cnt:讀出數(shù)據(jù)bit位數(shù)計數(shù)器
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        bit_cnt <=  6'b0;
    else    if(bit_cnt == 40 && dht11_rise == 1'b1)
        bit_cnt <=  6'b0;
    else    if(dht11_fall == 1'b1 && state == S_RD_DATA)
        bit_cnt <=  bit_cnt + 1'b1;	
//data_tmp:將讀出的數(shù)據(jù)寄存在data_tmp中
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_tmp    <=  40'b0;
    else    if(state == S_RD_DATA && dht11_fall == 1'b1 && cnt_us<=50)
        data_tmp[39-bit_cnt]   <=  1'b0;
    else    if(state == S_RD_DATA && dht11_fall == 1'b1 && cnt_us>50)
        data_tmp[39-bit_cnt]   <=  1'b1;
    else
        data_tmp    <=  data_tmp;
//data:校驗,若檢驗位正確,則數(shù)據(jù)值有效
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data    <=  32'b0;
    else    if(data_tmp[7:0] == data_tmp[39:32] + data_tmp[31:24] +
                                      data_tmp[23:16] + data_tmp[15:8])
        data    <=  data_tmp[39:8];   
     else
        data    <=  data;

//data_flag:數(shù)據(jù)變換標志信號的產(chǎn)生,按一次鍵變換一次  (系統(tǒng)時鐘)
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_flag   <=  1'b0;
    else    if(key_flag == 1'b1)
        data_flag   <=  ~data_flag;
    else
        data_flag   <=  data_flag;
//data_out:對數(shù)碼管顯示的濕度和溫度進行賦值
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_out    <=  20'b0;
    else    if(data_flag == 1'b0 ) //濕度小數(shù)位為0
        data_out    <=  data[31:24] * 10;  //為了兼容溫度顯示的小數(shù),將濕度的個
		                               //位與十位擴大10倍,小數(shù)位為零
    else    if(data_flag == 1'b1) //溫度低四位顯示溫度小數(shù)數(shù)據(jù)
        data_out    <=  data[15:8] * 10 + data[3:0];	
		
//sign:符號位的顯示
always@(posedge clk_1us or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        sign    <=  1'b0;
    else    if(data[7] == 1'b1 && data_flag == 1'b1)//當溫度低八位最高位為1時,顯示負號
        sign    <=  1'b1;
    else
        sign    <=  1'b0;
endmodule

2.3?上板驗證

當按鍵未被按下,濕度如下圖:

FPGA—DHT11數(shù)字溫濕度傳感器

當按鍵被按下,溫度如下圖:

FPGA—DHT11數(shù)字溫濕度傳感器

3. 總結(jié)

1. DH1T11溫濕度傳感器與DS18B20溫濕度傳感器非常類似,都是嚴格按照時序要求寫代碼。建議可以比較學(xué)習(xí)。

2. 顯示溫度與濕度部分的數(shù)據(jù)處理,采用 X10 進行在數(shù)碼管上的移一位顯示,配合了數(shù)碼管小數(shù)部分的顯示特點又區(qū)分了溫度與濕度。

3. 程序是按照一個接一個狀態(tài)及順序跳轉(zhuǎn)的,建議使用狀態(tài)機。

說明:

? ? ? ?本人使用的是野火家Xilinx Spartan6系列開發(fā)板及配套教程,以上內(nèi)容如有疑惑或錯誤歡迎評論區(qū)指出,或者移步B站觀看野火家視頻教程。

開發(fā)軟件:ise14.7? ? ?仿真:modelsim 10.5?

如需上述資料私信或留下郵箱文章來源地址http://www.zghlxwxcb.cn/news/detail-461701.html

到了這里,關(guān)于FPGA—DHT11數(shù)字溫濕度傳感器的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • DHT11溫濕度傳感器學(xué)習(xí)

    DHT11溫濕度傳感器學(xué)習(xí)

    ?DHT11溫濕度傳感器共有四個引腳 1個VCC高電平,1個GND接地低電平,1個數(shù)據(jù)輸出引腳,一個空引腳 工作時候,通過out引腳可以向傳感器傳遞應(yīng)答信號并返回40位的溫濕度數(shù)據(jù),也就是5個字節(jié) 前2個字節(jié)表示溫度的整數(shù)位和小數(shù)位,后面兩個字節(jié)是濕度的整數(shù)位和小數(shù)位,最后

    2024年02月07日
    瀏覽(96)
  • 溫濕度傳感器DHT11介紹

    溫濕度傳感器DHT11介紹

    溫濕度傳感器DHT11簡介 ? ? ? DHT11數(shù)字溫濕度傳感器是一種出廠時經(jīng)過校準的數(shù)字信號輸出的溫濕度數(shù)字溫濕度傳感器 。DHT11 數(shù)字溫濕度傳感器應(yīng)用溫濕度傳感技術(shù)和數(shù)字采集技術(shù),確保其具有極高的可靠性和卓越的長期穩(wěn)定性。 ? ? ? DHT11 數(shù)字溫濕度傳感器內(nèi)置一個電阻式

    2023年04月22日
    瀏覽(19)
  • 【mcuclub】溫濕度傳感器DHT11

    【mcuclub】溫濕度傳感器DHT11

    為什么接上拉電阻: 因為DHT11的數(shù)據(jù)口是漏極開路,如果不接上拉電阻,則只能輸出低電平和高阻態(tài),不能輸出高電平,因此需要外接上拉電阻,否則無法輸出1。DHT11的工作電流約為1mA,VCC一般為5V,則電阻R=5V/1mA=5KΩ。一般3.3k~10k都可以。 DHT11 數(shù)字溫濕度傳感器是一款含有已

    2024年02月06日
    瀏覽(87)
  • STM32+DHT11溫濕度傳感器

    STM32+DHT11溫濕度傳感器

    DATA 用于微處理器與 DHT11之間的通訊和同步,采用單總線數(shù)據(jù)格式,一次 通訊時間4ms左右,數(shù)據(jù)分小數(shù)部分和整數(shù)部分,具體格式在下面說明,當前小數(shù) 部分用于以后擴展,現(xiàn)讀出為零.操作流程如下: 一次完整的數(shù)據(jù)傳輸為40bit,高位先出。 數(shù)據(jù)格式:8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)

    2023年04月13日
    瀏覽(90)
  • STM32—DHT11溫濕度傳感器

    STM32—DHT11溫濕度傳感器

    (1).下圖一是DHT11總的時序圖。 (2).圖二對應(yīng)圖一的左邊黑色部分,圖三對應(yīng)圖一的綠色部分,圖四的左部分圖對應(yīng)圖一的紅色部分,圖四的右部分對應(yīng)圖一的黃色部分。 (3).首先圖二部分是單片機向DHT11發(fā)送我要開始的信號,此時單片機IO口處于輸出模式,輸出低電平至少18MS,

    2024年02月19日
    瀏覽(90)
  • STM32--DHT11溫濕度傳感器

    STM32--DHT11溫濕度傳感器

    本文介紹基于STM32F103實現(xiàn)的DHT11溫濕度傳感器數(shù)據(jù)采集及顯示,完整代碼見文末鏈接 一、DHT11傳感器簡介 DHT11數(shù)字溫濕度傳感器是一款含有已校準數(shù)字信號輸出的溫濕度復(fù)合傳感器。它應(yīng)用專用的數(shù)字模塊采集技術(shù)和溫濕度傳感技術(shù),確保產(chǎn)品具有極高的可靠性與卓越的長期

    2024年02月16日
    瀏覽(95)
  • CC2530——溫濕度傳感器DHT11

    CC2530——溫濕度傳感器DHT11

    DHT11是一款有已校準數(shù)字信號輸出的溫濕度傳感器。 其精度濕度±5%RH,溫度±2℃,量程濕度5~95%RH,溫度-20~+60℃。 ?1、用戶主機(單片機)發(fā)送一次開始信號后,DHT11從低功耗模式轉(zhuǎn)換到高速模式。 2、到主機開始信號結(jié)束后,DHT11發(fā)送響應(yīng)信號。 3、DHT11并送出40bit(5個字節(jié))

    2024年02月04日
    瀏覽(84)
  • 51單片機(DHT11溫濕度傳感器)

    51單片機(DHT11溫濕度傳感器)

    DHT11數(shù)字溫濕度傳感器是一款含有已校準數(shù)字信號輸出的溫濕度復(fù)合傳感器,應(yīng)用領(lǐng)域:暖通 空調(diào);汽車;消費品;氣象站;濕度調(diào)節(jié)器;除濕器;家電;醫(yī)療;自動控制 相對濕度和溫度測量 全部校準,數(shù)字輸出 長期穩(wěn)定性 超長的信號傳輸距離:20米 超低能耗:休眠 4 引腳

    2024年02月02日
    瀏覽(87)
  • stm32讀取DHT11溫濕度傳感器

    stm32讀取DHT11溫濕度傳感器

    我們知道DHT11是單總線協(xié)議,只有一根數(shù)據(jù)線。 且內(nèi)部有個上拉電路(下圖)。那么數(shù)據(jù)線默認就是高電平那接下來就可以講解主機如何和DHT11通訊的 讀取DHT11的芯片手冊,可以知道,DHT11一次完成的數(shù)據(jù)輸出是40bit,高位先出。 格式:8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù) +8bi溫

    2024年02月09日
    瀏覽(94)
  • stm32連接DHT11溫濕度傳感器

    stm32連接DHT11溫濕度傳感器

    目錄 1. DHT11簡介 1.1. 連接電路? 1.2. 串行接口 (單線雙向) ?2. cubeMX設(shè)置 3. 代碼開發(fā) ?3.1. 實現(xiàn)定時函數(shù) 3.2. 打開串口調(diào)試 3.4. 測試代碼實現(xiàn) 4. 運行效果 信息如下: 建議連接線長度短于20米時用5K上拉電阻,大于20米時根據(jù)實際情況使 用合適的上拉電阻 ?DHT11的供電電壓為 3-5

    2023年04月16日
    瀏覽(94)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包