简易电子琴
1.
任务及
(1)设计一个简易电子琴。
(2)产生 C调音符 1,2,3,4,5,6,7,高音 1和低音 6,7。
(3)自动播放一首乐曲。
2.可选器件
EPM7128S,4×4键盘,74LS04,喇叭,开关,电阻和电容。
3.总体框图
控制电路
时钟输入 分频电路
防抖动电路
键盘译码
控制分频
电路
音符分频
电路
4.源程序
(1)上层模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_unsigned.all;
entity em_player is
port(clk1M:in std_logic;
x : in std_logic_vector(3 downto 0);
y :out std_logic_vector(3 downto 0);
musicout:out std_logic);
end em_player;
architecture a of em_player is
component fenpin
port(clk1M :in std_logic;
clk100k,clk195,clk98,clk8: out std_logic;
cp2out: out std_logic_vector(1 downto 0);
cp4out: out std_logic_vector(3 downto 0));
end component;
component fangdou
port(clk98in: in std_logic;
key_in: in std_logic;
key_out: out std_logic);
end component;
component yima
port(clk98in: in std_logic;
Cp2in : in std_logic_vector(1 downto 0);
Cp4in : in std_logic_vector(3 downto 0);
Num_dec,music_dec: out std_logic_vector(3 downto 0);
Num_f,music_f: out std_logic);
end component;
component ctr1
port(clk98in1,clk8in: in std_logic;
num_dec,music_dec_in: in std_logic_vector(3 downto 0);
num_f_in,music_f_in: in std_logic;
index_out:out integer range 0 to 10);
end component;
component tone
port(index :in integer range 0 to 10;
toneout:out integer range 770 to 1024);
end component;
component speaker
port(clk100in: in std_logic;
tone_in: in integer range 770 to 1024;
soundout:out std_logic);
end component;
signal tone1 : integer range 770 to 1024;
signal index : integer range 0 to 10;
signal key_y,key_x,key_dec: std_logic_vector(3 downto 0);
signal numdec,musicdec : std_logic_vector(3 downto 0);
signal cp2: std_logic_vector(1 downto 0);
signal numf,musicf: std_logic;
signal clk_100k,clk_98: std_logic;
signal clk_195,clk_8: std_logic;
begin
key_x<=x;
u1:fenpin port map(clk1M,clk_100k,clk_195,clk_98,clk_8,cp2,key_y);
u2:fangdou port map(clk_195,key_x(0),key_dec(0));
u3:fangdou port map(clk_195,key_x(1),key_dec(1));
u4:fangdou port map(clk_195,key_x(2),key_dec(2));
u5:fangdou port map(clk_195,key_x(3),key_dec(3));
u6:yima port map(clk_98,cp2,key_dec,numdec,musicdec,numf,musicf);
u7:ctr1 port map(clk_98,clk_8,numdec,musicdec,numf,musicf,index);
u8:tone port map(index,tone1);
u9:speaker port map(clk_100k,tone1,musicout);
y<=key_y;
end;
(2)下层模块
1)分频模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity fenpin is
port(clk1M:in std_logic;
clk100k,clk195: out std_logic;
clk98,clk8:out std_logic;
cp2out:out std_logic_vector(1 downto 0);
cp4out: out std_logic_vector(3 downto 0));
end fenpin;
architecture a of fenpin is
signal counter : std_logic_vector(16 downto 0);
signal clk_100k: std_logic;
signal clk_8,clk_98,clk_195: std_logic;
signal cp2: std_logic_vector(1 downto 0);
signal cp4: std_logic_vector(3 downto 0);
begin
p1:process(clk1M)
variable count:integer range 0 to 9;
begin
if clk1M'event and clk1M='1'THEN
if count=9 then clk_100k<='1';
count:=0;
else count:=count+1;
clk_100k<='0';
end if;
end if;
end process p1;
clk100k<= clk_100k;
p2:process(clk_100k)
variable count1: integer range 0 to 12500;
begin
if clk_100k'event and clk_100k='1'then
if count1=12500 then clk_8<='1';
count1:=0;
else count1:= count1+1;
clk_8<='0';
end if;
end if;
end process p2;
clk8<=clk_8;
2)防抖动模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity fangdou is
port(clk195in:in std_logic;
key_in: in std_logic;
key_out: out std_logic);
end fangdou;
architecture a of fangdou is
signal q1,q2,q: std_logic;
begin
process(clk195in)
begin
if(clk195in'event and clk195in='1')then
q1<=key_in;
end if;
if(clk195in'event and clk195in='1')then
q2<=q1;
end if;
if(q='1')then
q<=q1 or q2;
else
q<=q1 and q2;
end if;
end process;
key_out<=q;
end;
3)键盘译码模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity yima is
port(clk98in :in std_logic;
cp2in :in std_logic_vector(1 downto 0);
cp4in :in std_logic_vector(3 downto 0);
num_dec,music_dec:out std_logic_vector(3 downto 0);
num_f,music_f:out std_logic);
end yima;
architecture a of yima is
signal numf,musicf: std_logic;
signal z:std_logic_vector(5 downto 0);
signal numdec,musicdec:std_logic_vector(3 downto 0);
begin
process(clk98in)
begin
z<=cp2in&cp4in;
if(clk98in'event and clk98in='1')then
case z is
when "000111"=>numdec<="0001";
when "001011"=>numdec<="0010";
when "001101"=>numdec<="0011";
when "001110"=>numdec<="0100";
when "010111"=>numdec<="0101";
when "011011"=>numdec<="0110";
when "011101"=>numdec<="0111";
when "011110"=>numdec<="1000";
when "100111"=>numdec<="1001";
when "101011"=>numdec<="1010";
when others=>numdec<="1111";
end case;
end if;
if(clk98in'event and clk98in='1')then
case z is
when "101101"=>musicdec<="0100";
when"101110"=>musicdec<="0001";
when others=>musicdec<="1000";
end case;
end if;
end process;
numf<=not(numdec(3) and numdec(2) and numdec(1) and numdec(0));
musicf<=(not musicdec(3) and musicdec(2) and not musicdec(1)and not
musicdec(0)) or (not musicdec(3) and not musicdec(2) and not musicdec(1) and
musicdec(0));
num_f<=numf;
music_f<=musicf;
num_dec<=numdec;
music_dec<=musicdec;
end;
4)控制模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity ctrl is
port(clk98inl,clk8in:in std_logic;
num_dec_in,music_dec_in:in std_logic_vector(3 downto 0);
num_f_in,music_f_in:in std_logic;
index_out:out integer range 0 to 10);
end ctrl;
architecture a of ctrl is
signal num,music:std_logic_vector(3 downto 0);
signal f_num:std_logic;
signal f_music:std_logic;
signal counter1:integer range 0 to 119;
signal counter2:integer range 0 to 16;
signal index_pu:integer range 0 to 10;
signal index_qin:integer range 0 to 10;
signal start:std_logic;
begin
num<=num_dec_in;
music<=music_dec_in;
f_num<=num_f_in;
f_music<=music_f_in;
p1:
process(clk8in)
begin
if counter1=119 then
counter1<=0;
else
if(clk8in'event and clk8in='1')then
counter1<=counter1+1;
end if;
end if;
end process p1;
p2:
process(clk98inl)
begin
if clk98inl'event and clk98inl='1'then
if f_num='1'then
case num is
when"0001"=>index_qin<=1;
counter2<=16;
when"0010"=>index_qin<=2;
counter2<=16;
when"0011"=>index_qin<=3;
counter2<=16;
when"0100"=>index_qin<=4;
counter2<=16;
when"0101"=>index_qin<=5;
counter2<=16;
when"0110"=>index_qin<=6;
counter2<=16;
when"0111"=>index_qin<=7;
counter2<=16;
when"1000"=>index_qin<=8;
counter2<=16;
when"1001"=>index_qin<=9;
counter2<=16;
when"1010"=>index_qin<=10;
counter2<=16;
when others =>null;
end case;
end if;
if f_music='1'and music="0100"then
start<='1';
else
if f_music='1'and music="0001"then
start<='0';
end if;
end if;
if start='1'then
case counter1 is
when 0 =>index_pu<=10;
when 1 =>index_pu<=10;
when 2 =>index_pu<=1;
when 3 =>index_pu<=1;
when 4 =>index_pu<=3;
when 5 =>index_pu<=3;
when 6 =>index_pu<=1;
when 7 =>index_pu<=1;
when 8 =>index_pu<=2;
when 9 =>index_pu<=2;
when 10 =>index_pu<=2;
when 11 =>index_pu<=2;
when 12 =>index_pu<=1;
when 13 =>index_pu<=1;
when 14 =>index_pu<=9;
when 15 =>index_pu<=9;
when 16 =>index_pu<=3;
when 17 =>index_pu<=3;
when 18 =>index_pu<=3;
when 19 =>index_pu<=3;
when 20 =>index_pu<=2;
when 21 =>index_pu<=2;
when 22 =>index_pu<=2;
when 23 =>index_pu<=2;
when 24 =>index_pu<=10;
when 25 =>index_pu<=10;
when 26 =>index_pu<=10;
when 27 =>index_pu<=10;
when 28 =>index_pu<=10;
when 29 =>index_pu<=10;
when 30 =>index_pu<=10;
when 31 =>index_pu<=10;
when 32 =>index_pu<=10;
when 33 =>index_pu<=10;
when 34 =>index_pu<=1;
when 35 =>index_pu<=1;
when 36 =>index_pu<=3;
when 37 =>index_pu<=3;
when 38 =>index_pu<=5;
when 39 =>index_pu<=5;
when 40 =>index_pu<=5;
when 41 =>index_pu<=5;
when 42 =>index_pu<=6;
when 43 =>index_pu<=6;
when 44 =>index_pu<=6;
when 45 =>index_pu<=6;
when 46 =>index_pu<=5;
when 47 =>index_pu<=5;
when 48 =>index_pu<=4;
when 49 =>index_pu<=4;
when 50 =>index_pu<=3;
when 51 =>index_pu<=3;
when 52 =>index_pu<=3;
when 53 =>index_pu<=3;
when 54 =>index_pu<=3;
when 55 =>index_pu<=3;
when 56 =>index_pu<=3;
when 57 =>index_pu<=3;
when 58 =>index_pu<=4;
when 59 =>index_pu<=4;
when 60 =>index_pu<=4;
when 61 =>index_pu<=4;
when 62 =>index_pu<=5;
when 63 =>index_pu<=5;
when 64 =>index_pu<=5;
when 65 =>index_pu<=5;
when 66 =>index_pu<=7;
when 67 =>index_pu<=7;
when 68 =>index_pu<=6;
when 69 =>index_pu<=6;
when 70 =>index_pu<=3;
when 71 =>index_pu<=3;
when 72 =>index_pu<=3;
when 73 =>index_pu<=3;
when 74 =>index_pu<=3;
when 75 =>index_pu<=3;
when 76 =>index_pu<=9;
when 77 =>index_pu<=9;
when 78 =>index_pu<=10;
when 79 =>index_pu<=10;
when 80 =>index_pu<=3;
when 81 =>index_pu<=3;
when 82 =>index_pu<=3;
when 83 =>index_pu<=2;
when 84 =>index_pu<=4;
when 85 =>index_pu<=4;
when 86 =>index_pu<=4;
when 87 =>index_pu<=4;
when 88 =>index_pu<=4;
when 89 =>index_pu<=4;
when 90 =>index_pu<=4;
when 91 =>index_pu<=4;
when 92 =>index_pu<=5;
when 93 =>index_pu<=5;
when 94 =>index_pu<=5;
when 95 =>index_pu<=5;
when 96 =>index_pu<=3;
when 97 =>index_pu<=3;
when 98 =>index_pu<=3;
when 99 =>index_pu<=3;
when 100 =>index_pu<=2;
when 101 =>index_pu<=2;
when 102 =>index_pu<=1;
when 103 =>index_pu<=1;
when 104 =>index_pu<=3;
when 105 =>index_pu<=3;
when 106 =>index_pu<=3;
when 107 =>index_pu<=3;
when 108 =>index_pu<=2;
when 109 =>index_pu<=2;
when 110 =>index_pu<=2;
when 111 =>index_pu<=2;
when 112 =>index_pu<=10;
when 113 =>index_pu<=10;
when 114 =>index_pu<=10;
when 115 =>index_pu<=10;
when 116 =>index_pu<=10;
when 117 =>index_pu<=10;
when 118 =>index_pu<=10;
when 119 =>index_pu<=10;
end case;
else
if(counter2>0)then
counter2<=counter2-1;
index_pu<=index_qin;
else
index_pu<=0;
end if;
end if;
end if;
end process p2;
index_out<=index_pu;
end;
5)控制分频模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity tone is
port(index:in integer range 0 to 10;
toneout:out integer range 770 to 1024);
end tone;
architecture a of tone is
signal tone1:integer range 770 to 1024;
signal index1:integer range 0 to 10;
begin
index1<=index;
process
begin
case index1 is
when 0 =>tone1<=1024;
when 1 =>tone1<=834;
when 2 =>tone1<=855;
when 3 =>tone1<=873;
when 4 =>tone1<=882;
when 5 =>tone1<=897;
when 6 =>tone1<=911;
when 7 =>tone1<=924;
when 8 =>tone1<=930;
when 9 =>tone1<=822;
when 10 =>tone1<=798;
when others=>null;
end case;
end process;
toneout<=tone1;
end;
6)音符分频模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity speaker is
port(clk100kin:in std_logic;
tone_in:in integer range 770 to 1024;
soundout:out std_logic);
end speaker;
architecture a of speaker is
signal sound1,sound2:std_logic;
signal tone:integer range 770 to 1024;
begin
tone<=tone_in;
p1: process(clk100kin,tone)
variable count:integer range 770 to 1024;
begin
if clk100kin'event and clk100kin='1'then
if count=1024 then
count:=tone;
sound1<='0';
else
count:=count+1;
end if;
end if;
end process p1;
p2:
process(sound1)
variable count2:std_logic;
begin
if sound1'event and sound1='1' then
sound2<=not sound2;
end if;
end process p2;
soundout<=sound2;
end;