当前位置:文档之家› 音乐彩灯控制电路数电FPGA设计(含代码)

音乐彩灯控制电路数电FPGA设计(含代码)

音乐彩灯控制电路1、申请题目:音乐彩灯控制电路采用4×4矩阵式键盘作为电子琴按键输入,用FPGA设计一个既可以区分不同音高和音阶进行乐曲的弹奏,又可以自动播放乐曲的音乐电路。

同时,在播放音乐的同时,点阵板上的彩灯会随着不同的音乐、不同的音阶、音调而出先不同的花型变化。

按键音符可以通过数码管显示出来。

2、项目规划:音乐演奏电路,既有通过键盘自由弹奏,又可以播放内存乐曲(播放的乐曲由设计者自由编辑,以简谱二进制码方式存放在ROM的数据文件中)。

彩灯显示电路,在音乐播放的同时,根据音乐节拍的不同,16路彩灯进行各种花型的变化,彩灯的亮灭有多种不同的模式,可以根据八个拨码开关来进行设计,进行自由组合搭配。

不同的音乐对应不同的彩灯模式,每种模式执行16拍后依次循环改变,当音乐停止时,彩灯的变化也停止。

设置启动、停止控制键,可以结束音乐的播放和彩灯变化。

设置选择音乐播放键,共存储了3首音乐,可以通过选择键进行选择播放具体不同的音乐。

设置了彩灯变化选择按钮,有普通彩灯和动感彩灯两种方式进行选择,可以通过按键进行选择。

设计采用音乐引入控制彩灯变化方式。

用4×4矩阵式键盘作为按键输入,16×16的LED 点阵板作为彩灯输出。

可以通过按键选择弹奏乐曲和播放乐曲两种模式。

点阵板上彩灯的变化随着乐曲的不同而进行不同的变化。

在播放过程中可以按键进行系统的停止和启动运行。

同时也可以通过扬声器将音乐播放出来。

3、实现方案:问题1:乐曲的发声原理组成乐曲的2个基本要素是每个音符的发声频率值和它持续的时间,可以利用程序控制FPGA某个引脚输出一定频率的矩形波,便可以得到某个音符的音调,也可以再接上扬声器之后,就能发出相应频率的声音。

同时,若能控制每个音符的持续时间,也就控制了乐曲的节奏,因此只需要控制输出到引脚的信号频率的高低以及每个信号持续的时间长短,即可实现乐曲的产生。

问题2:音符的获得方法和乐曲节奏的控制所有不同的频率信号都可以从同一个系统基准频率分频而来,可以通过预置不同频率的音符信号,通过系统基准频率值计算得到分频系数,提供给之后的节奏使用。

每个音符持续的时间是乐曲能连续播放的另一个要素。

设全音符的持续时间为1s,则2分音符的持续时间为0.5s,4分音符的持续时间为0.25s。

如果采用1MHz的频率作为系统基准频率,则需要对1MHz信号进行250000次分频,得到4Hz信号作为一个4分音符的频率。

对于其他占用时间较长的节拍,则只需要将该音符连续输出相应遍数即可。

问题3:16路彩灯控制原理根据系统设计要求,整个模块分为控制彩灯节奏的输入信号和16个输出信号,分别用于控制十六路彩灯。

利用状态机实现了7种花型的变化,同时利用六十六位常数的设计,可方便地设置和修改花型。

解决方案:1.乐曲播放功能设计根据乐曲发声的基本原理,乐曲播放模块的设计思路是通过1MHz时钟分频获得音符节拍频率,通过查音符频率表获得音符分频系数,作为音频分频模块分频的依据,将1MHz 时钟频率分频获得合适的音符频率,输出至音频播放模块。

节拍控制分频模块主要用于产生乐曲节拍,控制乐曲播放的节奏,1MHz的系统频率经过250000次分频,可以得到4分音符持续时间的频率。

乐曲长度计数器在节拍控制频率信号的作用下进行乐曲音符的顺序计数。

乐曲模块中存放的是各个乐曲音符的分频值。

音符分频器根据乐曲模块中存储的各个音符的分频系数来完成对1MHz系统频率的分频,输出相应的音频信号。

2.乐曲弹奏功能设计根据乐曲弹奏的工作原理,乐曲弹奏主要由键盘扫描模块、分频置数模块、音符分频器、输出模块构成。

其中,键盘扫描模块的设计思路是在系统时钟控制下循环给出键盘扫描信号,然后根据扫描信号和对应的键盘响应信号确定键盘按键位置,再将相应的值送到下一个处理模块。

这里采用列扫描方式,由FPGA输出键盘的列输入信号,采集键盘的行输出信号。

键盘扫描模块可以采用状态机的设计方法,用四个状态完成对键盘的四列扫描,确定每一列的输入;第五个状态用于键值处理状态,根据扫描结果判断按键是音符输入还是高低音的选择,以及长时间无按键时停止音频输出,对长时间按同一键按一次键处理等。

3.彩灯电路功能设计系统的工作原理是,通过时序控制电路根据输入信号产生符合一定要求的、供显示控制电路使用的控制时钟信号,而显示控制电路则根据时序控制电路输入的控制时钟信号,输出六种花型循环变化的、控制十六路彩灯工作的控制信号,这些控制信号加上驱动电路一起控制彩灯工作。

4、系统结构:系统结构框图:模块功能描述:根据设计要求,要求系统既可以播放乐曲,又可以弹奏乐曲,同时彩灯的变化都是随着音乐的变化而显现不同的花型,可以通过设置一个功能选择键将两者分开。

其中乐曲播放模块应包含节拍控制分频模块、音符频率输出模块、乐曲存储模块;乐曲弹奏模块应包含键盘扫描模块、音符频率输出模块。

还有一个彩灯显示模块。

乐曲播放模块乐曲播放模块的设计思路是通过1MHz时钟分频得到音符节拍频率,通过查表方式获取音符节拍频率分频系数,作为音符分频器的依据,将1MHz时钟分频获得合适的音符频率,输出至音频输出。

节拍控制分频模块主要用于产生乐曲节拍,控制乐曲的播放节奏。

乐曲长度计数器在节拍控制频率信号的作用下进行乐曲音符的顺序计数。

乐曲模块中存放的是乐曲各个音符的分频值。

音符分频器根据乐曲模块中存储的各个音符的分频系数完成对1MHz系统频率的分频,输出相应的音频信号。

乐曲弹奏模块和彩灯显示模块乐曲弹奏和彩灯显示主要有键盘扫描模块、分频系数模块、音符分频器和彩灯显示电路构成。

其中,键盘扫描模块的设计思路是在系统时钟控制下循环给出键盘扫瞄信号,然后根据扫描信号和对应键盘响应信号确定键盘按键位置,再将相应键值的段码输出。

分频系数模块用于确定输入音符对应的分频数。

音符分频器根据分频系数模块提供的分频系数完成对1MHz系统频率的分频,输出相应的频率信号。

彩灯显示模块根据输入的信号,对应输出不同花型的彩灯信号。

模块接口标注:5、状态流程图:系统工作状态流程6、各主要模块仿真结果波形各模块的仿真波形,详细注释输入输出功能端口1.乐曲播放模块仿真电路设计中,系统时钟clk采用1MHz的工作频率。

为了便于观察仿真的结果,这里将节拍控制分频模块4分音符的分频数由250000暂时调整为16,循环播放3个音符,且这三个音符的分频系数一次为2、4、8。

仿真波形如下,从图中可以看出,节拍控制分频模块的4分音符频率输出clk_4Hz确为系统基准频率clk的16分频,且在clk_4Hz信号节拍的控制下,out_sound依次输出为对clk的2分频、4分频和8分频信号。

2.键盘扫描及显示模块仿真为了便于观察仿真结果,将键盘扫描频率暂时调整为8个时钟信号clk,仿真前设定行输入信号KBcol为“1110”,仿真结果如图所示,可以看出当列扫描信号KBrow一次扫描输出“1110”、“1101”、“1011”、“0111”,及对应这3、2、1、0行各个按键信息。

3.乐曲弹奏模块仿真为了便于观察仿真的结果,键盘扫描频率采取上述加键盘扫描及显示模块仿真中的扫描频率,这里取中音1和低音1的仿真来验证模块的功能。

4.彩灯显示电路模块仿真彩灯显示电路是随着音乐的播放而出现不同变化花型的电路,这里仿真用的是自动循环播放乐曲来验证模块的功能。

7、课程设计总结通过此次数字系统课程设计自己觉得最大的体会是体会了独立设计一个小型系统的整个过程,为今后自己在实际应用于开发系统的发展方向提供了一个很好的锻炼的机会。

这次我设计的题目是音乐彩灯控制电路。

就如同题目所涵盖的意思一样,我的设计系统是一个可以随着音乐的播放而彩灯自动变化花型的数字电路系统。

这个系统是通过FPGA 来设计实现的。

系统分为两大部分,一部分是音乐产生电路,一部分是彩灯显示电路。

音乐产生电路又有两种区分,一种是自动播放音乐,一种是可以通过键盘来弹奏音乐。

最终实现的设计已经大部分实现了我设计中谈及到的功能。

系统中设计了开始按钮,可以开启系统运行。

可以有音乐播放的选择按钮,通过不同的选择,可以播放不同的音乐。

同时也可以通过键盘按键来弹奏乐曲。

键盘设计了A、B、C分别代表高音、中音和低音。

用数字1-7代表7个音符。

在播放音乐的同时,可以选择是否开启彩灯变化电路,开启电路时,彩灯的变化是随着音乐的变化而呈现缤纷多彩的变化的。

当然彩灯的变化也有两种选择方式:普通模式与动感模式。

总体来说,最终完成的设计和预期的目标基本相同。

在设计中还可以提高和改进的地方主要有彩灯变化的方式。

在最终完成的设计成品中彩灯的变化花型还是过于单一。

在设计中可以试着将列选进行扫描,最终使得彩灯的变化可以实现输出字或者图案等花型。

相信在以后的过程中,可以在这个方面进行更多的设计思考。

最后谈一点设计体会。

通过此次的课程设计,最直接的受益是学会了一门数字电路设计语言—VHDL语言。

通过在设计的过程中的整个立项和实施过程的体会是最重要的。

可以说从对VHDL语言的不了解到通过查阅各种资料来学习VHDL语言的语法和编程技术,这本身便是一个挑战与学习的过程,也正是有了这样一个课程设计,才使得我能够迅速地掌握了VHDL语言的编程入门。

当然令我映像深刻的还有的是调试的过程。

因为也许程序编写没有问题,但是在调试的过程中也许会出现很多意想不到的问题,正是在这种不断调试中才能发现更多的问题。

所以通过这一次的数字系统课程设计,使我受益匪浅。

8、参考文献1.电子设计自动化(EDA)课程设计与项目实例李莉路而红编著2.数字逻辑EDA设计与实践刘昌华编著3.EDA及技术实验与课程设计曹昕燕周凤臣聂春燕编著9.源程序Music.vhdllibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity music isgeneric(mid1 : integer range 1000 to 4000 :=1911;--mid1 : integer range 0 to 10 :=1;mid2 : integer range 1000 to 4000 :=1703;--mid2 : integer range 0 to 10 :=3;mid3 : integer range 1000 to 4000 :=1517; --mid3 : integer range 0 to 10 :=7;mid4 : integer range 1000 to 4000 :=1432; mid5 : integer range 1000 to 4000 :=1276; mid6 : integer range 1000 to 4000 :=1137; mid7 : integer range 1000 to 4000 :=1012;low1 : integer range 1000 to 4000 :=3823; low2 : integer range 1000 to 4000 :=3405; low3 : integer range 1000 to 4000 :=3034; low4 : integer range 1000 to 4000 :=2863; low5 : integer range 1000 to 4000 :=2551; low6 : integer range 1000 to 4000 :=2273; low7 : integer range 1000 to 4000 :=2025;high1 : integer range 100 to 4000 :=956; high2 : integer range 100 to 4000 :=851; high3 : integer range 100 to 4000 :=758; high4 : integer range 100 to 4000 :=716; high5 : integer range 100 to 4000 :=638; high6 : integer range 100 to 4000 :=568;high7 : integer range 100 to 4000 :=506);port(clk : in std_logic;start : in std_logic;out_sound : out std_logic;sel : in std_logic;sound : out std_logic_vector(2 downto 0));end music;architecture behav of music issignal clk_4Hz : std_logic;signal count : integer range 0 to 4096;signal freq : integer range 0 to 4096;signal counter : integer range 0 to 100;signal max_250000 : std_logic_vector(17 downto 0); --signal max_250000 : std_logic_vector(3 downto 0);beginprocess(start,clk)beginif start='0' thenclk_4Hz<='0';max_250000<="000000000000000000";--max_250000<="0000";elsif clk'event and clk='1' thenif max_250000>="111101000010001111" then--if max_250000>="1111" thenmax_250000<="000000000000000000";--max_250000<="0000";else max_250000<=max_250000+1;end if;if max_250000="000000000000000000" then--if max_250000="0000" thenclk_4Hz<='1';else clk_4Hz<='0';end if;end if;end process;process(clk_4Hz,start)beginif start='0' thencounter<=0;elsif clk_4Hz'event and clk_4Hz='1' then if counter>=21 then--if counter>=7 thencounter<=0;elsecounter<=counter+1;end if;end if;end process;process(counter)begincase counter is--when 0=>freq<=mid1;sound<="001"; --when 1=>freq<=mid2;sound<="010";--when 3=>freq<=mid4;sound<="100"; --when 4=>freq<=mid5;sound<="101"; --when 5=>freq<=mid6;sound<="110"; --when 6=>freq<=mid7;sound<="111"; --when 7=>freq<=high1;sound<="001";when 0=>freq<=low5;sound<="101"; when 1=>freq<=mid1;sound<="001"; when 2=>freq<=mid1;sound<="001"; when 3=>freq<=mid1;sound<="001"; when 4=>freq<=mid1;sound<="001"; when 5=>freq<=mid3;sound<="011"; when 6=>freq<=mid2;sound<="010"; when 7=>freq<=mid1;sound<="001"; when 8=>freq<=mid2;sound<="010"; when 9=>freq<=mid3;sound<="011"; when 10=>freq<=mid1;sound<="001"; when 11=>freq<=mid1;sound<="001"; when 12=>freq<=mid3;sound<="011"; when 13=>freq<=mid5;sound<="101"; when 14=>freq<=mid6;sound<="110";when 16=>freq<=mid6;sound<="110"; when 17=>freq<=mid5;sound<="101"; when 18=>freq<=mid3;sound<="011"; when 19=>freq<=mid3;sound<="011"; when 20=>freq<=mid1;sound<="001";when others=>freq<=0;sound<="000"; end case;end process;process(clk,start,sel)beginif sel='0' then out_sound<='0';elseif start='0' thencount<=0;out_sound<='0';elsif clk'event and clk='1' thenif freq=0 then out_sound<='0';elsif count=0 thencount<=freq;out_sound<='1';elsecount<=count-1;out_sound<='0';end if;end if;end if;end process;end behav;piano.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity piano isport(clk,start : in std_logic;KBCol : in std_logic_vector(3 downto 0);KBRow : out std_logic_vector(3 downto 0);out_sound : out std_logic;seg4 : out std_logic_vector(3 downto 0);sel : in std_logic;--key : out std_logic_vector(4 downto 0); sound : out std_logic_vector(2 downto 0));end entity;architecture behav of piano issignal state : std_logic_vector(2 downto 0);signal clk1 : std_logic;signal d : std_logic_vector(4 downto 0);signal d0,d1,d2,d3,d_reg : std_logic_vector(4 downto 0);signal snote : std_logic_vector(4 downto 0);signal sscal : std_logic_vector(1 downto 0);signal cnt,scnt : std_logic_vector(13downto 0); signal ctrln : std_logic_vector(2 downto 0);signal count,freq : integer range 0 to 4096;constant low1 : integer :=3822; constant low2 : integer :=3405; constant low3 : integer :=3034; constant low4 : integer :=2863; constant low5 : integer :=2551; constant low6 : integer :=2273; constant low7 : integer :=2025; --constant mid1 : integer :=2; constant mid1 : integer :=1911; constant mid2 : integer :=1703; constant mid3 : integer :=1517; constant mid4 : integer :=1432; constant mid5 : integer :=1276; constant mid6 : integer :=1137; constant mid7 : integer :=1012; constant high1 : integer :=956; constant high2 : integer :=851; constant high3 : integer :=758; constant high4 : integer :=716; constant high5 : integer :=638; constant high6 : integer :=568;constant stop : integer :=0;begin--clk1<=cnt(9);--process(clk)--begin--if clk'event and clk='1' then--cnt<=cnt+1;--end if;--end process;process(start,clk)--扫描时钟100Hz,由1MHz分频beginif start='0' thenclk1<='0';cnt<="00000000000000";elsif clk'event and clk='1' thenif cnt>="10011100001111" thencnt<="00000000000000";elsecnt<=cnt+1;end if;if cnt="00000000000000" thenclk1<='1';else clk1<='0';end if;end if;end process;d<=d0 or d1 or d2 or d3;process(clk1)beginif clk1'event and clk1='1' thencase state iswhen "000"=>KBRow<="1110";state<="001"; case KBCol iswhen "1110"=>d0<="11111";seg4<="1111";--Fwhen "1101"=>d0<="11011";seg4<="1011";--B when "1011"=>d0<="10111";seg4<="0111";--7 when "0111"=>d0<="10011";seg4<="0011";--3 when others=>d0<="00000";end case;when "001"=>KBRow<="1101";state<="010"; case KBCol iswhen "1110"=>d1<="11110";seg4<="1110";--Ewhen "1101"=>d1<="11010";seg4<="1010";--A when "1011"=>d1<="10110";seg4<="0110";--6 when "0111"=>d1<="10010";seg4<="0010";--2 when others=>d1<="00000";end case;when "010"=>KBRow<="1011";state<="011"; case KBCol iswhen "1110"=>d2<="11101";seg4<="1101";when "1101"=>d2<="11001";seg4<="1001";when "1011"=>d2<="10101";seg4<="0101";when "0111"=>d2<="10001";seg4<="0001";when others=>d2<="00000";end case;when "011"=>KBRow<="0111";state<="100"; case KBCol iswhen "1110"=>d3<="11100";seg4<="1100";when "1101"=>d3<="11000";seg4<="1000";when "1011"=>d3<="10100";seg4<="0100";when "0111"=>d3<="10000";seg4<="0000";when others=>d3<="00000";end case;when "100"=>state<="000";if d="00000" thend_reg<=d;if scnt=200 thensnote<="00000";elsescnt<=scnt+1;end if;elsescnt<="00000000000000";if d/=d_reg thend_reg<=d;if d>="10001" and d<="10111" thensnote<=sscal&d(2 downto 0);elsif d="11010" thensscal<="11";elsif d="11011" thensscal<="10";elsif d="11100" thensscal<="01";end if;end if;end if;when others=>state<="000";end case;end if;end process;process(snote)begincase snote iswhen "01001"=>freq<=low1;sound<="001";when "01010"=>freq<=low2;sound<="010";when "01011"=>freq<=low3;sound<="011";when "01100"=>freq<=low4;sound<="100";when "01101"=>freq<=low5;sound<="101";when "01110"=>freq<=low6;sound<="110";when "01111"=>freq<=low7;sound<="111";when "10001"=>freq<=mid1;sound<="001";when "10010"=>freq<=mid2;sound<="010";when "10011"=>freq<=mid3;sound<="011";when "10100"=>freq<=mid4;sound<="100";when "10101"=>freq<=mid5;sound<="101";when "10110"=>freq<=mid6;sound<="110";when "10111"=>freq<=mid7;sound<="111";when "11001"=>freq<=high1;sound<="001";when "11010"=>freq<=high2;sound<="010";when "11011"=>freq<=high3;sound<="011";when "11100"=>freq<=high4;sound<="100";when "11101"=>freq<=high5;sound<="101";when "11110"=>freq<=high6;sound<="110";when "11111"=>freq<=high7;sound<="111";when others =>freq<=stop;sound<="111"; end case;--key<=snote;end process;process(clk,sel,start)beginif sel='1' or start='0' thenout_sound<='0';elseif clk'event and clk='1' then if freq=0 thenout_sound<='0';elsif count=0 thencount<=freq;out_sound<='1';elsecount<=count-1;out_sound<='0';end if;end if;end if;end process;end behav;flower.vhdlibrary ieee;use ieee.std_logic_1164.all; entity flower isport(--clk : in std_logic;clr : in std_logic;--led : out std_logic_vector(15 downto 0);led : out std_logic_vector(6 downto 0);state : in std_logic_vector(2 downto 0));end flower;architecture behav of flower issignal current_state : std_logic_vector(2 downto 0);--signal flower : std_logic_vector(15 downto 0);signal flower : std_logic_vector(6 downto 0);begin--process(clr,clk)process(clr,state)--constant f1 : std_logic_vector(15 downto 0):="0001000100010001";--constant f2 : std_logic_vector(15 downto 0):="1010101010101010";--constant f3 : std_logic_vector(15 downto 0):="0011001100110011";--constant f4 : std_logic_vector(15 downto 0):="0100100100100100";--constant f5 : std_logic_vector(15 downto 0):="1001010010100101";--constant f6 : std_logic_vector(15 downto 0):="1101101101100110";--constant f7 : std_logic_vector(15 downto 0):="0111011101110111";constant f1 : std_logic_vector(6 downto 0):="0000001";constant f2 : std_logic_vector(6 downto 0):="0000011";constant f3 : std_logic_vector(6 downto 0):="0000111";constant f4 : std_logic_vector(6 downto 0):="0001111";constant f5 : std_logic_vector(6 downto 0):="0011111";constant f6 : std_logic_vector(6 downto 0):="0111111";constant f7 : std_logic_vector(6 downto 0):="1111111";begincurrent_state<=state;if clr='1' then--flower<="0000000000000000";flower<="0000000";--elsif rising_edge(clk) thenelsecase current_state is--when "000" =>flower<="0000000000000000";when "000" =>flower<="0000000";when "001" =>flower<=f1;when "010" =>flower<=f2;when "011" =>flower<=f3;when "100" =>flower<=f4;when "101" =>flower<=f5;when "110" =>flower<=f6;when "111" =>flower<=f7;--when others =>flower<="0000000000000000";when others =>flower<="0000000";end case;end if;end process;led<=flower;end behav;连接图。

相关主题