基于Basys2开发板的简易电子琴和音乐播放器设计

2023-04-28,,

背景:华中科技大学 电测综合实验

主要功能:Basys2开发板外接一个扬声器(或无源蜂鸣器也可)实现电子琴和音乐播放器的功能。其中由于开发板上只有4个按键,所以电子琴功能只做了4个音调,分别对应于4个轻触开关。音乐播放器功能需要根据挑选出来的乐谱,人工翻译为代码中对应的音调代码,然后输入到代码的状态机之中。两个功能分别采用两个不同的声道输出,因此两个功能互不干扰,可以同时进行。实现了一个符合综合实验要求的简单项目。因为没有队友,是一个人不到2天的时间赶出来的成果,所以比较简易,给需要的人做一个参考。

ISE工程文件(github链接)(包含实验报告):https://github.com/W-yt/YuTian_Pro/tree/master/piano%26palyer

以下直接粘贴课设报告的主要内容。

如有问题欢迎指正交流。

一、实验目的

1.熟练掌握Basys2的开发流程;

2.提高FPGA综合调试的能力;

二、实验选题及设计目标

实验选题:音乐播放器+电子琴(双声道)

项目目标:本项目要设计实现一个基于BASYS2的多功能电子琴,音乐播放和电子琴各占用一个声道的双声道电子琴。计划采用两个扬声器作为双声道的输出设备,利用拨码开关实现音乐播放器的控制,利用轻触开关实现电子琴的琴键(这里由于BASYS2开发板上只有4个轻触开关,因此电子琴部分仅选用了四个音,仅用来演示电子琴的实现原理,也可以外接按键,或者矩阵键盘拓展)。另外在程序中写定一个音乐的乐谱,实现音乐播放器的演示功能,如果时间允许,会在程序中存储多段音乐,使用拨码开关选择播放曲目。

三、硬件部分

    实验整体电路

2.扬声器简易驱动电路:

四、软件部分

1.系统主频

获取系统主频由开发板主频经过10分频得到:50MHz分频为5MHz

