在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于FPGA的DS18B20數(shù)字溫度傳感器測(cè)溫實(shí)例

FPGA設(shè)計(jì)論壇 ? 來(lái)源:CSDN技術(shù)社區(qū) ? 2025-03-17 11:06 ? 次閱讀

1、DS18B20數(shù)字溫度傳感器

本文將使用三段式狀態(tài)機(jī)(Moore型)的寫(xiě)法來(lái)對(duì)DS18B20進(jìn)行測(cè)溫操作,以便了解DS18B20和熟悉三段式狀態(tài)機(jī)的寫(xiě)法。

1.1、概述

溫度傳感器temperature transducer)是指能感受溫度并轉(zhuǎn)換成可用輸出信號(hào)的傳感器, 是各種傳感器中最常用的一種。隨著現(xiàn)代儀器的發(fā)展,微型化、集成化、數(shù)字化正成為傳感器發(fā)展的一個(gè)重要方向。

美國(guó)DALLAS半導(dǎo)體公司推出的數(shù)字化溫度傳感器DS18B20采用單總線協(xié)議,即與FPGA接口僅需占用一個(gè)I/O端口,無(wú)須任何外部元件,直接 將環(huán)境溫度轉(zhuǎn)化成數(shù)字信號(hào),以數(shù)字碼方式串行輸出,從而大大簡(jiǎn)化了傳感器與FPGA的接口設(shè)計(jì)。

引腳如下圖:

wKgZPGfXkdiAc-gzAAC18hnTOBI003.png

1.2、結(jié)構(gòu)組成

DS18B20測(cè)量溫度范圍為-55 ~ +125℃,精度為±0.5℃。現(xiàn)場(chǎng)(實(shí)時(shí))溫度直接以“單總線” 的數(shù)字方式傳輸,大大提高了系統(tǒng)的抗干擾性。它能直接讀出被測(cè)溫度,并且可根據(jù)實(shí)際要求通過(guò)簡(jiǎn)單的編程實(shí)現(xiàn)9 ~ l2位的數(shù)字值讀數(shù)方式。它工作在3~5.5V的電壓范圍,采用多種封裝形式,從而使系統(tǒng)設(shè)計(jì)靈活、方便,設(shè)定分辨率及用戶設(shè)定的報(bào)警溫度存儲(chǔ)在EEPROM中,掉電后 依然保存。其內(nèi)部結(jié)構(gòu)如圖:

wKgZO2fXkdiAWxjwAAE5oLT1fMM912.png

高速緩存器的結(jié)構(gòu)框圖如下:

wKgZO2fXkdiAEhuNAAHhYGw_ox0809.png

由上圖可知DS18B20的高速緩存器共有9個(gè)8位寄存器,其中溫度數(shù)據(jù)低位(LSB)對(duì)應(yīng)字節(jié) 地址0,溫度數(shù)據(jù)高位(MSB)對(duì)應(yīng)字節(jié)地址1,以此類推,配置寄存器的字節(jié)地址為4。溫度數(shù)據(jù)存放的格式如下圖:

wKgZPGfXkdiAVK5VAANk1dzyiCU197.png

DS18B20在出廠時(shí)默認(rèn)配置溫度數(shù)據(jù)為12位,其中最高位為符號(hào)位,即溫度值共11位,最低四位為小數(shù)位。FPGA在讀取溫度數(shù)據(jù)時(shí),一次會(huì)讀2字節(jié)共16位,讀完后將低11位的二進(jìn)制 數(shù)轉(zhuǎn)化為十進(jìn)制數(shù)后再乘以0.0625得到所測(cè)的實(shí)際溫度值。

另外還需要判斷溫度的正負(fù),前5 個(gè)數(shù)字為符號(hào)位,這5位同時(shí)變化,我們只需要判斷其中任何一位就可以了。前5位為1時(shí),讀 取的溫度為負(fù)值,則測(cè)到的數(shù)值需要取反加1再乘以0.0625才可得到實(shí)際溫度值。前5位為0時(shí), 讀取的溫度為正值,只要將測(cè)得的數(shù)值乘以0.0625即可得到實(shí)際溫度值。

高速緩存器中第四個(gè)字節(jié)即為配置寄存器,用戶通過(guò)改變 R1 和 R0 的值來(lái)配置 DS18B20 的分辨率,上電默認(rèn)為 R1=1 以及 R0=1(12 位分辨率)。需要注意的是轉(zhuǎn)換時(shí)間與分辨率時(shí)間是有關(guān)系的。另外寄存器中最高位和低 5 位作 為內(nèi)部使用而保留使用,不可被寫(xiě)入。轉(zhuǎn)換時(shí)間與位數(shù)關(guān)系如下表所示:

wKgZPGfXkdiAaALPAADM_YmczXo515.png

1.3、通訊步驟

如何操作 DS18B20 去進(jìn)行對(duì)溫度的轉(zhuǎn)換以及讀取呢?步驟如下:

初始化

1-Wire 總線上的所有事件都必須以初始化為開(kāi)始。初始化序列由總線上的主設(shè)備發(fā)出的復(fù)位脈沖以及緊跟著從設(shè)備回應(yīng)的存在脈沖構(gòu)成。該存在脈沖是讓總線主設(shè)備知道 DS18B20 在總線上并準(zhǔn)備好運(yùn)行。所有具體時(shí)序都在1.4章節(jié)介紹。

ROM命令

