設計背景:
FPGA的學習也算是是一種日積月累才能有成就的過程,前面我們學習了各個模塊,各個芯片的配置等等,之后筆者通過兩個簡單的例子來讓大家去系統的學習和認識FPGA。所學習的電子琴設計也算是一次簡單的各個模塊的聯系調用的一個過程,對以后工作中的學習有很好的幫助。
設計原理:
本次的設計主要是通過控制ps2鍵盤來使蜂鳴器發出哆來咪法嗦拉西7種音來,音符主要又高低音等等,本設計只選擇發出高音的多來咪發嗦啦西。本設計中還用到了VGA的設計,通過VGA來在顯示屏上畫出如下圖的黑白的電子琴鍵:
當按下多來咪發嗦啦西時,對應的鍵值變顏色表示按下,不變色表示不按下,顏色自己可以調節,但是琴的按鍵必須為黑白色來顯示出來。
當按下按鍵的時候,蜂鳴器來鳴響對應時間的音符,本設計蜂鳴器響的時間為0.25S一個音符持續的時間。
本次設計用到的PS2和VGA的設計原理筆者在這里就不過多的介紹了,不明白的可以翻看前面發的文檔內容。
在本設計中介紹蜂鳴器的使用和各音符發聲的頻率大小。本設計用的是無源蜂鳴器,原理圖如下:
由于FPGA的驅動能力不夠,我們添加了一個三極管來驅動這個無源蜂鳴器,而無源蜂鳴器的主要特點是內部不帶振蕩源,所以如果使用直流信號是無法使無源蜂鳴器鳴叫的,必須使用方波去驅動它。
現在我們明白了,只要往蜂鳴器發送一定頻率的方波,就可以使得蜂鳴器發出聲音,然后現在的問題是,我們究竟要往蜂鳴器發送什么頻率的方波信號呢?具體的頻率可以查看下圖:
現在我們知道了如何讓蜂鳴器響起,又知道發送什么頻率可以讓蜂鳴器響起什么的聲音,所以我相信我們已經有能力讓蜂鳴器響起我們需要的音樂了。
設計架構圖:
設計代碼:
頂層模塊
0modulemusic_ps2(clk,rst_n,hs,vs,r_g_b,ps2_clk,ps2_data,beep);
1
2 inputclk;
3 inputrst_n;
4
5 outpuths;
6 outputvs;
7 output[7:0]r_g_b;
8 outputbeep;
9
10 inputps2_clk;
11 inputps2_data;
12
13 wireflag;
14 wire[7:0]data,data_n;
15 wireclk_1M;
16
17
18 frenp frep_dut(
19 .clk(clk),
20 .rst_n(rst_n),
21 .clk_1M(clk_1M)
22 );
23
24 ps2_rec rec_dut(
25 .clk(clk_1M),
26 .rst_n(rst_n),
27 .ps2_clk(ps2_clk),
28 .ps2_data(ps2_data),
29 .flag(flag),
30 .data(data)
31 );
32
33 decode decode_dut(
34 .clk(clk_1M),
35 .rst_n(rst_n),
36 .flag(flag),
37 .data(data),
38 .data_n(data_n)
39 );
40
41 music music_dut(
42 .clk(clk_1M),
43 .rst_n(rst_n),
44 .data_n(data_n),
45 .beep(beep)
46 );
47
48 vga vga_dut(
49 .clk(clk),
50 .rst_n(rst_n),
51 .hs(hs),
52 .vs(vs),
53 .r_g_b(r_g_b),
54 .data_n(data_n)
55 );
56
57endmodule
蜂鳴器模塊
0modulemusic(clk,rst_n,data_n,beep);端口列表
1
2 inputclk;
3 inputrst_n;
4 input[7:0]data_n;//輸入的鍵值
5 outputregbeep;//蜂鳴器
6
7 reg[10:0]music_data;
8 wire[10:0]data;
9
10 always@(posedgeclk)
11 if(!rst_n)
12 begin
13 music_data <=0;
14 end
15 else
16 case(data_n)
17 1 : music_data <=478;//蜂鳴器的高音1
18 2 : music_data <=425; //蜂鳴器的高音2
19 3 : music_data <=379; //蜂鳴器的高音3
20 4 : music_data <=358;//蜂鳴器的高音4
21
22 5 : music_data <=319; //蜂鳴器的高音5
23 6 : music_data <=284; //蜂鳴器的高音6
24 7 : music_data <=253; //蜂鳴器的高音7
25 default:music_data <=0;
26 endcase
27
28
29 reg[20:0]count,cnt;
30
31 always@(posedgeclk)
32 if(!rst_n &&!data_n)
33 begin
34 count <=0;
35 end
36 else
37 if(count <250_000-1)
38 begin
39 count <=count +1;
40 end
41 else
42 begin
43 count <=0;
44 end
45
46 //計數0.25S的時間
47 assigndata =(count ==250_000-1)?music_data :data;
48
49 always@(posedgeclk)
50 if(!rst_n)
51 begin
52 cnt <=1;
53 beep <=0;
54 end
55 else
56 if(data ==0)//控制蜂鳴器不響
57 begin
58 cnt <=1;
59 beep <=0;
60 end
61 elseif(cnt <data)//計數對應的頻率
62 begin
63 cnt <=cnt +1;
64 end
65 else
66 begin
67 cnt <=1;//蜂鳴器響
68 beep <=~beep;
69 end
70
71
72
73endmodule
代碼驗證正確無誤,筆者在這邊就不過多的驗證,大家可以自主的補全代碼,后續代碼會在論壇中發出來供大家參考個學習。
-
FPGA
+關注
關注
1629文章
21748瀏覽量
603795
發布評論請先 登錄
相關推薦
評論