音乐播放器VHDL蜂鸣器数码管显示简谱,视频/代码

名称:音乐播放器数码管显示简谱蜂鸣器

软件:Quartus

语言:VHDL

代码功能:

设计音乐播放器,播放一首歌,使用开发板的蜂鸣器播放音乐,使用Quartus内的ROM IP核存储音乐文件,使用数码管显示简谱,led显示节奏

简谱存储在ROM中,具体值可以打开music.mif文件查看

mif文件说明:

8表示简谱1

9表示简谱2

10表示简谱3

以此类推

每个简谱对应4个相同的值

演示视频:音乐播放器VHDL蜂鸣器数码管显示简谱_Verilog/VHDL资源下载

代码下载:音乐播放器VHDL蜂鸣器数码管显示简谱_Verilog/VHDL资源下载名称:音乐播放器数码管显示简谱蜂鸣器(代码在文末付费下载)软件:Quartus语言:VHDL代码功能:设计音乐播放器,播放一首歌,使用开发板的蜂鸣器播放音乐,使用Quartus内的ROM IP核存储音乐文件,使用数码管显示简谱,led显示节奏简谱存储在ROM中,具体值可以打开music.mif文件查看mif文件说明:8表示简谱19表示简谱210表示简谱3以此类推每个简谱对应4个相同的值演示视频:部icon-default.png?t=N7T8http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=196

部分代码展示

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
--调用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是根据音乐文件产生的频率控制字,不同step产生不同频率的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,为便于仿真,计数器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时蜂鸣器拉高,不唱

         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";--播放完后循环

            ELSE

               codeaddr1 <= codeaddr1 + "00000001";

            END IF;

         END IF;

      END IF;

   END PROCESS;

   

   

END trans;

设计文档:

1. 工程文件

2. 程序文件

3. 程序编译

4. RTL图

5. 仿真图

整体仿真图

频率控制字模块

音乐控制模块

显示模块

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个较为复杂的设计,需要分步骤进行。 首先,我们需要使用VHDL设计一个计数器模块,该模块可以根据时钟信号进行计时,并输出计数值。接着,我们需要设计一个模块,该模块可以将计数值转换成用2位数码管显示的数字,并将其输出。最后,我们需要添加一个蜂鸣器模块,该模块可以根据计数值判断是否到达设定的倒计时结束时间,并在结束时产生报警信号。 下面是一个简单的实现过程: 1. 设计计数器模块 ```vhdl entity counter is port ( clk : in std_logic; rst : in std_logic; count_out : out integer range 0 to 99); end entity counter; architecture rtl of counter is signal count : integer range 0 to 99 := 0; begin process (clk, rst) begin if rst = '1' then count <= 0; elsif rising_edge(clk) then if count = 99 then count <= 0; else count <= count + 1; end if; end if; end process; count_out <= count; end architecture rtl; ``` 2. 设计数码管显示模块 ```vhdl entity display is port ( num : in integer range 0 to 99; seg : out std_logic_vector(6 downto 0)); end entity display; architecture rtl of display is signal seg_out : std_logic_vector(6 downto 0); begin process (num) variable digit : integer range 0 to 9; begin digit := num mod 10; case digit is when 0 => seg_out <= "0000001"; when 1 => seg_out <= "1001111"; when 2 => seg_out <= "0010010"; when 3 => seg_out <= "0000110"; when 4 => seg_out <= "1001100"; when 5 => seg_out <= "0100100"; when 6 => seg_out <= "0100000"; when 7 => seg_out <= "0001111"; when 8 => seg_out <= "0000000"; when 9 => seg_out <= "0000100"; when others => seg_out <= "1111111"; end case; end process; seg <= seg_out; end architecture rtl; ``` 3. 设计蜂鸣器模块 ```vhdl entity buzzer is port ( freq : in integer range 1 to 1000000; alarm : out std_logic); end entity buzzer; architecture rtl of buzzer is signal count : integer range 0 to 1000000; begin process (freq) begin if freq = 0 then count <= 0; else count <= count + 1; end if; end process; alarm <= '1' when count >= freq/2 else '0'; end architecture rtl; ``` 4. 整合模块 最后,我们将三个模块整合在一起,并添加一个开始倒计时的输入信号start,以及设定的倒计时时间timeout。 ```vhdl entity countdown is port ( clk : in std_logic; rst : in std_logic; start : in std_logic; timeout : in integer range 1 to 99; seg : out std_logic_vector(6 downto 0); alarm : out std_logic); end entity countdown; architecture rtl of countdown is signal count : integer range 0 to 99 := 0; signal buzzer_freq : integer range 0 to 1000000 := 0; begin counter_inst : entity work.counter port map ( clk => clk, rst => rst, count_out => count); display_inst : entity work.display port map ( num => count, seg => seg); buzzer_inst : entity work.buzzer port map ( freq => buzzer_freq, alarm => alarm); process (clk, start, timeout, count) begin if rst = '1' then count <= 0; buzzer_freq <= 0; elsif rising_edge(clk) then if start = '1' then if count = timeout then buzzer_freq <= 1000; -- 设定报警频率为1kHz elsif count > timeout then buzzer_freq <= buzzer_freq + 1; end if; end if; end if; end process; end architecture rtl; ``` 以上是一个简单的倒计时时钟设计,其中只考虑了基本功能,实际应用中还需要考虑更多的细节问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值