當(dāng)初始化完成之后,就可以執(zhí)行 ROM 命令。這些命令是對(duì)每個(gè)設(shè)備的 64 位 ROM 編 碼進(jìn)行操作的,當(dāng)總線上連接有多個(gè)設(shè)備時(shí),可以通過(guò)這些命令識(shí)別各個(gè)設(shè)備。總共包含 有 5 種 ROM 命令,每個(gè)命令的長(zhǎng)度都是 8bit。

搜索 ROM[F0h]:當(dāng)系統(tǒng)上電初始化后,主設(shè)備可識(shí)別該總線上所有的從設(shè)備的 ROM 編碼,這樣就可以使得主設(shè)備確定總線上的從設(shè)備的類型以及數(shù)量。

讀 ROM[33h] :該命令允許主設(shè)備讀取 DS18B20 的 64 位 ROM 編碼,只有在總線上只有一個(gè) DS18B20 時(shí)才能使用這個(gè)命令。如果總線上存在多個(gè)從設(shè)備,發(fā)送此命令,則當(dāng)所有從設(shè) 備都會(huì)回應(yīng)時(shí),將會(huì)引起數(shù)據(jù)沖突。

匹配 ROM[55h] :該匹配 ROM 命令之后接著發(fā)出 64 位 ROM 編碼,使主設(shè)備在多點(diǎn)總線上定位一只特定的 DS18B20。只有和 64 位 ROM 序列完全匹配的 DS18B20 才會(huì)做出響應(yīng)。總線上的其 他從設(shè)備都將等待下一個(gè)復(fù)位脈沖。此命令在總線上有單個(gè)或多個(gè)器件時(shí)都可以使用。

跳過(guò) ROM[CCh] :這條命令可以不用提供 64 位 ROM 編碼就進(jìn)行下一步操作,在單點(diǎn)總線(一個(gè) DS18B20 傳感器)情況下可以節(jié)省時(shí)間。如果總線上不止一個(gè)從設(shè)備,在跳過(guò) ROM 命令 之后跟著發(fā)一條讀命令,則所有從設(shè)備將會(huì)同時(shí)執(zhí)行溫度轉(zhuǎn)換,總線上就會(huì)發(fā)生數(shù)據(jù)沖突。

警報(bào)搜索[ECh] :該命令的操作與跳過(guò) ROM 命令基本相同,但是不同的是只有溫度高于 TH 或低于 TL (達(dá)到報(bào)警條件)的從設(shè)備才會(huì)響應(yīng)。只要不掉電,警報(bào)狀態(tài)將一直保持,直到溫度不在警報(bào)范圍內(nèi)為止。

功能命令

當(dāng)總線上的主設(shè)備通過(guò) ROM 命令確定了哪個(gè) DS18B20 可以進(jìn)行通信時(shí),主設(shè)備就可 以向其中一個(gè)從設(shè)備發(fā)送功能命令。這些命令可以使得主設(shè)備操控從設(shè)備進(jìn)行一系列的操作。

溫度轉(zhuǎn)換[44h]:此命令為初始化單次溫度轉(zhuǎn)換,溫度轉(zhuǎn)換完后,轉(zhuǎn)換的溫度數(shù)據(jù)會(huì)寄存在高速緩存器 的 byte0(溫度數(shù)據(jù)低八位)和 byte1(溫度數(shù)據(jù)高八位)中,之后 DS18B20 恢復(fù)到低功耗 的閑置狀態(tài)。如果總線在該命令后發(fā)出讀時(shí)隙,若 DS18B20 正在進(jìn)行溫度轉(zhuǎn)換則會(huì)響應(yīng) “0”,若完成了溫度轉(zhuǎn)換則響應(yīng)“1”。如果是用的“寄生電源”供電模式,則在命令發(fā) 出后應(yīng)立即強(qiáng)制拉高總線,拉高時(shí)間應(yīng)大于時(shí)序要求。

寫(xiě)入暫存器[4Eh] :該命令使得主設(shè)備向高速緩存器寫(xiě)入 3 個(gè)字節(jié)的數(shù)據(jù)。第一個(gè)字節(jié)寫(xiě)入高速緩存器的 byte2 中(TH 寄存器),第二個(gè)字節(jié)的數(shù)據(jù)寫(xiě)入 byte3 中(TL 寄存器),第三個(gè)字節(jié)的數(shù)據(jù)寫(xiě)入 byte4 中(配置寄存器)。所有的數(shù)據(jù)都是由低位到高位的順序?qū)懭搿?fù)位可隨時(shí)中斷寫(xiě)入。

讀取高速緩存器[BEh] :讀取高速緩存器里的值,從 byte0(溫度低八位)開(kāi)始一直讀到 byte8(CRC 校驗(yàn)),每個(gè)字節(jié)的數(shù)據(jù)從低位開(kāi)始傳送。若是不想讀取這么多數(shù)據(jù)則在讀取數(shù)據(jù)時(shí)隨時(shí)可以通過(guò)復(fù)位來(lái)終止。

復(fù)制高速緩存器[48h] :該命令是將高速緩存器中的 TH(byte2)、TL(byte3)以及配置寄存器(byte4)里的 值拷貝到非易失性的存儲(chǔ)器 EEPROM 里。如果總線控制器在這條命令之后跟著發(fā)出讀時(shí) 隙,而 DS18B20 又正在忙于把暫存器拷貝到 EEPROM 存儲(chǔ)器,DS18B20 就會(huì)輸出一個(gè) “0”,如果拷貝結(jié)束的話,DS18B20 則輸出“1”。如果設(shè)備采用“寄生電源”供電模 式,則在該命令發(fā)送后,必須立即強(qiáng)制拉高總線至少 10ms。

