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

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

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

最近在做一個DHT11相關(guān)的東西,寫了一個DHT11控制模塊。參考了正點原子和野火電子的文檔資料后總覺得又亂又雜,所以自己跟著數(shù)據(jù)手冊寫了一遍,當(dāng)然了也很感謝正點原子和野火文檔的幫助。

DHT11是一種數(shù)字溫濕度傳感器,有4個引腳但只有三個有效引腳,分別是VDD,DATA和GND,如圖1所示,使用的是典型的單總線通信,即一根數(shù)據(jù)線。這根數(shù)據(jù)線需要通過上拉電阻連接到電源,使得數(shù)據(jù)線在空閑時保持高電平。數(shù)據(jù)手冊建議每2秒種對數(shù)據(jù)進(jìn)行一次讀取,來保證數(shù)據(jù)的穩(wěn)定性。

FPGA讀取DHT11數(shù)字溫濕度傳感器
圖1 外觀

單總線數(shù)據(jù)傳輸位定義:一次傳輸40位數(shù)據(jù),高位先出。

數(shù)據(jù)格式:8bit濕度整數(shù)+8bit濕度小數(shù)+8bit溫度整數(shù)+8bit溫度小數(shù)+8bit校驗位。

示例數(shù)據(jù):

00110101 ?00000000 ?00011000 ?00000100 ?01010001

濕度高8位 ?濕度低8位??溫度高8位 ?溫度低8位 ?校驗位8bit

計算:

00110101+00000000+00011000+00000100=01010001

濕度:00110101 = 35H = 53

??00000000 = 00H = 0 ?濕度為53.0%

溫度:00011000 = 18H = 24

??00000100 = 04H = 0.4 溫度為24.4℃

并且當(dāng)溫度低于0時溫度數(shù)據(jù)的低8位的最高位置1。由于一般不會出現(xiàn)負(fù)數(shù),所以此次設(shè)計不關(guān)心此處。

時序圖如圖2:

?文章來源地址http://www.zghlxwxcb.cn/news/detail-451430.html

FPGA讀取DHT11數(shù)字溫濕度傳感器
圖2 時序圖

?

外設(shè)讀取步驟:

①設(shè)備上電,等待1s越過不穩(wěn)定狀態(tài),由于2秒讀取一次數(shù)據(jù)較穩(wěn)定,所以我們等待2s。

②主機(jī)發(fā)送開始信號,數(shù)據(jù)線拉低至少18ms。此時總線由FPGA控制。

③主機(jī)將數(shù)據(jù)線拉高后釋放總線等待從機(jī)響應(yīng),時間為13us。

④從機(jī)相應(yīng)低電平,時間為83us。

⑤從機(jī)相應(yīng)高電平,時間為87us。

⑥FPGA讀取DHT11的溫濕度數(shù)據(jù)。

圖3為時間參數(shù)表。

FPGA讀取DHT11數(shù)字溫濕度傳感器
圖3 時間參數(shù)

由此我們可以確定使用狀態(tài)機(jī)實現(xiàn)該設(shè)計,很輕松便可以畫出狀態(tài)轉(zhuǎn)換圖,如圖4,圖中狀態(tài)分別對應(yīng)上述外設(shè)讀取的6個步驟。

FPGA讀取DHT11數(shù)字溫濕度傳感器
圖4 狀態(tài)轉(zhuǎn)換

?

?接下來就根據(jù)狀態(tài)轉(zhuǎn)換圖來進(jìn)行verilog代碼的編寫,代碼如下。

/*
	description : dht11 control
*/
module dht11(
	input	sys_clk		,	//system clock
	input	sys_rst_n	,	//system reset negedge
	
	inout	dht11_data	,	//dht11 inout port
	
	output	reg	[39:0]	t_h_data
);

//---------state code
parameter	WAIT			=	6'b000_001,//wait state 2s
			START			=	6'b000_010,//make bus low 20ms
			WAIT_RES		=	6'b000_100,//wait respond
			RES_LOW			=	6'b001_000,//respond low
			RES_HIGH		=	6'b010_000,//respong high
			REC_DATA		=	6'b100_000;//receive datas
//---------time parameter
//parameter	CNT_2S_MAX		=	100	,
//			CNT_20MS_MAX	=	1_0	,
//			CNT_1US_MAX		=	50	;
parameter	CNT_2S_MAX		=	100_000_000	,
			CNT_20MS_MAX	=	1_000_000	,
			CNT_1US_MAX		=	50			;
//---------state define
reg	[5:0] 	state_cur;//current state
reg [5:0] 	state_nex;//next state
//---------flag define
wire		end_2s		;	//wait 2s end
wire		end_20ms    ;	//wait 20ms end
wire		res_ok      ;	//respond ok
wire		res_no      ;	//no respond
wire		end_res_low ;	//wait respond low end 83us
wire		end_res_high;	//wait respond high end 87us
wire		end_rec     ;	//data receive end 40bits
//---------dht11_data regist
reg			dht11_data_r1;
reg			dht11_data_r2;
wire		dht11_posedge;
wire		dht11_negedge;
reg			data;
reg			output_en;
wire		check;			//the datas is correct or wrong ?
reg	[39:0]	t_h_data_temp;//temperature and huminity data
//---------counter define
reg	[26:0]	cnt_2s;
reg [19:0]	cnt_20ms;
reg	[6:0]	cnt_nus;
reg	[5:0]	cnt_1us;
reg			cnt_us_rst;
reg	[5:0]	cnt_bit;
//---------flag assignments
assign	end_2s 			= (state_cur == WAIT && cnt_2s == CNT_2S_MAX - 1'b1) ? 1'b1 : 1'b0;
assign	end_20ms 		= (state_cur == START && cnt_20ms == CNT_20MS_MAX - 1'b1) ? 1'b1 : 1'b0;
assign	res_ok 			= (state_cur == WAIT_RES && cnt_nus < 20 && dht11_negedge) ? 1'b1 : 1'b0;
assign 	res_no 			= (state_cur == WAIT_RES && cnt_nus > 20) ? 1'b1 : 1'b0;
assign 	end_res_low 	= (state_cur == RES_LOW && cnt_nus > 70 && dht11_posedge) ? 1'b1 : 1'b0;
assign 	end_res_high 	= (state_cur == RES_HIGH && cnt_nus > 70 && dht11_negedge) ? 1'b1 : 1'b0;
assign	end_rec 		= (state_cur == REC_DATA && cnt_bit >= 40) ? 1'b1 : 1'b0;
//---------dht11 assignments
assign dht11_posedge = dht11_data_r1 & ~dht11_data_r2;
assign dht11_negedge = ~dht11_data_r1 & dht11_data_r2;
assign dht11_data = output_en ? data : 1'bz;
assign check = (t_h_data_temp[39:32]+t_h_data_temp[31:24]+
					t_h_data_temp[23:16]+t_h_data_temp[15:8] == t_h_data_temp[7:0])
					? 1'b1 : 1'b0;//the datas is correct or wrong ?
//*********posedge and negedge detect
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		dht11_data_r1 <= 1'b0;
		dht11_data_r2 <= 1'b0;
	end
	else begin
		dht11_data_r1 <= dht11_data;
		dht11_data_r2 <= dht11_data_r1;
	end
end
//*********counter
always@(*)begin
	case(state_cur)
		WAIT		:	cnt_us_rst = 1'b1;
	    START		:	cnt_us_rst = 1'b1;
	    WAIT_RES	:	begin
			if(res_ok)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
	    RES_LOW		:	begin
			if(end_res_low)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
	    RES_HIGH	:	begin
			if(end_res_high)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
	    REC_DATA	:	begin
			if(dht11_posedge || dht11_negedge)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
		default		:cnt_us_rst = 1'b1;
	endcase
end
//---------cnt_2s
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_2s <= 27'd0;
	end
	else begin
		if(state_cur == WAIT)begin
			if(cnt_2s <= CNT_2S_MAX - 1'b1)
				cnt_2s <= cnt_2s + 1'b1;
			else
				cnt_2s <= cnt_2s;
		end
		else if(state_cur == REC_DATA)begin
			cnt_2s <= 27'd0;
		end
		else begin
			cnt_2s <= cnt_2s;
		end
	end
end
//---------cnt_20ms
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_20ms <= 20'd0;
	end
	else begin
		if(state_cur == START)begin
			if(cnt_20ms <= CNT_20MS_MAX - 1'b1)
				cnt_20ms <= cnt_20ms + 1'b1;
			else
				cnt_20ms <= cnt_20ms;
		end
		else if(state_cur == REC_DATA)begin
			cnt_20ms <= 20'd0;
		end
		else begin
			cnt_20ms <= cnt_20ms;
		end
	end
end
//---------cnt_1us
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_1us <= 6'd0;
	end
	else begin
		if(cnt_1us == CNT_1US_MAX - 1'b1)
			cnt_1us <= 6'd0;
		else if(cnt_us_rst)
			cnt_1us <= 6'd0;
		else
			cnt_1us <= cnt_1us + 1'b1;
	end
end
//---------cnt_nus
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_nus <= 7'd0;
	end
	else begin
		if(cnt_us_rst)
			cnt_nus <= 7'd0;
		else if(cnt_1us == CNT_1US_MAX - 1'b1)
			cnt_nus <= cnt_nus + 1'b1;
		else
			cnt_nus <= cnt_nus;
	end
end
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_bit <= 6'd0;
	end
	else begin
		if(state_cur == REC_DATA)begin
			if(dht11_negedge)
				cnt_bit <= cnt_bit + 1'b1;
			else
				cnt_bit <= cnt_bit;
		end
		else begin
			cnt_bit <= 6'd0;
		end
	end
end
//*********three stages state machine
//---------the first stage : state transmission
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)
		state_cur <= WAIT;
	else
		state_cur <= state_nex;
end
//---------the second stage : conditions
always@(*)begin
	case(state_cur)
		WAIT	:begin
			if(end_2s)
				state_nex = START;	//count 2s finish 
			else
				state_nex = WAIT;
		end		
		START	:begin
			if(end_20ms)
				state_nex = WAIT_RES;//count 20ms finish 
			else
				state_nex = START;
		end			
		WAIT_RES:begin	
			if(res_ok)				//respond 
				state_nex = RES_LOW;	
			else if(res_no)			//no respond 
				state_nex = WAIT;
			else
				state_nex = WAIT_RES;
		end			
		RES_LOW	:begin
			if(end_res_low)
				state_nex = RES_HIGH;
			else
				state_nex = RES_LOW;
		end			
		RES_HIGH:begin
			if(end_res_high)
				state_nex = REC_DATA;
			else
				state_nex = RES_HIGH;
		end			
		REC_DATA:begin
			if(end_rec)
				state_nex = WAIT;
			else
				state_nex = REC_DATA;
		end		
		default	:begin
			state_nex = WAIT;
		end			
	endcase
end
//---------the third stage : outputs
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		output_en <= 1'b0;
		data <= 1'b0;
	end
	else begin
		case(state_cur)
			WAIT	 :begin
				output_en <= 1'b1;//output
				data <= 1'b1;
			end
		    START	 :begin
				output_en <= 1'b1;//output
				data <= 1'b0;
				if(end_20ms)
					data <= 1'b1;
			end
		    WAIT_RES :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		    RES_LOW	 :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		    RES_HIGH :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		    REC_DATA :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
			default  :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		endcase
	end
end
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		t_h_data_temp <= 40'd0;
	end
	else begin
		if(state_cur == REC_DATA)begin
			if(cnt_nus > 50 && dht11_negedge)
				t_h_data_temp[39 - cnt_bit] <= 1'b1;
			else if(cnt_nus < 50 && dht11_negedge)
				t_h_data_temp[39 - cnt_bit] <= 1'b0;
			else 
				t_h_data_temp <= t_h_data_temp;
		end
		else begin
			t_h_data_temp <= t_h_data_temp;
		end
	end
end
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		t_h_data <= 40'd0;
	end
	else begin
		if(state_cur == REC_DATA)begin
			if(end_rec && check)
				t_h_data <= t_h_data_temp;
			else
				t_h_data <= t_h_data;
		end
		else begin
			t_h_data <= t_h_data;
		end
	end
end
endmodule

?完成代碼后仿真觀察前三個狀態(tài),modelsim仿真結(jié)果如圖5,可以清晰地觀察到狀態(tài)的轉(zhuǎn)換以及轉(zhuǎn)換條件。

FPGA讀取DHT11數(shù)字溫濕度傳感器
圖5 仿真圖

由于沒有dht11仿真模型,所以只好使用signaltap直接對實際波形進(jìn)行抓取,在抓取了幾次之后并且更改代碼后得到了最終的正確結(jié)果,如圖6,讀取波形數(shù)據(jù)后可得濕度為18,溫度為25,并且校驗通過,數(shù)據(jù)讀取正確。

FPGA讀取DHT11數(shù)字溫濕度傳感器
圖6 signaltap波形

?

隨后通過數(shù)碼管進(jìn)行顯示,數(shù)碼管模塊的代碼非常簡單,這里就不再貼出,直接查看最后的上板實驗效果,只顯示了溫濕度的整數(shù)位,如圖7,左側(cè)為濕度,右側(cè)為溫度。

FPGA讀取DHT11數(shù)字溫濕度傳感器
圖7 上板測試

參考資料:

1.dht11數(shù)據(jù)手冊

2.征途Mini《FPGA Verilog開發(fā)實戰(zhàn)指南——基于Altera EP4CE10》

3.新起點FPGA開發(fā)指南

?

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

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

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

相關(guān)文章

  • FPGA實驗筆記_Vivado:DDS信號發(fā)生器;數(shù)碼管;基于DHT11的溫濕度傳感器

    FPGA實驗筆記_Vivado:DDS信號發(fā)生器;數(shù)碼管;基于DHT11的溫濕度傳感器

    目錄 1、 FPGA的DDS信號發(fā)生器 1.1、DDS簡介 1.2、ROM IP核的生成 1.3、波形數(shù)據(jù)的生成 1.4、 ROM的調(diào)用 1.5、 完整代碼(包括拓展部分) 2、數(shù)碼管顯示 2.1、數(shù)碼管簡要說明 2.2、SM410564 3、基于DHT11的溫濕度傳感器 3.1、DHT11 3.2、基本思路 3.3、數(shù)據(jù)分離模塊(BTD) 3.4、數(shù)據(jù)轉(zhuǎn)換模塊(

    2024年02月04日
    瀏覽(97)
  • 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)過校準(zhǔn)的數(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ù)部分,具體格式在下面說明,當(dāng)前小數(shù) 部分用于以后擴(kuò)展,現(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).首先圖二部分是單片機(jī)向DHT11發(fā)送我要開始的信號,此時單片機(jī)IO口處于輸出模式,輸出低電平至少18MS,

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

    STM32--DHT11溫濕度傳感器

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

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

    CC2530——溫濕度傳感器DHT11

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

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

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

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

    2024年02月02日
    瀏覽(87)
  • 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)紅包