代码(digital_piano.v):

     /* 10分频:50MHz到5Mhz分频 */

         always@(posedge inclk)                           

         begin   

              if(cnt<3'd5)

              cnt <= cnt + 3'b1;

          else

                            begin

                            cnt <= 3'b0;

                            clk_5MHz <= ~clk_5MHz;

                            end

           end

2.电子琴子模块

读取输入的轻触按键的状态,决定声音频率,再通过计数器实现定频率方波的输出,作为扬声器的驱动信号。其中origin的值为根据各个音调对应的声音频率换算确定的。

代码(piano.v):

          /* piano子模块 */

         module piano(inclk, clk_5MHz, key_in, beep);

         input  inclk;                      //开发板主频

         input  clk_5MHz;             //系统时钟

         input [3:0]  key_in;         //轻触按键输入

         output  beep;                 //扬声器输出

         wire carry;

         reg beep_r;       

         assign beep = beep_r;       //输出音乐

         /* 按键转换音调输出 */

         always @ (posedge clk_5MHz)

                  begin

                            case (key_in[3:0])

                                     /* 消除不按时的噪声 */

                                     4'b0000: origin<=0000;

                                     4'b0001: origin<=6826;   // Hdo

                                     4'b0010: origin<=7871;   // Hre

                                     4'b0100: origin<=8798;   // Hmi

                                     4'b1000: origin<=9224;   // Hfa

                                     default: origin<=0000;

                            endcase

                  end

         assign carry=(count == 16383);

         /* 获取驱动信号 */

         always @(posedge clk_5MHz)

         begin 

                  if(key_in[3:0] == 4'b0000)

                            begin

                            end

                  else

                            if(carry)

                                     count = origin;

                            else

                                     count = count + 1;

         end

         /* 扬声器驱动 */

         always @(posedge carry)

         begin

                  beep_r<=~beep_r;

         end

         endmodule

3.音乐播放器子模块

音乐播放器子模块首先通过分频实现了一个低频时钟(这里采用5Hz),作为音乐的节拍器。然后调用按照程序翻译出来的曲谱函数(这里由于时间原因仅翻译了天空之城一首音乐的一部分)。

代码(song.v):

         module song(clk_5MHz, select, beep);

         input clk_5MHz;

         input select;               //音乐播放暂停选项                       

         output beep;              //蜂鸣器输出

         reg  [25:0] cnt2;     //计数器

         reg  clk_5Hz;

         wire  beep_r;

         wire out3;                  //曲谱的输出

         wire clk;

         assign beep = beep_r;

         /* 调用曲谱模块——模拟有限状态机实现 */

         /* 《天空之城》 */

         song3 m3(.clk_5MHz(clk_5MHz),.clk_4Hz(clk),.select(select),.beep(out3));

         assign beep_r = out3;

         assign clk = clk_5Hz;

         /* 5hz分频 */

         always@(posedge clk_5MHz)                  

         begin   

         //     if(select)

         //     begin

                            if(cnt2<25'd400000)

                                     cnt2 <= cnt2+25'b1;

                           else

                                     begin

                                     cnt2<=25'b0;

                                     clk_5Hz <= ~clk_5Hz;

                                     end

         //     end

         end

         endmodule

4.曲谱子模块

这里对天空之城曲谱的一部分进行了翻译,由于钢琴谱比较复杂,且一般为双手谱,这里选择了一个较为简单的吉他谱,按照吉他谱中的简谱进行逐拍翻译。

曲谱如下:

代码(song3.v):

        /* 《天空之城》 */

        module song3(clk_5MHz,clk_4Hz,select,beep);

        input clk_5MHz,clk_4Hz,select;   //系统时钟,节拍时钟,播放暂停选项

         output beep;                                          //扬声器输出 

         reg  [3:0] high,med,low;

         reg  [15:0] origin;

         reg    beep_r;                                            

         reg  [7:0] state;                                           

         reg  [15:0] count;                    

         assign beep = beep_r;           

         /* 扬声器基本驱动 */

         always @(posedge clk_5MHz)

         begin

                  /* 计数器 */

                  count <= count + 1'b1;             

                  If(count == origin)

                  begin

                   /* 计数器清零 */

                   count <= 16'h0;                          

                   /* 输出取反 */

                   beep_r <= !beep_r;            

                  end

         end

         /* 音调输出转换 */

         always@(posedge clk_4Hz)

         begin

                  if(select)

                  begin

                            case({high,med,low})

                                     /*  24音转换为方波频率 */

                                     'b000000000001:origin=22900; //低1

                                     'b000000000010:origin=20408; //低2

                                     'b000000000011:origin=18181; //低3

                                     'b000000000100:origin=17142; //低4

                                     'b000000000101:origin=15267; //低5

                                     'b000000000110:origin=13605; //低6

                                     'b000000000111:origin=12121; //低7

                                     'b000000010000:origin=11472; //中1

                                     'b000000100000:origin=10216; //中2

                                     'b000000110000:origin=9101;  //中3

                                     'b000000111000:origin=8571;  //中4

                                     'b000001010000:origin=7653;  //中5

                                     'b000001100000:origin=6818;  //中6

                                     'b000010000000:origin=6060;  //中7

                                     'b000100000000:origin=5733;  //高1

                                     'b001000000000:origin=5108;  //高2

                                     'b001100000000:origin=4551;  //高3

                                     'b001010000000:origin=4294;  //高4

                                     'b010000000000:origin=3826;  //高5

                                     'b011000000000:origin=3409;  //高6

                                     'b010100000000:origin=3050;  //高7

                            endcase

                  end

                  else

                            /* 消除杂音 */

                           origin=0000;

         end

         /* 《天空之城》乐谱翻译 */

         always @(posedge clk_4Hz)  

         begin

         if(select)

         begin

                  /* 全曲总节拍数 */

                  if(state ==193)

                           /* 自动重放 */

                           state = 0;

                  else

                           /* 节拍计数 */

                           state = state + 1'b1;

                  case(state)

                           /* 按小节间隔 */

                            /* 1 */

                            0:                                                                       {high,med,low}='b000001100000;//中6

                            1:                                                                       {high,med,low}='b000010000000;//中7              

                            /* 2 */

                            2,3,4:                                                                 {high,med,low}='b000100000000;//高1

                            5:                                                                       {high,med,low}='b000010000000;//中7

                            6,7:                                                              {high,med,low}='b000100000000;//高1

                            8,9:                                                                    {high,med,low}='b001100000000;//高3    

                            /* 3 */

                            10,11,12,13,14,15:                                        {high,med,low}='b000010000000;//中7

                            16,17:                                                high,med,low}='b000000110000;//中3

                            /* 4 */               

                            18,19,20:                                                          {high,med,low}='b000001100000;//中6

                            21:                                                                   {high,med,low}='b000001010000;//中5

                            22,23:                                              {high,med,low}='b000001100000;//中6

                            24,25:                                                               {high,med,low}='b000100000000;//高1

                            ………………………………..

                            /* 25 */

                            186,187,188,189,190,191,192,193:          {high,med,low}='b001100000000;//高3       

         endcase

end

end

endmodule

5.管脚定义

代码(digital_piano_ucf.ucf):

        NET "inclk"     LOC = "B8";                //开发板主频

         NET "select" LOC = "N3";                 //拨码开关作为播放器暂停选项

         /* 双声道输出:电子琴&音乐播放器,互不干扰

         NET "out_r"  LOC = "D12";              //右声道输出

         NET "out_l"  LOC = "C9";                  //左声道输出

         /* 电子琴演示琴键:轻触开关 */

         NET "key_in[3]" LOC = "G12";       

         NET "key_in[2]" LOC = "C11";

         NET "key_in[1]" LOC = "M4";

         NET "key_in[0]" LOC = "A7";

         NET "select" CLOCK_DEDICATED_ROUTE = FALSE;

如有问题欢迎指正交流。

——cloud over sky

——2020/1/18

基于Basys2开发板的简易电子琴和音乐播放器设计的相关教程结束。

《基于Basys2开发板的简易电子琴和音乐播放器设计.doc》

下载本文的Word格式文档,以方便收藏与打印。