召回 EEPROM[B8h] :該命令將溫度報(bào)警觸發(fā)值(TH 和 TL)及配置寄存器的數(shù)據(jù)從 EEPROM 中召回至高速 緩存器中。這個(gè)操作會(huì)在上電后自動(dòng)執(zhí)行一次,所以在上電期間暫存器中一直會(huì)存在有效 的數(shù)據(jù)。若在召回命令之后啟動(dòng)讀時(shí)隙,若 DS18B20 正在進(jìn)行召回 EEPROM 則會(huì)響應(yīng) “0”,若召回完成則響應(yīng)“1”。

讀取供電模式[B4h] :該命令可以讀取總線上的 DS18B20 是否是由“寄生電源”供電。在讀取數(shù)據(jù)時(shí)序中 “0”表示“寄生電源供”模式供電,“1”表示外部電源供電。

1.4、總線時(shí)序

初始化—復(fù)位和存在脈沖

與 DS18B20 所有的通信都是由初始化開(kāi)始的,初始化由主設(shè)備發(fā)出的復(fù)位脈沖及 DS18B20 響應(yīng)的存在脈沖組成。如下圖 所示。當(dāng) DS18B20 響應(yīng)復(fù)位信號(hào)的存在脈沖 后,則其向主設(shè)備表明其在該總線上,并且已經(jīng)做好了執(zhí)行命令的準(zhǔn)備。在初始化狀態(tài),總線上的主設(shè)備通過(guò)拉低 1-Wire 總線最少 480us 來(lái)表示發(fā)送復(fù)位脈 沖。發(fā)送完之后,主設(shè)備要釋放總線進(jìn)入接收模式。當(dāng)總線釋放后,上拉電阻將 1- Wire 總線拉至高電平。當(dāng) DS18B20 檢測(cè)到該上升沿信號(hào)后,其等待 15us 至 60us 后將總線 拉低 60us 至 240us 來(lái)實(shí)現(xiàn)發(fā)送一個(gè)存在脈沖。

wKgZO2fXkdiANo52AACjxf_QsmA214.png

寫(xiě)時(shí)隙

主設(shè)備通過(guò)寫(xiě)時(shí)隙將命令寫(xiě)入 DS18B20 中,寫(xiě)時(shí)隙有兩種情況:寫(xiě)“1”和寫(xiě)“0”時(shí) 隙。主設(shè)備通過(guò)寫(xiě) 1 時(shí)隙來(lái)向 DS18B20 中寫(xiě)入邏輯 1,通過(guò)寫(xiě) 0 時(shí)隙來(lái)向 DS18B20 中寫(xiě)入 邏輯 0。當(dāng)主設(shè)備將總線從高電平拉至低電平時(shí),啟動(dòng)寫(xiě)時(shí)隙,所有的寫(xiě)時(shí)隙持續(xù)時(shí)間最 少為 60us,每個(gè)寫(xiě)時(shí)隙間的恢復(fù)時(shí)間最少為 1us。當(dāng)總線(DQ)拉低后,DS18B20 在 15us 至 60us 之間對(duì)總線進(jìn)行采樣,如果采的 DQ 為高電平則發(fā)生寫(xiě) 1,如果為低電平則發(fā)生寫(xiě) 0,如下圖所示(圖中的總線控制器即為主設(shè)備)。如果要產(chǎn)生寫(xiě) 1 時(shí)隙,必須先將總線拉至邏輯低電平然后釋放總線,允許總線在寫(xiě) 隙開(kāi)始后 15us 內(nèi)上拉至高電平。若要產(chǎn)生寫(xiě) 0 時(shí)隙,必須將總線拉至邏輯低電平并保持不 變最少 60us。

wKgZPGfXkdiAPKYIAADCFd5DULI870.png

讀時(shí)隙

當(dāng)我們發(fā)送完讀取供電模式[B4h]或讀高速緩存器[BEh]命令時(shí),必須及時(shí)地生成讀時(shí)隙,只有在讀時(shí)隙 DS18B20 才能向主設(shè)備傳送數(shù)據(jù)。每個(gè)讀時(shí)隙最小必須有 60us 的持續(xù) 時(shí)間以及每個(gè)讀時(shí)隙間至少要有 1us 的恢復(fù)時(shí)間。當(dāng)主設(shè)備將總線從高電平拉至低電平超 過(guò) 1us,啟動(dòng)讀時(shí)隙,如下圖所示。當(dāng)啟動(dòng)讀時(shí)隙后,DS18B20 將會(huì)向主設(shè)備發(fā)送“0”或者“1”。DS18B20 通過(guò)將總線 拉高來(lái)發(fā)送 1,將總線拉低來(lái)發(fā)送 0 。當(dāng)讀時(shí)隙完成后,DQ 引腳將通過(guò)上拉電阻將總線拉高至高電平的閑置狀態(tài)。從 DS18B20 中輸出的數(shù)據(jù)在啟動(dòng)讀時(shí)隙后的 15us 內(nèi)有效,所以,主設(shè)備在讀時(shí)隙開(kāi)始后的 15us 內(nèi)必須釋放總線,并且對(duì)總線進(jìn)行采樣。

wKgZO2fXkdiAYt1_AADVfTEGKjM042.png

2、采用三段式狀態(tài)機(jī)測(cè)試

接下來(lái)將采用三段式狀態(tài)機(jī)對(duì)DS18B20進(jìn)行測(cè)溫操作。

2.1、整體設(shè)計(jì)

因?yàn)楸疚闹粚?xiě)DS18B20的驅(qū)動(dòng),不涉及到其他模塊(如數(shù)碼管),所以模塊框圖如下:

