STEP模块——电子琴
电子琴原理
什么是声音?上过初中的朋友都知道声音是由震动所产生的。一定频率的震动就产生了一定频率的声音。
理论研究第一步,让喇叭发出do re mi fa sol la si的音,我们先不管do的频率是不是261hz,更重要的是我们必须知道,每个音之间的频率关系,初中老师说,do re mi这三个音相邻两个音是全音关系,mi 和 fa 是半音关系,fa sol la si 这四个音相邻两个音也是全音关系。全音关系意味着振动频率关系为2的开六次方,即1.12246,半音关系意味着频率关系为2的开16次方,即1.05946。什么意思呢?比如do为261hz,那么re 为261*1.12246=293hz,以此类推,mi为293*1.12246=329hz,fa和mi成半音关系,则fa为329*1.05946=348hz。这样算下去,可以得到所有音的频率了。
原理设计
通过产生脉冲信号驱动无源蜂鸣器来产生相应频率的声音,7个按键对应do re mi fa sol la si的音,蜂鸣器由三极管驱动
如图,按键需要加上拉电阻(由于FPGA内部可以设置为上啦,所以没有外接 )。蜂鸣器由三极管来驱动。使用小脚丫FPGA板
功能描述
模式一,通过按键来弹奏,同时按下do 和 si 键切换到自动播放模式
模式二,自动播放音乐,
verilog代码如下
1 /*-------------------------------------------------------------------------------------- 2 -- Filename ﹕ piano.v 3 -- Author ﹕tony-ning 4 -- Description ﹕piano-based STEP PGGA board 5 -- Called by ﹕-- 6 -- Revision History ﹕15-10-26 7 -- Revision 1.0 8 -- 9 ---------------------------------------------------------------------------------------*/ 10 11 module piano 12 ( 13 input CLK, 14 input [7:1]key, 15 output reg beep 16 ); 17 /*-------------------------------define --------------------------------------*/ 18 parameter dao =7'b1111110; //261hz countmax 47892 19 parameter ruai=7'b1111101; //293hz countmax 42662 20 parameter mi =7'b1111011; //329hz countmax 37993 21 parameter fa =7'b1110111; //349hz countmax 35816 22 parameter suo =7'b1101111; //392hz countmax 31887 23 parameter la =7'b1011111; //440hz countmax 28409 24 parameter xi =7'b0111111; //493hz countmax 25354 25 26 reg [6:0]sheet[0:32]; 27 28 initial 29 begin 30 sheet[0]<= 7'b1111110; 31 sheet[1]<= 7'b1111110; 32 sheet[2]<= 7'b1101111; 33 sheet[3]<= 7'b1101111; 34 sheet[4]<= 7'b1011111; 35 sheet[5]<= 7'b1011111; 36 sheet[6]<= 7'b1101111; 37 sheet[7]<= 7'b1111111; 38 sheet[8]<= 7'b1110111; 39 sheet[9]<= 7'b1110111; 40 sheet[10]<=mi; 41 sheet[11]<=mi; 42 sheet[12]<=ruai; 43 sheet[13]<=ruai; 44 sheet[14]<=dao; 45 sheet[15]<=7'b1111111; 46 sheet[16]<=7'b1101111; 47 sheet[17]<=7'b1101111; 48 sheet[18]<=7'b1110111; 49 sheet[19]<=7'b1110111; 50 sheet[20]<=mi; 51 sheet[21]<=mi; 52 sheet[22]<=ruai; 53 sheet[23]<=7'b1111111; 54 sheet[24]<=7'b1101111; 55 sheet[25]<=7'b1101111; 56 sheet[26]<=7'b1110111; 57 sheet[27]<=7'b1110111; 58 sheet[28]<=mi; 59 sheet[29]<=mi; 60 sheet[30]<=dao; 61 sheet[31]<=7'b1111111; 62 end 63 /*-------------------------------use internal osc-------------------------------------- 64 // Internal Oscillator 65 defparam OSCH_inst.NOM_FREQ = "2.08";// This is the default frequency 66 //defparam OSCH_inst.NOM_FREQ = "24.18"; 67 OSCH OSCH_inst( .STDBY(1'b0), // 0=Enabled, 1=Disabled 68 // also Disabled with Bandgap=OFF 69 .OSC(osc_clk), 70 .SEDSTDBY()); // this signal is not required if not 71 // using SED 72 73 -------------------------------piano --------------------------------------*/ 74 reg [15:0]rcount=0,countmax,mcount; 75 reg run,state=0; 76 reg [8:0]num=0; 77 reg [6:0]rsheet; 78 always@(posedge CLK) 79 case(state) 80 0: begin 81 case(key) 82 dao : begin countmax<=47892; run<=1; if(countmax >47892)rcount<=0; end //set the max count 83 ruai: begin countmax<=42662; run<=1; if(countmax >42662)rcount<=0; end 84 mi : begin countmax<=37993; run<=1; if(countmax >37993)rcount<=0; end 85 fa : begin countmax<=35816; run<=1; if(countmax >35816)rcount<=0; end 86 suo : begin countmax<=31887; run<=1; if(countmax >31887)rcount<=0; end 87 la : begin countmax<=28409; run<=1; if(countmax >28409)rcount<=0; end 88 xi : begin countmax<=25354; run<=1; if(countmax >25354)rcount<=0; end 89 default : run<=0; 90 endcase 91 92 if(rcount==countmax && run) //produce the frequency 93 begin 94 rcount<=0; 95 beep<=~beep; 96 end 97 else rcount<=rcount+1; 98 99 if(key==7'b0111110) //push dao and xi keys will play the pre sound 100 state<=1; 101 102 end 103 104 1: begin 105 if(mcount==12_500_000) //meter produce 106 begin 107 mcount<=0; 108 if(num==31) 109 num<=0; 110 else num<=num+1; 111 rsheet<=sheet[num]; 112 end 113 else mcount<=mcount+1; 114 115 case(rsheet) 116 dao : begin countmax<=47892; run<=1; if(countmax >47892)rcount<=0; end //set the max count 117 ruai : begin countmax<=42662; run<=1; if(countmax >42662)rcount<=0; end 118 mi : begin countmax<=37993; run<=1; if(countmax >37993)rcount<=0; end 119 fa : begin countmax<=35816; run<=1; if(countmax >35816)rcount<=0; end 120 suo : begin countmax<=31887; run<=1; if(countmax >31887)rcount<=0; end 121 la : begin countmax<=28409; run<=1; if(countmax >28409)rcount<=0; end 122 xi : begin countmax<=25354; run<=1; if(countmax >25354)rcount<=0; end 123 default : run<=0; 124 endcase 125 126 if((rcount==countmax) && run) //produce the frequency 127 begin 128 rcount<=0; 129 beep<=~beep; 130 end 131 else rcount<=rcount+1; 132 133 134 if(key==7'b0111101) //push dao and la keys will back to make music 135 state<=0; 136 137 end 138 endcase 139 140 141 142 143 144 145 146 147 148 endmodule 149
PCB
实物图