通過使用Basys 3開發(fā)來回顧FPGA設(shè)計(jì)的基礎(chǔ)知識(shí)以及與簡單執(zhí)行器的接口
掃描二維碼
隨時(shí)隨地手機(jī)看文章
多年來,在超過100個(gè)Hackster項(xiàng)目中,我們研究了一些非常深入和復(fù)雜的解決方案,從機(jī)器人到視覺處理,創(chuàng)建自己的硬件,當(dāng)然還有涵蓋數(shù)學(xué)等概念的項(xiàng)目,以及fpga中的濾波。
在這個(gè)項(xiàng)目中,我想回顧一下基礎(chǔ)知識(shí),看看我們?nèi)绾闻c不同類型的開關(guān)、按鈕、led和顯示器進(jìn)行交互,這樣我們就可以了解更多,當(dāng)我們?cè)谄渌麘?yīng)用中使用它們時(shí),我們可以最好地解決它們。
所以在這個(gè)項(xiàng)目中,我們將使用Basys 3開發(fā)板以及一些Pmods來提供額外的接口。
對(duì)于這個(gè)項(xiàng)目,我們將使用
?Pmod ENC -正交編碼器
?按鈕
?發(fā)光二極管
我們的目標(biāo)是教授以下內(nèi)容
?如何消除一個(gè)開關(guān)的彈跳
?如何閱讀正交編碼器
?如何驅(qū)動(dòng)led有不同的強(qiáng)度使用脈寬調(diào)制
讓我們開始吧,當(dāng)然,這些技術(shù)和代碼將能夠在任何具有類似開關(guān),顯示器和led的FPGA板上使用。
消除彈跳
Basys 3有兩種開關(guān),一個(gè)按鈕和滑塊,當(dāng)開關(guān)被翻轉(zhuǎn)、滑動(dòng)或按下時(shí),我們正在斷開或建立電氣連接。開關(guān)不做一個(gè)干凈的即時(shí)連接,而是在穩(wěn)定之前,他們先斷斷續(xù)續(xù)地接觸。這種斷斷續(xù)續(xù)的初始接觸導(dǎo)致被稱為開關(guān)彈跳。
開關(guān)彈跳如下圖所示,在開關(guān)打開或斷開之后有許多過渡。反彈可能是全振幅或部分振幅反彈。
當(dāng)我們想要在應(yīng)用程序中對(duì)開關(guān)進(jìn)行采樣時(shí),我們需要考慮可能發(fā)生的任何開關(guān)反彈。如果不這樣做,就意味著我們可能會(huì)多次注冊(cè)操作,這將是困難的。
在真實(shí)的硬件世界中,開關(guān)反彈可能如下所示,這是Basys 3上的一個(gè)按鈕開關(guān)的示波器捕獲。
通常一個(gè)開關(guān)可能會(huì)反彈幾毫秒,所以我們需要在FPGA中考慮到這一點(diǎn)。
值得慶幸的是,在使用fpga中的開關(guān)時(shí),我們可以使用幾種技術(shù)來消除它們的反彈。所有這些都包括使用同步設(shè)計(jì),因此我們需要做的第一件事是將開關(guān)輸入同步到正確的時(shí)鐘域。
如果你不熟悉為什么我們需要同步到時(shí)鐘域。這是因?yàn)樗屑拇嫫鞫加幸粋€(gè)設(shè)置和保持時(shí)鐘邊緣的時(shí)間,它更新寄存器。
如果輸入在此窗口內(nèi)發(fā)生變化,則寄存器的輸出將變?yōu)閬喎€(wěn)態(tài)。這意味著在1和0之間的狀態(tài),它會(huì)隨機(jī)恢復(fù)到1或0但它與輸入電平?jīng)]有關(guān)系。
因此,我們至少使用一個(gè)兩級(jí)寄存器來同步進(jìn)入FPGA的信號(hào),該信號(hào)未與時(shí)鐘同步。這允許第一個(gè)寄存器進(jìn)入亞穩(wěn)態(tài)并在下一個(gè)時(shí)鐘和更新第二個(gè)寄存器之前恢復(fù)。這確保了同步器下游的寄存器不會(huì)冒著看到亞穩(wěn)態(tài)值和在設(shè)計(jì)中傳播問題的風(fēng)險(xiǎn)。
因此,我們需要使用這樣的同步器來同步輸入的開關(guān)信號(hào)。
一旦我們同步了信號(hào),我們就需要消除信號(hào)的反彈,因?yàn)榉磸椚匀粫?huì)通過同步器,它們只是與時(shí)鐘同步。
我們可以使用一個(gè)簡單的同步器和計(jì)數(shù)器來消除開關(guān)輸入的反彈
為了測(cè)試這段代碼,我們可以創(chuàng)建一個(gè)針對(duì)Basys 3板的Vivado項(xiàng)目,創(chuàng)建一個(gè)新的VHDL文件并模擬它。
我們將看到如下波形,其中輸入開關(guān)改變狀態(tài),它使用兩個(gè)寄存器同步,然后在輸入輸出之前等待10毫秒。
現(xiàn)在我們已經(jīng)消除了一個(gè)開關(guān)輸入,我們可以看看如何使用一個(gè)更復(fù)雜的開關(guān),如旋轉(zhuǎn)編碼器。
旋轉(zhuǎn)編碼器
旋轉(zhuǎn)編碼器是一種快速切換不同選項(xiàng)的方法,一個(gè)常見的例子是使用它的旋轉(zhuǎn)來控制LED或顯示屏的亮度。
它通常也被稱為正交編碼器,因?yàn)閮蓚€(gè)輸出a和B彼此位于90度,例如在正交中。
當(dāng)開關(guān)按時(shí)鐘或反時(shí)鐘方向旋轉(zhuǎn)時(shí),你會(huì)看到A和B的變化,當(dāng)然你會(huì)得到反彈。
根據(jù)兩個(gè)輸出A或B中哪一個(gè)有第一條邊,我們可以確定旋轉(zhuǎn)的方向。
通常旋轉(zhuǎn)編碼器也有一個(gè)按鈕,可用于確認(rèn)選擇等。
當(dāng)我們旋轉(zhuǎn)旋轉(zhuǎn)編碼器,我們會(huì)得到小故障,可以看到下面,但這些是較短的持續(xù)時(shí)間,因?yàn)檐囕喰D(zhuǎn)。
注意,使用的編碼器通常是高的,因?yàn)樗焕饋怼?
為了讀取編碼器并確定旋轉(zhuǎn)方向,我們可以使用邊緣檢測(cè)。
下面的代碼示例允許我們根據(jù)表盤的旋轉(zhuǎn)方向增加或減少向量值。
我們可以將其添加到我們的Vivado項(xiàng)目中,并使用下面的測(cè)試臺(tái)模擬其行為
運(yùn)行模擬,您可以看到計(jì)數(shù)隨著編碼器旋轉(zhuǎn)的變化而增加,然后減少。
通過切換設(shè)置的斜坡值模擬,我們可以看到計(jì)數(shù)增加,然后減少。
現(xiàn)在我們有兩個(gè)元素,我們需要我們的LED調(diào)光電路。下一個(gè)要素是創(chuàng)建驅(qū)動(dòng)電路。
脈寬調(diào)制
脈寬調(diào)制是偉大的提供可變功率負(fù)載和重建模擬信號(hào)與簡單的后處理與R和C。
PWM信號(hào)有兩個(gè)關(guān)鍵元素
?周期-信號(hào)的重復(fù)周期
?占空比-多少周期的信號(hào)是高的
對(duì)于本應(yīng)用程序,我們將使用50Hz PWM周期,并使用旋轉(zhuǎn)編碼器使PWM周期可控。
PWM的代碼是
而試驗(yàn)臺(tái)將設(shè)置幾個(gè)不同的PWM輸出
在我們的Vivado項(xiàng)目中運(yùn)行這個(gè)程序顯示如下,我們可以看到脈沖寬度隨著輸入需求的改變而改變。
現(xiàn)在,我們準(zhǔn)備將所有這些整合到Vivado設(shè)計(jì)中,并在硬件上進(jìn)行測(cè)試。
整合設(shè)計(jì)
為了開始這個(gè),我們將在Vivado創(chuàng)建一個(gè)新的框圖項(xiàng)目。在此基礎(chǔ)上,我們將添加剛剛創(chuàng)建的RTL課程代碼。
通過將IP核添加到框圖中,我們能夠創(chuàng)建頂層包裝器并綜合設(shè)計(jì)。
我已經(jīng)將旋轉(zhuǎn)編碼器連接到A和B輸入,旋轉(zhuǎn)編碼器還包括1毫秒的彈跳鎖定。我還稍微更改了代碼,每次旋轉(zhuǎn)增加/減少8,以停止需要256次調(diào)整。
我還增加了第二個(gè)LED連接到按鈕開關(guān)時(shí),旋轉(zhuǎn)開關(guān)被推動(dòng)。這是連接到消跳電路。
讓Vivado管理包裝器
一旦合成完成,我們就可以在XDC文件中分配IO
一旦比特流完成,我們就可以下載并在硬件上進(jìn)行測(cè)試。
當(dāng)旋轉(zhuǎn)編碼器改變時(shí),我們可以看到ILA上的LED值發(fā)生變化。
總結(jié)
雖然是一個(gè)簡單的項(xiàng)目,但我希望這個(gè)項(xiàng)目已經(jīng)提供了信息和有用的,特別是如果你剛剛開始你的FPGA之旅。在更復(fù)雜的解決方案中,與交換機(jī)接口和處理反彈可能會(huì)導(dǎo)致意外命令的問題。
本文編譯自hackster.io