wKgZO2fXkdiACHfdAAAIveVkBQI000.png

信號(hào)說(shuō)明如下:

sys_clk:系統(tǒng)時(shí)鐘,50M

rst_n:低電平有效的復(fù)位信號(hào)

dq:?jiǎn)慰偩€(雙向信號(hào))

temp_data:輸出的有效數(shù)據(jù),位寬20

sign:輸出給數(shù)碼管的正負(fù)信號(hào),1表示數(shù)據(jù)為負(fù)數(shù);0表示數(shù)據(jù)為正數(shù)

根據(jù)上面對(duì)DS18B20的介紹,可以概括出整個(gè)的測(cè)溫流程如下:

wKgZO2fXkdiAIQIHAABlPKmQeyw479.png

2.2、狀態(tài)機(jī)設(shè)計(jì)

三段式狀態(tài)機(jī)的概念可以參考:狀態(tài)機(jī)(一段式、二段式、三段式)、摩爾型(Moore)和米勒型(Mealy)

當(dāng)知道了 DS18B20 的控制流程之后,我們可以借助狀態(tài)機(jī)來(lái)進(jìn)一步了解它是如何跳轉(zhuǎn)的:

wKgZPGfXkdiAIFjEAABTG9ty98E656.png

下面對(duì)各狀態(tài)說(shuō)明:

INIT1:每次操作前都需要進(jìn)行初始化操作。在這個(gè)狀態(tài)主機(jī)會(huì)使用一個(gè)計(jì)數(shù)器從0計(jì)數(shù)到1000us。一開(kāi)始就先拉低總線500us,然后釋放總線;在570us處采集總線電平,若為0,則說(shuō)明總線進(jìn)行了響應(yīng),初始化完成。

WR_CMD:在這個(gè)狀態(tài)一起發(fā)送跳過(guò)ROM和溫度轉(zhuǎn)換指令。使用一個(gè)計(jì)數(shù)器計(jì)時(shí),使用另一個(gè)計(jì)數(shù)器則對(duì)發(fā)送的數(shù)據(jù)個(gè)數(shù)計(jì)數(shù),當(dāng)成功發(fā)送16個(gè)數(shù)據(jù)后,發(fā)送命令完成

WAIT:這個(gè)狀態(tài)為延時(shí)狀態(tài),滿足發(fā)送溫度轉(zhuǎn)換指令后的等待時(shí)間750ms。使用一個(gè)計(jì)數(shù)器計(jì)時(shí),時(shí)間滿足750ms則說(shuō)明計(jì)時(shí)完成。

INIT2:第二次操作前的初始化操作。所有操作同INIT1,不贅述。

RD_CMD:在這個(gè)狀態(tài)一起發(fā)送跳過(guò)ROM和讀取溫度指令。使用一個(gè)計(jì)數(shù)器計(jì)時(shí),使用另一個(gè)計(jì)數(shù)器則對(duì)發(fā)送的數(shù)據(jù)個(gè)數(shù)計(jì)數(shù),當(dāng)成功發(fā)送16個(gè)數(shù)據(jù)后,發(fā)送命令完成

RD_DATA:在這個(gè)狀態(tài)讀取從機(jī)返回的16位溫度數(shù)據(jù)。使用一個(gè)計(jì)數(shù)器計(jì)時(shí),使用另一個(gè)計(jì)數(shù)器則對(duì)讀取的數(shù)據(jù)個(gè)數(shù)計(jì)數(shù),使用一個(gè)寄存器寄存讀取到的溫度數(shù)據(jù),當(dāng)成功讀取16個(gè)數(shù)據(jù)后,接收命令完成

需要注意:信號(hào)線dq是一個(gè)雙向信號(hào),所以使用時(shí)要用使用三態(tài)門的方法來(lái)操作,具體方法參考:如何規(guī)范地使用雙向(inout)信號(hào)?

2.3、Verilog代碼

根據(jù)上面的狀態(tài)分析圖,編寫(xiě)Verilog代碼如下:(這里就不寫(xiě)分析了,注釋已經(jīng)寫(xiě)得很詳細(xì)了,如果你看到了這邊文章且這段代碼又不懂的地方,可以評(píng)論給我)

//==================================================================
//--3段式狀態(tài)機(jī)(Moore)實(shí)現(xiàn)的DS18B20驅(qū)動(dòng)
//==================================================================

//------------<模塊及端口聲明>----------------------------------------
module ds18b20_dri(
input clk,//系統(tǒng)時(shí)鐘,50M
inputrst_n,       //低電平有效的復(fù)位信號(hào)

inoutdq,//單總線(雙向信號(hào))
output reg [19:0]   temp_data  ,   // 轉(zhuǎn)換后得到的溫度值
    output reg          sign // 符號(hào)位
);

//------------<參數(shù)定義>----------------------------------------------
//狀態(tài)機(jī)狀態(tài)定義
localparamINIT1= 6'b000001 ,
WR_CMD      = 6'b000010 ,
WAIT  = 6'b000100 ,
INIT2  = 6'b001000 ,
RD_CMD  = 6'b010000 ,
RD_DATA  = 6'b100000 ;

//時(shí)間參數(shù)定義
localparamT_INIT = 1000,//初始化最大時(shí)間,單位us
T_WAIT = 780_000;//轉(zhuǎn)換等待延時(shí),單位us

//命令定義
localparam WR_CMD_DATA = 16'h44cc, //跳過(guò) ROM 及溫度轉(zhuǎn)換命令,低位在前
RD_CMD_DATA = 16'hbecc; //跳過(guò) ROM 及讀取溫度命令,低位在前

