<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STEP FPGA驅(qū)動(dòng)溫度傳感器DS18B20Z

          STEP FPGA驅(qū)動(dòng)溫度傳感器DS18B20Z

          作者: 時(shí)間:2023-11-28 來(lái)源:電子森林 收藏

          硬件說(shuō)明

          DS18B20是我們?nèi)粘TO(shè)計(jì)中常用的一款芯片,只需要一根總線就可以實(shí)現(xiàn)通信,非常的方便,我們的STEP-BaseBoard底板上就集成了DS18B20Z,下面我們就一起來(lái)學(xué)習(xí)一下它的硬件鏈接及驅(qū)動(dòng)方法。

          本文引用地址:http://www.ex-cimer.com/article/202311/453369.htm

          DS18B20Z只有一根總線,硬件電路非常簡(jiǎn)單,但是一定記得總線需要做上拉處理,如下圖總線上連接了10K(上拉電阻取值可以一定范圍內(nèi)自行調(diào)整)的上拉電阻,另外我們使用FPGA驅(qū)動(dòng),一定記得將FPGA對(duì)應(yīng)的管腳同樣作上拉配置,重要的事情說(shuō)三遍,總線上拉,總線上拉,總線上拉。

          聊完硬件連接,接下來(lái)簡(jiǎn)要介紹如何驅(qū)動(dòng)(更加詳細(xì)的信息需要大家參考數(shù)據(jù)手冊(cè)),不同的功能需求對(duì)應(yīng)不同寄存器配置,本設(shè)計(jì)執(zhí)行的操作案例如下。

          下面為大家展示上述案例中每個(gè)環(huán)節(jié)的時(shí)序要求:


          Verilog代碼

          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module:DS18B20Z 
          // 
          // Author: Step
          // 
          // Description: Drive DS18B20Z to get temperature code
          // 
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.0     |2015/11/11   |Initial ver
          // --------------------------------------------------------------------
          module DS18B20Z(
          	input				clk_in,			//系統(tǒng)時(shí)鐘
          	input				rst_n_in,		//系統(tǒng)復(fù)位,低有效
          	inout				one_wire,		//DS18B20Z傳感器單總線,雙向管腳
          	output	reg	[15:0]	data_out		//DS18B20Z有效溫度數(shù)據(jù)輸出)
          	; 	
          	/*
          	本設(shè)計(jì)通過(guò)驅(qū)動(dòng)DS18B20Z芯片獲取溫度數(shù)據(jù),
          	需要了解inout類型的接口如何實(shí)現(xiàn)雙向通信,
          	中間涉及各種不同的延時(shí)和寄存器指令操作,注釋部分以作簡(jiǎn)要說(shuō)明,更多詳情需參考數(shù)據(jù)手冊(cè)
          	*/ 	
          	localparam	IDLE	=	3'd0;
          	localparam	MAIN	=	3'd1;
          	localparam	INIT	=	3'd2;
          	localparam	WRITE	=	3'd3;
          	localparam	READ	=	3'd4;
          	localparam	DELAY	=	3'd5; 	//計(jì)數(shù)器分頻產(chǎn)生1MHz的時(shí)鐘信號(hào)
          	reg					clk_1mhz;
          	reg		[2:0]		cnt_1mhz;
          	always@(posedge clk_in or negedge rst_n_in) begin
          		if(!rst_n_in) begin
          			cnt_1mhz <= 3'd0;
          			clk_1mhz <= 1'b0;
          		end else if(cnt_1mhz >= 3'd5) begin
          			cnt_1mhz <= 3'd0;
          			clk_1mhz <= ~clk_1mhz;	//產(chǎn)生1MHz分頻
          		end else begin
          			cnt_1mhz <= cnt_1mhz + 1'b1;
          		end
          	end 	
          	reg		[2:0]		cnt;
          	reg					one_wire_buffer;
          	reg		[3:0]		cnt_main;
          	reg		[7:0]		data_wr;
          	reg		[7:0]		data_wr_buffer;
          	reg		[2:0]		cnt_init;
          	reg		[19:0]		cnt_delay;
          	reg		[19:0]		num_delay;
          	reg		[3:0]		cnt_write;
          	reg		[2:0]		cnt_read;
          	reg		[15:0]		temperature;
          	reg		[7:0]		temperature_buffer;
          	reg		[2:0] 		state = IDLE;
          	reg		[2:0] 		state_back = IDLE;
          	//使用1MHz時(shí)鐘信號(hào)做觸發(fā)完成下面狀態(tài)機(jī)的功能
          	always@(posedge clk_1mhz or negedge rst_n_in) begin
          		if(!rst_n_in) begin
          			state <= IDLE;
          			state_back <= IDLE;
          			cnt <= 1'b0;
          			cnt_main <= 1'b0;
          			cnt_init <= 1'b0;
          			cnt_write <= 1'b0;
          			cnt_read <= 1'b0;
          			cnt_delay <= 1'b0;
          			one_wire_buffer <= 1'bz;
          			temperature <= 16'h0;
          		end else begin
          			case(state)
          				IDLE:begin		//IDLE狀態(tài),程序設(shè)計(jì)的軟復(fù)位功能,各狀態(tài)異常都會(huì)跳轉(zhuǎn)到此狀態(tài)
          						state <= MAIN;	//軟復(fù)位完成,跳轉(zhuǎn)之MAIN狀態(tài)重新工作
          						state_back <= MAIN;
          						cnt <= 1'b0;
          						cnt_main <= 1'b0;
          						cnt_init <= 1'b0;
          						cnt_write <= 1'b0;
          						cnt_read <= 1'b0;
          						cnt_delay <= 1'b0;
          						one_wire_buffer <= 1'bz;
          					end
          				MAIN:begin		//MAIN狀態(tài)控制狀態(tài)機(jī)在不同狀態(tài)間跳轉(zhuǎn),實(shí)現(xiàn)完整的溫度數(shù)據(jù)采集
          						if(cnt_main >= 4'd11) cnt_main <= 1'b0;
          						else cnt_main <= cnt_main + 1'b1;
          						case(cnt_main)
          							4'd0: begin state <= INIT; 
          							end	//跳轉(zhuǎn)至INIT狀態(tài)進(jìn)行芯片的復(fù)位及驗(yàn)證
          							4'd1: begin data_wr <= 8'hcc;
          							state <= WRITE; 
          							end	//主設(shè)備發(fā)出跳轉(zhuǎn)ROM指令
          							4'd2: begin data_wr <= 8'h44;
          							state <= WRITE; 
          							end	//主設(shè)備發(fā)出溫度轉(zhuǎn)換指令
          							4'd3: begin num_delay <= 20'd750000;
          							state <= DELAY;
          							state_back <= MAIN; 
          							end	//延時(shí)750ms等待轉(zhuǎn)換完成
          							4'd4: begin state <= INIT; 
          							end	//跳轉(zhuǎn)至INIT狀態(tài)進(jìn)行芯片的復(fù)位及驗(yàn)證
          							4'd5: begin data_wr <= 8'hcc;
          							state <= WRITE; 
          							end	//主設(shè)備發(fā)出跳轉(zhuǎn)ROM指令
          							4'd6: begin data_wr <= 8'hbe;
          							state <= WRITE; 
          							end	//主設(shè)備發(fā)出讀取溫度指令
          							4'd7: begin state <= READ; 
          							end	//跳轉(zhuǎn)至READ狀態(tài)進(jìn)行單總線數(shù)據(jù)讀取
          							4'd8: begin temperature[7:0] <= temperature_buffer; 
          							end	//先讀取的為低8位數(shù)據(jù)
          							4'd9: begin state <= READ; 
          							end	//跳轉(zhuǎn)至READ狀態(tài)進(jìn)行單總線數(shù)據(jù)讀取
          							4'd10: begin temperature[15:8] <= temperature_buffer;
          							end	//后讀取的為高8為數(shù)據(jù)
          							4'd11: begin state <= IDLE;
          							data_out <= temperature; 
          							end	//將完整的溫度數(shù)據(jù)輸出并重復(fù)以上所有操作
          							default: state <= IDLE;
          						endcase
          					end
          				INIT:begin		//INIT狀態(tài)完成DS18B20Z芯片的復(fù)位及驗(yàn)證功能
          						if(cnt_init >= 3'd6) cnt_init <= 1'b0;
          						else cnt_init <= cnt_init + 1'b1;
          						case(cnt_init)
          							3'd0: begin one_wire_buffer <= 1'b0; 
          							end	//單總線復(fù)位脈沖拉低
          							3'd1: begin num_delay <= 20'd500;
          							state <= DELAY;
          							state_back <= INIT; end	//復(fù)位脈沖保持拉低500us時(shí)間
          							3'd2: begin one_wire_buffer <= 1'bz; 
          							end	//單總線復(fù)位脈沖釋放,自動(dòng)上拉
          							3'd3: begin num_delay <= 20'd100;
          							state <= DELAY;
          							state_back <= INIT; end	//復(fù)位脈沖保持釋放100us時(shí)間
          							3'd4: begin if(one_wire) state <= IDLE; 
          							else state <= INIT; 
          							end	//根據(jù)單總線的存在檢測(cè)結(jié)果判定是否繼續(xù)
          							3'd5: begin num_delay <= 20'd400;
          							state <= DELAY;
          							state_back <= INIT; 
          							end	//如果檢測(cè)正常繼續(xù)保持釋放400us時(shí)間
          							3'd6: begin state <= MAIN; 
          							end	//INIT狀態(tài)操作完成,返回MAIN狀態(tài)
          							default: state <= IDLE;
          						endcase
          					end
          				WRITE:begin		//按照DS18B20Z芯片單總線時(shí)序進(jìn)行寫(xiě)操作
          						if(cnt <= 3'd6) begin	//共需要發(fā)送8bit的數(shù)據(jù),這里控制循環(huán)的次數(shù)
          							if(cnt_write >= 4'd6) begin cnt_write <= 1'b1; 
          							cnt <= cnt + 1'b1; 
          							end
          							else begin cnt_write <= cnt_write + 1'b1; 
          							cnt <= cnt; end
          						end else begin
          							if(cnt_write >= 4'd8) begin cnt_write <= 1'b0; 
          							cnt <= 1'b0; 
          							end	//兩個(gè)變量都恢復(fù)初值
          							else begin cnt_write <= cnt_write + 1'b1; 
          							cnt <= cnt; 
          							end
          						end
          						//對(duì)于WRITE狀態(tài)中cnt_write來(lái)講,執(zhí)行過(guò)程為:0;[1~6]*8;7;8;
          						case(cnt_write)
          							//lock data_wr
          							4'd0: begin data_wr_buffer <= data_wr; 
          							end	//將需要寫(xiě)出的數(shù)據(jù)緩存
          							//發(fā)送 1bit 數(shù)據(jù)的用時(shí)在60~120us之間,參考數(shù)據(jù)手冊(cè)
          							4'd1: begin one_wire_buffer <= 1'b0; end	//總線拉低
          							4'd2: begin num_delay <= 20'd2;
          							state <= DELAY;
          							state_back <= WRITE; 
          							end	//延時(shí)2us時(shí)間,保證15us以內(nèi)
          							4'd3: begin one_wire_buffer <= data_wr_buffer[cnt]; 
          							end	//先發(fā)送數(shù)據(jù)最低位
          							4'd4: begin num_delay <= 20'd80;
          							state <= DELAY;
          							state_back <= WRITE; end	//延時(shí)80us時(shí)間
          							4'd5: begin one_wire_buffer <= 1'bz; 
          							end	//總線釋放
          							4'd6: begin num_delay <= 20'd2;
          							state <= DELAY;
          							state_back <= WRITE; 
          							end	//延時(shí)2us時(shí)間
          							//back to main
          							4'd7: begin num_delay <= 20'd80;
          							state <= DELAY;
          							state_back <= WRITE; 
          							end	//延時(shí)80us時(shí)間
          							4'd8: begin state <= MAIN; end	//返回MAIN狀態(tài)
          							default: state <= IDLE;
          						endcase
          					end
          				READ:begin		//按照DS18B20Z芯片單總線時(shí)序進(jìn)行讀操作
          						if(cnt <= 3'd6) begin	//共需要接收8bit的數(shù)據(jù),這里控制循環(huán)的次數(shù)
          							if(cnt_read >= 3'd5) begin cnt_read <= 1'b0; 
          							cnt <= cnt + 1'b1; end
          							else begin cnt_read <= cnt_read + 1'b1; 
          							cnt <= cnt; end
          						end else begin
          							if(cnt_read >= 3'd6) begin cnt_read <= 1'b0; 
          							cnt <= 1'b0; end	//兩個(gè)變量都恢復(fù)初值
          							else begin cnt_read <= cnt_read + 1'b1; cnt <= cnt; 
          							end
          						end
          						case(cnt_read)
          							//讀取 1bit 數(shù)據(jù)的用時(shí)在60~120us之間,總線拉低后15us時(shí)間內(nèi)讀取數(shù)據(jù),參考數(shù)據(jù)手冊(cè)
          							3'd0: begin one_wire_buffer <= 1'b0; 
          							end	//總線拉低
          							3'd1: begin num_delay <= 20'd2;
          							state <= DELAY;
          							state_back <= READ; 
          							end	//延時(shí)2us時(shí)間
          							3'd2: begin one_wire_buffer <= 1'bz; 
          							end	//總線釋放
          							3'd3: begin num_delay <= 20'd5;
          							state <= DELAY;
          							state_back <= READ; 
          							end	//延時(shí)5us時(shí)間
          							3'd4: begin temperature_buffer[cnt] <= one_wire; 
          							end	//讀取DS18B20Z返回的總線數(shù)據(jù),先收最低位
          							3'd5: begin num_delay <= 20'd60;
          							state <= DELAY;
          							state_back <= READ; 
          							end	//延時(shí)60us時(shí)間
          							//back to main
          							3'd6: begin state <= MAIN; 
          							end	//返回MAIN狀態(tài)
          							default: state <= IDLE;
          						endcase
          					end
          				DELAY:begin		//延時(shí)控制
          						if(cnt_delay >= num_delay) begin	//延時(shí)控制,延時(shí)時(shí)間由num_delay指定
          							cnt_delay <= 1'b0;
          							state <= state_back; 	//很多狀態(tài)都需要延時(shí),延時(shí)后返回哪個(gè)狀態(tài)由state_back指定
          						end else cnt_delay <= cnt_delay + 1'b1;
          					end
          			endcase
          		end
          	end 	
          	assign	one_wire = one_wire_buffer; 
          	endmodule

          小結(jié)

          本節(jié)主要為大家講解了DS18B20Z的驅(qū)動(dòng)方法及軟件實(shí)現(xiàn),需要大家掌握的同時(shí)自己創(chuàng)建工程,通過(guò)整個(gè)設(shè)計(jì)流程,生成FPGA配置文件加載測(cè)試。



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();