1.同步動態掃描
多個數碼管的顯示采用的是同步動態掃描方法,同步動態掃描指的是:行信號和列信號同步掃描,是一種並行操作。
2.數碼管驅動電路實現思路
如果要求數碼管顯示我們想要的數字,首先需要寫一個數據接收模塊,這個模塊接收數據之后需要做什么樣的處理呢?這時候我們會想到兩個數碼管,其中一個顯示十位數字,另一個顯示各位數字,即把這個數據的十位傳給其中一個數碼管,各位數字傳給另一個數碼管來顯示。這樣我們就會明確了:數據接收模塊需要將接收的數據進行拆分,分別輸出其十位數據與個位上的數據
程序風格:
1.always塊語句中,總是先寫出復位信號到來時候的情況,即輸出全部置零。
2.always塊語句中的變量都是reg型,因此在寫always塊語句前需要事先定義好,定義好reg型變量的位寬與名字。
3.盡管always塊語句里面是對輸出量的處理,但reg型的變量名最好不用輸出量的名字,應先用其它的變量名代替,最后通過assign語句傳遞給輸出量。(以后的工作中需要弄清楚為什么是這種編碼風格)。
注意:
1.給變量賦值時,應帶上數據的位寬與進制,總之,在編碼的過程中,時刻注意變量的位寬與進制。多敲代碼,養成良好的編碼習慣。
2.寫條件語句時,注意里面的代碼,通常是以begin開頭,end結尾,很重要,即使邏輯正確,少了這些,都無法通過編譯。
當我們獲得輸入數據的十位與個位信號后,我們並不能直接傳輸給數碼管,讓其顯示。當然八段數碼管的顯示方式並不陌生,因此十位與個位信號需要經過一個翻譯的過程,把這兩個信號翻譯成數碼管能識別的代碼,這是一個加碼的過程。
以上為八段數碼管的顯示編碼,在程序中以參數的形式給出,方便以后調用。其中,當復位信號到來時,給輸出信號賦值為“8’b1111_1111”此時八段數碼管處於熄滅狀態。
注意:似乎有大量參數的程序,都會用到case/endcase程序段,類似一個查表的過程,當case(輸入量),在以下的代碼中找到相匹配的輸入量后,執行對應的語句(對輸出量進行操作,賦值等)。
在我們獲得了數碼管的顯示代碼后,為什么不直接傳給數碼管呢,直接顯示應該沒問題呀,但為什么需要加一個行掃描模塊與列掃描模塊,希望有看到這篇博客的人能告訴為原因。
先說說列掃描,掃描頻率制定為50Hz,即周期為0.02s,即從左至右,把兩個燈掃一遍需要20ms,分配給兩個燈,一個燈亮10ms,即每隔10ms換一個數碼管使能。列掃描的工作機制如下:無需額外的輸入,內部需要計數器,產生10ms的時間,然后通過內部邏輯控制數碼管的使能。輸出的列掃描信號即為數碼管的片選信號,在實際的引腳分配中要注意。
以下為計數器的典型寫法。
寫完計數器之后,就應該寫對輸出語句的操作了。結合兩個always塊語句來看,前一個always塊語句里面的變量t用在了下一個always塊語句里面的case里面。
這其中涉及到一個狀態機的編碼技巧(哈哈,前幾天看視頻才弄明白的)。
分析:
輸出信號有兩種狀態0:rColumn_Scan <= 2’b10; 個位數碼管使能
1: rColumn_Scan <= 2’b01;十位數碼管使能
前一個always塊語句專門用來控制狀態變量t的跳變,即在什么條件下由一個狀態跳變到另外一個狀態中呢?繪制如下狀態圖:
狀態機與相應的操作分開寫,會讓程序更加清晰。
最后是行掃描模塊,數碼管的十位與個位顯示代碼是傳給行掃描模塊的,最后模塊輸出一個行掃描信號。行掃描模塊的工作機制如下:
因為行掃描與列掃描是同步進行的,因此也需要一個10ms的計數器,假設初始時間是0,過了10ms后,十位的數碼管被使能,這時候,行掃描模塊應該把十位上的數據傳給十位數碼管,再過10ms,個位的數碼管被使能,這時候,行掃描模塊應該把個位上的數據傳給個位數碼管。這其中也有一個狀態的跳變過程,需要寫狀態機。
至此,數碼管驅動電路各個模塊已經完成,最后只需要通過一個頂層文件用wire將各個模塊連接起來。