//----------------------------------------------------------
reg[5:0]cur_state;//現(xiàn)態(tài)
reg[5:0]next_state;//次態(tài)
reg[4:0]cnt;//50分頻計(jì)數(shù)器,1Mhz(1us)
regdq_out;//雙向總線輸出
regdq_en;//雙向總線輸出使能,1則輸出,0則高阻態(tài)
regflag_ack;//從機(jī)響應(yīng)標(biāo)志信號(hào)
regclk_us;//us時(shí)鐘
reg [19:0]cnt_us;//us計(jì)數(shù)器,最大可表示1048ms
reg [3:0]bit_cnt;//接收數(shù)據(jù)計(jì)數(shù)器
reg [15:0]data_temp;//讀取的溫度數(shù)據(jù)寄存
reg [15:0]data;//未處理的原始溫度數(shù)據(jù)

//----------------------------------------------------------
wiredq_in;//雙向總線輸入

//==================================================================
//===========================
=========================== //================================================================== //----------------------------------------------------------------------- //--雙向端口使用方式 //----------------------------------------------------------------------- assigndq_in = dq;//高阻態(tài)的話,則把總線上的數(shù)據(jù)賦給dq_in assigndq = dq_en ? dq_out : 1'bz;//使能1則輸出,0則高阻態(tài) //----------------------------------------------------------------------- //--us時(shí)鐘生成,因?yàn)闀r(shí)序都是以u(píng)s為單位,所以生成一個(gè)1us的時(shí)鐘會(huì)比較方便 //----------------------------------------------------------------------- //50分頻計(jì)數(shù) always @(posedge clk or negedge rst_n)begin if(!rst_n) cnt <= 5'd0; else if(cnt == 5'd24)//每25個(gè)時(shí)鐘500ns清零 cnt <= 5'd0; else cnt <= cnt + 1'd1; end //生成1us時(shí)鐘 always @(posedge clk or negedge rst_n)begin if(!rst_n) clk_us <= 1'b0; else if(cnt == 5'd24)//每500ns clk_us <= ~clk_us; //時(shí)鐘反轉(zhuǎn) else clk_us <= clk_us; end //----------------------------------------------------------------------- //--三段式狀態(tài)機(jī) //----------------------------------------------------------------------- //狀態(tài)機(jī)第一段:同步時(shí)序描述狀態(tài)轉(zhuǎn)移 always @(posedge clk_us or negedge rst_n)begin if(!rst_n) cur_state <= INIT1; else cur_state <= next_state; end //狀態(tài)機(jī)第二段:組合邏輯判斷狀態(tài)轉(zhuǎn)移條件,描述狀態(tài)轉(zhuǎn)移規(guī)律以及輸出 always @(*)begin next_state = INIT1; case(cur_state) INIT1:begin if(cnt_us == T_INIT && flag_ack)//滿足初始化時(shí)間且接收到了從機(jī)的響應(yīng)信號(hào) next_state = WR_CMD;//跳轉(zhuǎn)到寫(xiě)狀態(tài) else next_state = INIT1;//不滿足則保持原有狀態(tài) end WR_CMD :begin if(bit_cnt == 4'd15 && cnt_us == 20'd62)//寫(xiě)完了16個(gè)數(shù)據(jù),寫(xiě)跳過(guò)ROM和寫(xiě)溫度轉(zhuǎn)換命令 next_state = WAIT;//跳轉(zhuǎn)到等待狀態(tài),等待溫度轉(zhuǎn)換完成 else next_state = WR_CMD;//不滿足則保持原有狀態(tài) end WAIT :begin if(cnt_us == T_WAIT)//等待時(shí)間結(jié)束 next_state = INIT2; else next_state = WAIT; end INIT2 :begin if(cnt_us == T_INIT && flag_ack)//再進(jìn)行初始化,時(shí)序同INIT1 next_state = RD_CMD; else next_state = INIT2; end RD_CMD :begin if(bit_cnt == 4'd15 && cnt_us == 20'd62)//寫(xiě)完了16個(gè)數(shù)據(jù),寫(xiě)跳過(guò)ROM和寫(xiě)讀取溫度轉(zhuǎn)換命令 next_state = RD_DATA;//跳轉(zhuǎn)到讀取溫度數(shù)據(jù)狀態(tài) else next_state = RD_CMD; end RD_DATA :begin if(bit_cnt == 4'd15 && cnt_us == 20'd62)//讀取完了16個(gè)數(shù)據(jù) next_state = INIT1;//跳轉(zhuǎn)到初始化狀態(tài),開(kāi)始新一輪溫度采集 else next_state = RD_DATA; end default:next_state = INIT1;//默認(rèn)初始化狀態(tài) endcase end //狀態(tài)機(jī)第三段:時(shí)序邏輯描述輸出 always @(posedge clk_us or negedge rst_n)begin if(!rst_n)begin//默認(rèn)輸出 dq_en <= 1'b0; dq_out <= 1'b0; flag_ack <= 1'b0; cnt_us <= 20'd0; bit_cnt <= 4'd0; end else begin case(cur_state) INIT1:begin if(cnt_us == T_INIT)begin//時(shí)間計(jì)數(shù)到最大值(初始化時(shí)間) cnt_us <= 20'd0;//計(jì)數(shù)器清零 flag_ack <= 1'b0;//從機(jī)響應(yīng)標(biāo)志信號(hào)拉低 end else begin//沒(méi)有計(jì)數(shù)到最大值 cnt_us <= cnt_us + 1'd1;//計(jì)數(shù)器計(jì)數(shù) if(cnt_us <= 20'd499)begin//小于500us時(shí) dq_en <= 1'b1;//控制總線 dq_out <= 1'b0;//輸出0,即拉低總線 end else begin//在500us處 dq_en <= 1'b0;//釋放總線,等待從機(jī)響應(yīng) if (cnt_us == 20'd570 && !dq_in)//在570us處采集總線電平,如果為0則說(shuō)明從機(jī)響應(yīng)了 flag_ack <= 1'b1;//拉高從機(jī)響應(yīng)標(biāo)志信號(hào) end end end WR_CMD:begin if(cnt_us == 20'd62)begin//一個(gè)寫(xiě)時(shí)隙周期63us,滿足計(jì)時(shí)條件則 cnt_us <= 20'd0;//清空計(jì)數(shù)器 dq_en <= 1'b0;//釋放總線 if(bit_cnt == 4'd15)//如果數(shù)據(jù)已經(jīng)寫(xiě)了15個(gè) bit_cnt <= 4'd0;//則清空 else//沒(méi)寫(xiě)15個(gè) bit_cnt <= bit_cnt + 1'd1;//則數(shù)據(jù)計(jì)數(shù)器+1,代表寫(xiě)入了一個(gè)數(shù)據(jù) end else begin//一個(gè)寫(xiě)時(shí)隙周期63us未完成 cnt_us <= cnt_us + 1'd1;//計(jì)數(shù)器一直計(jì)數(shù) if(cnt_us <= 20'd1)begin//0~1us(每?jī)蓚€(gè)寫(xiě)數(shù)據(jù)之間需要間隔2us) dq_en <= 1'b1;//拉低總線 dq_out <= 1'b0; end else begin if (WR_CMD_DATA[bit_cnt] == 1'b0)begin//需要寫(xiě)入的數(shù)據(jù)為0 dq_en <= 1'b1;//拉低總線 dq_out <= 1'b0;// end else if(WR_CMD_DATA[bit_cnt] == 1'b1)begin dq_en <= 1'b0;//需要寫(xiě)入的數(shù)據(jù)為1 dq_out <= 1'b0;//釋放總線 end end end end WAIT:begin//等待溫度轉(zhuǎn)換完成 dq_en <= 1'b1;//拉低總線兼容寄生電源模式 dq_out <= 1'b1; if(cnt_us == T_WAIT)//計(jì)數(shù)完成 cnt_us <= 20'd0; else cnt_us <= cnt_us + 1'd1; end INIT2:begin//第二次初始化,時(shí)序同INIT1 if(cnt_us == T_INIT)begin cnt_us <= 20'd0; flag_ack <= 1'b0; end else begin cnt_us <= cnt_us + 1'd1; if(cnt_us <= 20'd499)begin dq_en <= 1'b1; dq_out <= 1'b0; end else begin dq_en <= 1'b0; if (cnt_us == 20'd570 && !dq_in) flag_ack <= 1'b1; end end end RD_CMD:begin//寫(xiě)16個(gè)數(shù)據(jù),時(shí)序同WR_CMD if(cnt_us == 20'd62)begin cnt_us <= 20'd0; dq_en <= 1'b0; if(bit_cnt == 4'd15) bit_cnt <= 4'd0; else bit_cnt <= bit_cnt + 1'd1; end else begin cnt_us <= cnt_us + 1'd1; if(cnt_us <= 20'd1)begin dq_en <= 1'b1; dq_out <= 1'b0; end else begin if (RD_CMD_DATA[bit_cnt] == 1'b0)begin dq_en <= 1'b1; dq_out <= 1'b0; end else if(RD_CMD_DATA[bit_cnt] == 1'b1)begin dq_en <= 1'b0; dq_out <= 1'b0; end end end end RD_DATA:begin//讀16位溫度數(shù)據(jù) if(cnt_us == 20'd62)begin//一個(gè)讀時(shí)隙周期63us,滿足計(jì)時(shí)條件則 cnt_us <= 20'd0;//清空計(jì)數(shù)器 dq_en <= 1'b0;//釋放總線 if(bit_cnt == 4'd15)begin//如果數(shù)據(jù)已經(jīng)讀取了15個(gè) bit_cnt <= 4'd0;//則清空 data <= data_temp;//臨時(shí)的數(shù)據(jù)賦值給data end else begin//如果數(shù)據(jù)沒(méi)有讀取15個(gè) bit_cnt <= bit_cnt + 1'd1;//則數(shù)據(jù)計(jì)數(shù)器+1,意味著讀取了一個(gè)數(shù)據(jù) data <= data; end end else begin//一個(gè)讀時(shí)隙周期還沒(méi)結(jié)束 cnt_us <= cnt_us + 1'd1;//計(jì)數(shù)器累加 if(cnt_us <= 20'd1)begin//0~1us(每?jī)蓚€(gè)讀數(shù)據(jù)之間需要間隔2us) dq_en <= 1'b1;//拉低總線 dq_out <= 1'b0; end else begin//2us后 dq_en <= 1'b0;//釋放總掉線 if (cnt_us == 20'd10)//在10us處讀取總線電平 data_temp <= {dq,data_temp[15:1]};//讀取總線電平 end end end default:; endcase end end //----------------------------------------------------------------------- //--12位溫度數(shù)據(jù)處理 //----------------------------------------------------------------------- always @(posedge clk_us or negedge rst_n)begin if(!rst_n)begin//初始狀態(tài) temp_data <= 20'd0; sign <= 1'b0; end else begin if(!data[15])begin//最高位為0則溫度為正 sign <= 1'b0;//標(biāo)志位為正 temp_data <= data[10:0] * 11'd625 /7'd100;//12位溫度數(shù)據(jù)處理 end else if(data[15])begin//最高位為1則溫度為負(fù) sign <= 1'b1;//標(biāo)志位為負(fù) temp_data <= (~data[10:0] + 1'b1)* 11'd625 /7'd100;//12位溫度數(shù)據(jù)處理 end end end endmodule

