摘要:
FPGA是現場可編程門陣列的簡稱, 它既有門陣列器件的高度集成和通用性, 又有可編程邏輯器件用戶可編程的靈活性。通過 FPGA實現音樂流水燈的控制, 實質上就是將不同音階與特定頻率的方波信號對應起來, 以方波信號驅動蜂鳴器發出音樂, 再根據不同音階來控制流水燈的閃爍。與借助微處理器實現樂曲演奏相比, 以純硬件方式完成樂曲演奏電路更直觀。EDA工具和硬件描述語言發揮了強大功能,提供了設計可能性。
1、總體設計方案
音樂流水燈主要是點綴公共場合的裝飾品, 音樂的播放和流水燈有節奏地閃爍, 同時達到聽覺和視覺的完美結合, 成為構成其必不可少的條件。要了解如何產生不同音階的音樂, 首先要對樂音的特性有所了解。樂音實際上是有固定頻率的信號。在樂曲的構成中, 樂音的頻率和持續的時間是其構成的要素。音階的頻率可以通過高頻時鐘進行分頻得到。音頻的高低可以通過外部的 LED燈的閃爍來顯示, 這樣在音樂和流水燈的配合下可以使人產生強烈的節奏感。再輔以 LCD來顯示音階的高低長短, 不懂樂理知識的人便可以直觀的看到不同音調對應的音階。
總體設計要求如下:
( 1)分頻主要是通過一個可控分頻器實現的。采用時鐘的頻率越高, 分頻系數越大, 分頻后的音階頻率就越準確。但同時由于分頻系數大使用的計數單元增加, 從而耗費更多的硬件邏輯單元, 因此可以采取一個較為適中的時鐘頻率 12MH z 。
( 2)經過分頻后的信號是一個脈寬極窄的時鐘信號, 必須對其進行脈沖寬度調整, 增大占空比, 才能有效地驅動蜂鳴器。在脈沖寬度調整時會對此信號再次二分頻, 所以在計算時, 以樂音音階的二倍頻率去求取在特定時鐘信號下的分頻系數, 以便在調整占空比后得到正確的音階頻率。
( 3)樂曲的頻率變化多端, 對應的分頻系數也不斷變化, 因此需要將播放的樂曲的分頻系數事先存放在 ROM 中便于讀取。如果將分頻系數直接作為存儲碼存放在寄存器中, 勢必會占有更大的容量。因此在這里選取索引值來作為存儲碼以減小容量。
( 4)開發平臺上的 LED燈數量有限, 可以選用有規律的閃爍, 例如從左到右依次點亮、漸亮、漸滅等; 也可以用燈閃爍的多少來表示頻率的大小。本設計選用第二種。
圖 1為音樂流水燈控制系統的總原理框圖。可以看到該系統包含樂曲播放控制模塊, 流水燈控制模塊和 LCD顯示模塊 3個模塊。其中樂曲播放控制模塊分為樂譜播放控制模塊, 音階分頻模塊和音階頻率產生模塊。
圖1 音樂流水燈控制系統的總體原理框圖
2、 模塊設計
2.1 、樂曲播放控制模塊
樂曲播放控制模塊的主要功能是在一定的時鐘信號驅動下將事先存儲在 ROM 里的樂譜所對應的索引值依次輸出, 控制分頻, 并產生相應的分頻信號頻率, 以此來控制蜂鳴器的發聲。
2.1.1、音階分頻器的設計
為了能夠在播放樂曲的同時顯示當前音階, 用LED的位數來指示當前音階的高低音。程序中的音階分頻系數通過索引值來進行選取, 即在音樂播放過程中由樂譜存儲電路傳遞來的當前音階的索引值。
2.1.2 、音階頻率產生的設計
音階頻率產生電路在獲取上面的音階索引值對應的分頻系數后, 通過可控計數器進行分頻。分頻電路中的計數器進行減 1計數, 計數器的進位信號即為分頻信號。因為此信號的脈沖寬度極小, 所以需要調整占空比才使外部驅動電路提供足夠的驅動蜂鳴器的功率, 而具體是對分頻信號再進行二分頻實現的。
2.1.3、 樂譜播放控制模塊設計
音樂播放就是通過外部的 8 H z時鐘驅動, 內部以計數器進行計數、產生地址, 送到 ROM 單元中作為存儲器地址, 將對應地址的數據 音階索引值輸出。
在本設計中, 每個音的發出由另一個 8H z的時鐘信號來控制。樂譜中的 4分音符由 4個時鐘信號來驅動。每個時鐘下, 其對應的音階輸出以索引值的形式存儲在 ROM中。文中 ROM 的地址線為 10位, 數據線寬度為 4位。ROM 里存儲的數據即各音節的索引值, 根據樂譜轉換的需要, 16個索引值即可滿足樂曲曲譜編寫的需求, 所以設置了 4位數據線。地址線的寬度主要取決于樂曲的長度。本設計中用到了約520個 4 bit單元, 為了留有一定裕度, 將數據線寬度定義為 10位, 即 1 024個 4 b i t單元。其中不同的音階對應的索引值如表 1所示。
表 1 音階索引表
按照樂譜, 將音階對應的索引值連續地存儲到ROM中。例如, 樂譜上一個 4分音符的中音 3 , 在ROM存儲器中對應的索引值是 10 , 并且連續放置 4次, 而一個 8分音符 5也就是半拍的 5 , 則是將對應索引值 5在 ROM 中連續存放兩次。播放時在播放時鐘( 8H z )的驅動下, 索引值不斷地從 ROM 輸出。索引值送到音階分頻模塊中, 轉換為計數初值輸出, 再送到音階分頻產生模塊中, 作為計數初值, 產生音階頻率輸出驅動蜂鳴器。這樣, 就能在蜂鳴器上發出要播放的樂曲了。確定了樂譜后, 即 ROM 的存儲內容后, 就可以定制 ROM, 將其初始化文件指定為mif文件即可。
2.2、流水燈控制模塊設計
由于此設計是基于 DE270開發板之上的, 因此將對應的音階輸出, 應用 LED燈來顯示流水燈閃爍效果。根據音調"hight"的高低設置點亮燈的數量,當"hight "為低時播放低音信號, 為高時播放中音信號。如果要用到高音信號可以將! hight!長度改為 2bit 。選取板上的 oLEDR [ 6..0]前 7盞燈與低音信號對應, oLEDR[ 13..7]與中音信號對應。在本設計中,為了看到明顯的流水燈變化, 當發出中音音頻時低音顯示燈全亮。
2.3、 LCD顯示模塊設計
首先需要在 SOPC Builder中構建 SOPC系統, 按要求依次添加 NiosII處理器, 4 kB的片上 RAM, LCD模塊, 4位輸入口, 給處理器分配復位向量地址和異常向量地址。
LCD顯示模塊用來實現樂譜和音頻強度的實時顯示, 可以顯示 16 ? 2個字符, 其軟件流程如圖 2所示。
圖 2 LCD軟件流程圖
其中 LCD初始化包括對 LCD的功能設置, 顯示開關設置和模式設置。LCD定位到首行首列是通過對LCD寫定位指令, 將顯示位置確定到第一行第一列。寫字符" jian pu"到第一行是通過寫數據指令將字符jian pu : 和實時變化的樂譜顯示在液晶屏的第一行。
低、中、高音分別用 L、M、H表示并且加上對應的音階值進行顯示。LCD顯示換行是通過定位指令來實現的。顯示音頻強度到第二行是用符號# > !的個數表示音調的高低, 一個表示低音 1 , 兩個表示低音 2 ,依次類推。
在對 LCD模塊進行顯示控制時, 用到了寫控制命令和寫數據命令。這些命令是針對具體配置的硬件電路而編寫的 .h頭文件。LCD模塊的頭文件如下:
#definelcd_write_cmd(base,data)
IOWR(base,0,data)
#definelcd_read_cmd(base)
IORD(base,1)
#definelcd_write_data(base,data)
IOWR(base,2,data)
#definelcd_read_data(base)
IORD(base,3)
這樣編寫是為了和具體的硬件電路相對應, 在LCD模塊的硬件描述語言中, 液晶模塊 RW 和 RS的地址分配如下:
assi gn LCD_ RW = address[ 0]
assi gn LCD_ RS = address[ 1]
其中 RS信號是命令與數據線, 高電平表示目前數據線上交換的是數據, 低電平表示目前數據線上交換的是命令。液晶模塊根據這個信號做出正確的響應。RW 是電平信號, 高電平表示對液晶模塊執行讀取操作, 低電平表示對液晶模塊寫入數據或命令。這樣便可以確定各讀寫操作對應于基地址的偏移量。
3、 頂層設計和驗證
系統的頂層設計就是將各個底層功能模塊例化,在頂層調用, 進行正確的連接, 構成最后的系統。整個系統的硬件電路如圖 3所示。
圖3 系統硬件電路
至此, 一個硬件音樂流水燈電路就完成了。外部提供兩路時鐘信號( 12MH z和 8 Hz) , 再將樂曲輸出端連接到帶有驅動裝置的蜂鳴器或揚聲器上, 就可以欣賞所添加的樂曲了。若硬件設計上只有一路時鐘信號輸入, 可在 FPGA 內部設計分頻器, 將其分頻到8H z 再使用, 還可以在此基礎上更改。另外還可以在一個 ROM 種存儲多首樂曲, 通過按鍵選擇播放樂曲。
3、 結束語
文中在 FPGA芯片上, 利用 VHDL語言設計了功能強大的 32位 ALU。由于 ALU是 CP U的重要組成部分, 各類系統中都不可避免地需要 ALU, 因此本設計的應用泛圍較廣。