⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buzzer.vhd

📁 Mars-XC2S50-S-Core-V2.0开发板核心板的说明和设计文档
💻 VHD
字号:

-- 向蜂鸣器发送一定频率的方波可以使蜂鸣器发出相应的音调,该实验通过设计一个状态机和分频
-- 器使蜂鸣器发出"多来咪发梭拉西多"的音调。
-- 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY buzzer IS
   PORT (
      clk  : IN std_logic;   
      rst  : IN std_logic;   
      out_bit  : OUT std_logic);   
END buzzer;

ARCHITECTURE arch OF buzzer IS


   SIGNAL clk_div1   :  std_logic_vector(3 DOWNTO 0);   --基频分频计数器,基频为4M
   SIGNAL clk_div2   :  std_logic_vector(12 DOWNTO 0);  --音阶分频计数器,由基频分频产生各个音阶 
   SIGNAL cnt        :  std_logic_vector(21 DOWNTO 0);  --各音阶发声时间长短计数器 
   SIGNAL state      :  std_logic_vector(2 DOWNTO 0);   
   --各个音调的分频系数
   CONSTANT  duo   :  std_logic_vector(12 DOWNTO 0) :="0111011101110";     
   CONSTANT  lai  :  std_logic_vector(12 DOWNTO 0) := "0110101001101";    
   CONSTANT  mi   :  std_logic_vector(12 DOWNTO 0) := "0101111011010";    
   CONSTANT  fa    :  std_logic_vector(12 DOWNTO 0) := "0101100110001";    
   CONSTANT  suo   :  std_logic_vector(12 DOWNTO 0) := "0100111110111";    
   CONSTANT  la    :  std_logic_vector(12 DOWNTO 0) := "0100011100001";    
   CONSTANT  xi    :  std_logic_vector(12 DOWNTO 0) := "0011111101000";    
   CONSTANT  duo1   :  std_logic_vector(12 DOWNTO 0) := "0011101110111";   
   SIGNAL out_bit_tmp :std_logic; 

BEGIN
   out_bit<=out_bit_tmp;
   PROCESS(clk,rst)
   BEGIN
      
      IF (NOT rst = '1') THEN
         clk_div1 <= "0000";    
      ELSIF(clk'EVENT AND clk='1')THEN
         IF (clk_div1 /= "1001") THEN
            clk_div1 <= clk_div1 + "0001";    
         ELSE
            clk_div1 <= "0000";    
         END IF;
      END IF;
   END PROCESS;

   PROCESS(clk,rst)
   BEGIN
    
      IF (NOT rst = '1') THEN
         clk_div2 <= "0000000000000";    
         state <= "000";    
         cnt <= "0000000000000000000000";    
         out_bit_tmp <= '0';    
      ELSIF(clk'EVENT AND clk='1')THEN
         IF (clk_div1 = "1001") THEN
            CASE state IS
               WHEN "000" =>             --发“多”
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "001";    
                        END IF;
                        IF (clk_div2 /= duo) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN "001" =>             --发“来”
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "010";    
                        END IF;
                        IF (clk_div2 /=lai) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN "010" =>             --发"米“
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "011";    
                        END IF;
                        IF (clk_div2 /=mi) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN "011" =>             --发"法“
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "100";    
                        END IF;
                        IF (clk_div2 /=fa) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN "100" =>            --发"梭“   
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "101";    
                        END IF;
                        IF (clk_div2 /=suo) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN "101" =>            --发"拉“
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "110";    
                        END IF;
                        IF (clk_div2 /= la) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN "110" =>            --发"西“
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "111";    
                        END IF;
                        IF (clk_div2 /= xi) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN "111" =>            --发"多“(高音)
                        cnt <= cnt + "0000000000000000000001";    
                        IF (cnt = "1111111111111111111111") THEN
                           state <= "000";    
                        END IF;
                        IF (clk_div2 /= duo1) THEN
                           clk_div2 <= clk_div2 + "0000000000001";    
                        ELSE
                           clk_div2 <= "0000000000000";    
                           out_bit_tmp <= NOT out_bit_tmp;    
                        END IF;
               WHEN OTHERS =>
                        NULL;
               
            END CASE;
         END IF;
      END IF;
   END PROCESS;

END arch;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -