名稱:音樂播放器數(shù)碼管顯示簡譜蜂鳴器(代碼在文末付費(fèi)下載)
軟件:Quartus
語言:VHDL
代碼功能:
設(shè)計(jì)音樂播放器,播放一首歌,使用開發(fā)板的蜂鳴器播放音樂,使用Quartus內(nèi)的ROM IP核存儲音樂文件,使用數(shù)碼管顯示簡譜,led顯示節(jié)奏。
簡譜存儲在ROM中,具體值可以打開music.mif文件查看
mif文件說明:
8表示簡譜1
9表示簡譜2
10表示簡譜3
以此類推
每個(gè)簡譜對應(yīng)4個(gè)相同的值
演示視頻:
部分代碼展示
LIBRARY?ieee; ???USE?ieee.std_logic_1164.all; ???USE?ieee.std_logic_unsigned.all; --播放器控制 ENTITY?music_ctrl?IS ???PORT?( ??????sysclk?????:?IN?STD_LOGIC;--50M晶振 ??????stop_key???:?IN?STD_LOGIC; ??????start_key??:?IN?STD_LOGIC;--開始 ??????tonecode???:?OUT?STD_LOGIC_VECTOR(7?DOWNTO?0); ??????tonestep???:?IN?STD_LOGIC_VECTOR(9?DOWNTO?0); ??????led????????:?OUT?STD_LOGIC;--指示燈 ??????spkout?????:?OUT?STD_LOGIC--蜂鳴器輸出 ???); END?music_ctrl; ARCHITECTURE?trans?OF?music_ctrl?IS --調(diào)用ROM COMPONENT?ROM?IS PORT ( address:?IN?STD_LOGIC_VECTOR?(7?DOWNTO?0); clock:?IN?STD_LOGIC??; q:?OUT?STD_LOGIC_VECTOR?(7?DOWNTO?0) ); END?COMPONENT; ??? ???SIGNAL?addr?????????????:?STD_LOGIC_VECTOR(21?DOWNTO?0);--分頻控制字 ???SIGNAL?divclk_counter???:?STD_LOGIC_VECTOR(24?DOWNTO?0); ???SIGNAL?musicclk?????????:?STD_LOGIC; ???SIGNAL?musickeyshiftbuf?:?STD_LOGIC_VECTOR(31?DOWNTO?0); ???SIGNAL?musicno??????????:?STD_LOGIC_VECTOR(1?DOWNTO?0); ??? ???SIGNAL?step?????????????:?STD_LOGIC_VECTOR(9?DOWNTO?0); ???SIGNAL?codeaddr1????????:?STD_LOGIC_VECTOR(7?DOWNTO?0); ??? ???SIGNAL?model_Key_down???:?STD_LOGIC; ??? ???SIGNAL?ROM_data?????????:?STD_LOGIC_VECTOR(7?DOWNTO?0); ??? ???SIGNAL?music_select?????:?STD_LOGIC?:=?'0'; BEGIN ??? ?--例化ROM,ROM里面存了樂譜?? ???i_ROM?:?ROM ??????PORT?MAP?( ?????????address??=>?codeaddr1, ?????????clock????=>?musicclk, ?????????q????????=>?ROM_data ??????); ???led?<=?music_select; ???PROCESS?(sysclk,?stop_key,?start_key) ???BEGIN ??????IF?(sysclk'EVENT?AND?sysclk?=?'1')?THEN ?????????IF?((NOT(stop_key))?=?'1')?THEN ????????????music_select?<=?'0';--停止 ?????????ELSIF?((NOT(start_key))?=?'1')?THEN ????????????music_select?<=?'1';--開始 ?????????END?IF; ??????END?IF; ???END?PROCESS; ??? ??? ???step?<=?tonestep; ???PROCESS?(sysclk) ???BEGIN ??????IF?(sysclk'EVENT?AND?sysclk?=?'1')?THEN ?????????addr?<=?addr?+?("000000000000"?&?step);--step是根據(jù)音樂文件產(chǎn)生的頻率控制字,不同step產(chǎn)生不同頻率的spkout ??????END?IF; ???END?PROCESS; ??? ??? ???PROCESS?(sysclk) ???BEGIN ??????IF?(sysclk'EVENT?AND?sysclk?=?'1')?THEN ?????????IF?(divclk_counter?=?"0000000000000000000001000")?THEN--50M/(1799999*2)=分頻到13.9Hz,為便于仿真,計(jì)數(shù)器0000110110111011100111111改小為0000000000000000000001000 ????????????musicclk?<=?(NOT(musicclk));--musicclk=13.9Hz ????????????divclk_counter?<=?"0000000000000000000000000"; ?????????ELSE ????????????divclk_counter?<=?divclk_counter?+?"0000000000000000000000001"; ?????????END?IF; ??????END?IF; ???END?PROCESS;
PROCESS (sysclk)
BEGIN
IF (sysclk'EVENT AND sysclk = '1') THEN
IF (music_select = '0') THEN
spkout <= '1';--0時(shí)蜂鳴器拉高,不唱
ELSE
spkout <= addr(3);--addr的最高位就是輸出蜂鳴器的頻率--addr2
END IF;
END IF;
END PROCESS;
PROCESS (musicclk, stop_key)
BEGIN
IF ((NOT(stop_key)) = '1') THEN
codeaddr1 <= "00000000";
ELSIF (musicclk'EVENT AND musicclk = '1') THEN
IF (music_select = '1') THEN
tonecode <= ROM_data;--播放歌曲
IF (codeaddr1 = "11111111") THEN
codeaddr1 <= "00000000";--播放完后循環(huán)
ELSE
codeaddr1 <= codeaddr1 + "00000001";
END IF;
END IF;
END IF;
END PROCESS;
END trans;
設(shè)計(jì)文檔:
1. 工程文件
2. 程序文件
3. 程序編譯
4. RTL圖
5. 仿真圖
整體仿真圖
頻率控制字模塊
音樂控制模塊
顯示模塊
點(diǎn)擊鏈接獲取代碼文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=196