2.4、調(diào)試

因?yàn)橥ㄓ嵾^(guò)程涉及到從機(jī)的響應(yīng),我又找不到相應(yīng)的器件模型,仿真就不搞了。

直接使用signaltap抓下波形:

wKgZO2fXkkOAKV7kAAEIrvBPNsA831.png

上圖中:

狀態(tài)機(jī)開(kāi)始運(yùn)行,進(jìn)入INTI1的初始化狀態(tài)

dht11_en拉高同時(shí)dht11_out為0,說(shuō)明主機(jī)拉低了總線

主機(jī)拉低總線后在500us處釋放了總線,總線被上拉電阻拉高

在528us處總線被從機(jī)拉低,直至637us從機(jī)才釋放了總線,說(shuō)明從機(jī)發(fā)送了響應(yīng)

在570us處因?yàn)榭偩€被從機(jī)拉低,所以拉高了響應(yīng)信號(hào)flag_ack,直到進(jìn)入下個(gè)狀態(tài)才將flag_ack拉低

1cf9e31e-fcc2-11ef-9310-92fbcf53809c.png

上圖中:

狀態(tài)機(jī)從INTI1的初始化狀態(tài)跳轉(zhuǎn)到寫(xiě)入ROM和溫度轉(zhuǎn)換命令的狀態(tài)WR_CMD

bit_cnt從0計(jì)數(shù)到F,說(shuō)明寫(xiě)入了16個(gè)數(shù)據(jù);與此同時(shí),總線上也在分別寫(xiě)入“0”和“1”

wKgZPGfXkkSATQ7BAABu2EveLgc894.png

上圖中:

狀態(tài)機(jī)從WAIT狀態(tài)跳轉(zhuǎn)到初始化狀態(tài)INIT2

cnt_us計(jì)數(shù)器從780000清零,說(shuō)明此時(shí)延時(shí)了780ms的時(shí)間以便完成溫度轉(zhuǎn)換

1d276348-fcc2-11ef-9310-92fbcf53809c.png

上圖中:

狀態(tài)機(jī)從狀態(tài)RD_CMD跳轉(zhuǎn)到數(shù)據(jù)讀取狀態(tài)RD_DATA

bit_cnt從0計(jì)數(shù)到F,說(shuō)明讀取了16個(gè)數(shù)據(jù);與此同時(shí),總線上也在分別輸出“0”和“1”

wKgZO2fXkkOAJa-YAADs-q-BajY681.png

上圖中:

data是直接從DS18B20溫度寄存器中讀取的數(shù)據(jù)0000000111111001

temp_data是處理后發(fā)送給數(shù)碼管顯示的數(shù)據(jù)3156,對(duì)應(yīng)攝氏度31.56

3、上板調(diào)試

添加數(shù)碼管顯示模塊,編譯工程,板卡顯示如下:

wKgZPGfXkkOAYUiyAAJn15EbezI348.jpg

和用調(diào)試軟件抓取的結(jié)果一致。

原文連接:https://gitcode.csdn.net/65ed75e21a836825ed799ef4.html

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1637

    文章

    21847

    瀏覽量

    608731
  • DS18B20
    +關(guān)注

    關(guān)注

    10

    文章

    782

    瀏覽量

    81431
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    493

    瀏覽量

    27800
  • 數(shù)字溫度傳感器

    關(guān)注

    0

    文章

    191

    瀏覽量

    15576

原文標(biāo)題:基于FPGA的DS18B20數(shù)字溫度傳感器測(cè)溫實(shí)例

