📄 buzzer.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 + -