一。介紹
本文是FPGA之旅設計的第十二個例子。在前麵的例子中,完成了DS18B20溫度傳感器的數據采集,並將采集到的數據顯示在數碼管上。由於本例將采集溫濕度傳感器DHT11,兩者的數據采集過程類似,可以參考前麵的例程。本例中會通過signal top實時采集波形,以確保采集到的數據正確(數據經過驗證)。
二。 DHT11傳感器簡介
應用電路如下。與DS18B20一樣,隻需要一根數據線即可與FPGA通信。每次通信均由FPGA發起,然後DHT11將輸出40位數據到FPGA。溫度測試範圍為0-50,濕度測試範圍為20-90%RH(相對濕度)。簡單看一下即可。
三。數據傳輸過程
數據傳輸由三部分組成:
開始收集。 FPGA將數據線拉低,然後釋放,等待DHT11響應。
數據采集: 該部分總共需要傳輸40 位數據,分別是(從高到低)8 位濕度整數位、8 位濕度小數位、8 位溫度整數位、8 位溫度小數位,和8位校驗和。校驗和=數據的和,通過它可以判斷接收到的數據是否正確。
采集結束:從機拉低後約50us,主機拉低
官方圖如下,下麵對各個部分進行詳細解釋。
1
開始收集
從圖中可以看出,啟動采集包括主機和從機兩部分。主機首先將總線拉低18ms,然後拉高20-40us,然後釋放總線。然後從機做出響應,將總線拉低80us,然後將總線拉高80us,就完成了。這裏的下拉和上拉時間不是固定值,可以根據實際情況確定。
2
數據傳輸
采集開始後,數據傳輸開始。對於總線來說最重要的問題是如何表示數據1和數據0。
數據0表示如下
數據1表示如下
可以看出,無論是數據0還是數據1,總線被拉低的時間都是相同的,所以判斷數據0和數據1時,隻需要依靠高電平的持續時間即可。
3
征集結束
從機拉低50us後,FPGA可以將總線拉高。
以上就是DHT11數據傳輸的全部內容,比較容易。
四。代碼
(一)。狀態機已確認
從上麵的時序圖可以確定,采集過程大致可以分為6個階段,其中請求部分可以分為FPGA請求和DHT11響應兩部分,具體如下。
localparam S_IDLE='d0; //空閑狀態localparam S_START_FPGA='d1; //FPGA請求數據采集啟動localparam S_START_DHT11='d2; //DHT11開始請求響應localparam S_DATA='d3; //數據傳輸localparam S_STOP='d4 ; //數據結束localparam S_DOEN='d5; //數據采集完成
(二)。定時周期數確定
時序圖中提到了18ms、26-28us、20-40us、50us、70us、80us等。不過經過分析,沒有必要定義那麼多的時序周期,隻需兩個。為什麼隻定義這兩個就足夠了?
時序圖中,有兩個位置需要FPGA進行時間判斷。一是當FPGA拉低超過18ms的時候,二是判斷數據是代表數據0還是數據1。第一個明顯是18ms。數據0代表的數據位為26-28us。為了保險起見,設置為35us。如果高電平持續時間小於35us,則表示數據為0。
//時鍾為50MHZ,20nslocalparam TIME18ms='d1000_099; //初始下拉時間為18ms,900_000個時鍾周期,這裏適當延長下拉時間。 localparam TIME35us='d1_750; //數據傳輸過程中,發生數據0拉高
寫代碼時,低電平不需要處理,隻需要下降沿當前的傳輸狀態即可。例如,在dht11響應階段,隻需判斷是否出現下降沿即可。至於它的高電平和低電平持續多久,這個可以忽略不計。
(三)。狀態轉移寫入
從狀態轉移條件可以看出,轉移是通過下降沿和周期數作為條件來進行的。
always@l332.comt=TIME18ms) dht11_negedge==1 'b1) //FPGA請求結束next_state=S_START_DHT11;否則next_state=S_START_FPGA; S_START_DHT11: if ((DHT11_Cnt TIME35us) dht11_negedge==1'b1) //延時一段時間後,通過判斷dht11總線的下降沿來判斷是否結束Response next_state=S_DATA;否則next_state=S_START_DHT11; S_DATA: if (DHT11Bit_Cnt=='d39 dht11_negedge==1'b1) //接收到40bit數據後,進入停止狀態next_state=S_STOP;否則next_state=S_DATA; S_STOP: if (DHT11_Cnt==TIME35us + TIME35us) //數據發送完成後,等待總線拉低50us,這裏是70us next_state=S_DOEN;否則next_state=S_STOP; S_DOEN: next_state=S_IDLE;默認: next_state=S_IDLE;尾端
(四)。采集數據存儲
按照手冊說明,先發送高位,後發送低位,根據條件存儲。
/*接收數據存儲*/always@l332.comt=TIME35us + 'd3000) dht11_negedge==1'b1) //'d3000為低電平時間(這個是必須的),高電平持續時間小於35us視為數據0 dht11_data={dht11_data[38:0],1'b0};否則如果(dht11_negedge==1'b1) dht11_data={dht11_data[38:0],1'b1};否則dht11_data=dht11_data;否則dht11_data=dht11_data;結束
最終通過signal tap得到的數據如下。
計數校驗和,2C+02+1C+06=50,即可知道數據采集是否正確。
更多信息可以在這裏獲取==電子技術應用-AET