文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    DS18B20溫度傳感器工作原理及其應(yīng)用電路圖

    DS18B20溫度傳感器的應(yīng)用電路    1.DS18B20溫度傳感器寄生電源供電方式電路圖 
    發(fā)表于 02-21 14:43

    基于單總線數(shù)字溫度傳感器DS18B20測(cè)溫系統(tǒng)方案

      摘要:設(shè)計(jì)了一種基于單總線數(shù)字溫度傳感器DS18B20測(cè)溫系統(tǒng),給出了DS18B20
    發(fā)表于 11-06 15:18

    DS18B20溫度傳感器是什么

    DALLAS最新單線數(shù)字溫度傳感器DS18B20簡(jiǎn)介新的“一線器件”體積更小、適用電壓更寬、更經(jīng)濟(jì) Dallas 半導(dǎo)體公司的數(shù)字
    發(fā)表于 04-27 08:14

    DS18B20溫度傳感器簡(jiǎn)介

    文章目錄DS18B20 簡(jiǎn)介硬件設(shè)計(jì)軟件設(shè)計(jì)下載驗(yàn)證DS18B20 簡(jiǎn)介DS18B20 是由 DALLAS 半導(dǎo)體公司推出的一種的“一線總線”接口的溫度
    發(fā)表于 12-17 07:47

    DS18B20數(shù)字溫度傳感器介紹

    由于做比賽,所以寫(xiě)了溫度傳感器,記錄一下一.介紹DS18B20是常用的數(shù)字溫度傳感器,其輸出的是
    發(fā)表于 01-05 07:26

    DS18B20數(shù)字溫度傳感器介紹

    DS18B20介紹DS18B20是常用的數(shù)字溫度傳感器,具有體積小,硬件開(kāi)銷低,抗干擾能力強(qiáng),精度高的特點(diǎn)。
    發(fā)表于 03-02 06:26

    新型溫度傳感器DS18B20高精度測(cè)溫的實(shí)現(xiàn)

    介紹了一種數(shù)字式的溫度傳感器DS18B20, 提出了一種基于89C2051 的測(cè)溫電路及軟件框圖在內(nèi)的實(shí)現(xiàn)方法。關(guān)鍵詞 
    發(fā)表于 07-03 10:14 ?62次下載

    數(shù)字溫度傳感器DS18B20的設(shè)計(jì)及應(yīng)用

    數(shù)字溫度傳感器DS18B20的設(shè)計(jì)及應(yīng)用 1引言 DS18B20是DALLAS公司生產(chǎn)的一線式數(shù)字
    發(fā)表于 04-02 18:00 ?2892次閱讀
    <b class='flag-5'>數(shù)字</b><b class='flag-5'>溫度</b><b class='flag-5'>傳感器</b><b class='flag-5'>DS18B20</b>的設(shè)計(jì)及應(yīng)用

    DS18B20數(shù)字溫度傳感器

    本設(shè)計(jì)基于單片機(jī)STM32開(kāi)發(fā)板,對(duì)DS18B20數(shù)字溫度傳感器進(jìn)行控制,有源代碼
    發(fā)表于 05-11 14:54 ?42次下載

    智能溫度傳感器DS18B20的原理與應(yīng)用

    DS18B20是DALLAS公司生產(chǎn)的單線數(shù)字溫度傳感器,他具有獨(dú)特的單線總線接口方式。文章詳細(xì)的介紹了單線數(shù)字
    發(fā)表于 10-11 18:19 ?49次下載

    ds18b20的特性_ds18b20溫度傳感器應(yīng)用

    本文首先介紹了ds18b20的特性,其次介紹了DS18B20工作原理,最后介紹了ds18b20溫度傳感器應(yīng)用。
    發(fā)表于 04-24 09:10 ?1.1w次閱讀
    <b class='flag-5'>ds18b20</b>的特性_<b class='flag-5'>ds18b20</b><b class='flag-5'>溫度</b><b class='flag-5'>傳感器</b>應(yīng)用

    DS18B20溫度傳感器測(cè)溫實(shí)驗(yàn)詳細(xì)說(shuō)明

    在前面,我們學(xué)習(xí)了DS18B20新型數(shù)字溫度傳感器的基礎(chǔ)理論知識(shí),對(duì)DS18B20的特性及應(yīng)用有了較全面的了解,本課我們就結(jié)合S51增強(qiáng)型實(shí)
    的頭像 發(fā)表于 10-06 18:13 ?1.2w次閱讀
    <b class='flag-5'>DS18B20</b><b class='flag-5'>溫度</b><b class='flag-5'>傳感器</b>的<b class='flag-5'>測(cè)溫</b>實(shí)驗(yàn)詳細(xì)說(shuō)明

    DS18B20溫度傳感器數(shù)字溫度計(jì)設(shè)計(jì)案例

    本設(shè)計(jì)采用的主控芯片是ATMEL公司的AT89S52單片機(jī),數(shù)字溫度傳感器是DALLAS公司的DS18B20。本設(shè)計(jì)用數(shù)字
    發(fā)表于 05-09 16:02 ?57次下載

    ds18b20溫度傳感器如何使用

    DS18B20是一款廣泛使用的數(shù)字溫度傳感器,它具有高精度、低功耗和易于使用的特點(diǎn)。 DS18B20溫度
    的頭像 發(fā)表于 09-03 16:51 ?976次閱讀

    基于FPGA溫度傳感器(ds18b20)驅(qū)動(dòng)設(shè)計(jì)

    數(shù)字溫度傳感器,其輸出的是數(shù)字信號(hào),具有體積小,硬件開(kāi)銷低,抗干擾能力強(qiáng),精度高的特點(diǎn)。 DS18B20
    的頭像 發(fā)表于 01-16 14:08 ?501次閱讀
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>溫度</b><b class='flag-5'>傳感器</b>(<b class='flag-5'>ds18b20</b>)驅(qū)動(dòng)設(shè)計(jì)
    主站蜘蛛池模板: 亚洲欧美视频网站 | 亚洲高清免费观看 | 日本wwwwwwwww| a天堂在线观看 | 免费视频网站在线看视频 | 毛片在线播| 色之综合天天综合色天天棕色 | 久久国产中文字幕 | 高清国产亚洲va精品 | 亚洲精品视频免费 | 国产精品久久久精品视频 | 天天操天天干视频 | 久久久久久午夜精品 | 中文字幕一区二区三区在线播放 | 狠狠狠色丁香婷婷综合激情 | 一级特级毛片免费 | 狼人射综合 | 天堂网www中文在线 天堂网传媒 | 91久久婷婷国产综合精品青草 | 日本高清色图 | 99久久精品99999久久 | 最新理论三级中文在线观看 | 四虎网址在线 | 五月婷婷欧美 | 扒开双腿猛进湿润18p | 全免费一级午夜毛片 | 国产gaysexchina男同men1068 | brazzers720欧美丰满 | 免费黄色地址 | 免费观看一级特黄三大片视频 | 波多野结衣在线视频免费观看 | 天天色色网 | 两性午夜欧美高清做性 | 亚洲h视频| 俺来也婷婷 | 黄色一级片在线观看 | 天天做天天玩天天爽天天 | 日韩一级片视频 | 成年女人在线观看 | 国产全部理论片线观看 | 老司机亚洲精品影院在线 |