zoukankan      html  css  js  c++  java
  • 【连载】 FPGA Verilog HDL 系列实例乐曲演奏

    【连载】 FPGA Verilog HDL 系列实例  

    Verilog HDL 之 乐曲演奏

      我们都知道,乐曲由音调和音长组成,只要将音调和音长控制好就能演奏出动听的乐曲。下面将用Verilog HDL 硬件描述语言完成乐曲演奏的设计。

    1、音调的控制

      频率的高低决定了音调的高低。图1.1是音调和音律之间的关系。

                          图1.1 音调和音律之间的关系

      所有不同频率的信号都是从同一个基准频率分频得来的。由于音阶频率多为非整数,而分频系数又不能为小数,故必须将计算得到的分频数四舍五入取整。若基准频率过低,则由于分频比太小,四舍五入取证后的误差较大。若基准频率过高,虽然误差变小,但分频数将变大。实际的设计应综合考虑两方面的因素,在尽量减小频率误差的前提下去合适的基准频率。

      本例中需要演奏的是梁祝,该乐曲各音阶频率及相应的分频比如图1.2所示。

     

                           图1.2 乐曲各音阶频率及相应的分频比

      在表中除了给出分频比外,还给出了对应与各个音阶频率时计数器不同的预置数。对于不同的分频系数,只要加载不同的预置数即可。采用加载预置数实现分频的方法比采用反馈复零法节省资源,实现起来更容易。

     2、音长的控制


      音符的持续时间须根据乐曲的速度及每个音符的节拍数来确定。
      本实验中演奏梁祝片断,最短的音符为四分音符。


    3、乐曲演奏电路的原理框图

     

                      图1.3  乐曲演奏电路的原理框图 

      其中,乐谱产生电路用来控制音乐的音调和音长。控制音调通过设置计数器的预置数来实现,预置不同的数值可以使计数器产生不同频率的信号,从而产生不同的音调。控制音长是通过控制计数器预置数停留时间来实现,每个音符的演奏时间是0.25S的整数倍,对于节拍较长的音符,如二分音符。在记谱时将分别连续记录两次即可。

    实验实现:

      详细实现步骤请参考  【连载】 FPGA Verilog HDL 系列实例--------8-3编码器

    (1)在设计文件中输入Verilog代码。

      1 //--------------------------------------------------------------------------------------------------
    2 //
    3 // Title : play
    4 // Author : wangliang
    5 //
    6 //-------------------------------------------------------------------------------------------------
    7 //-------------------------------------------------------------------------------------------------
    8 //
    9 // Description :
    10 //
    11 //-------------------------------------------------------------------------------------------------
    12 `timescale 1 ns / 1 ps
    13
    14 module play ( audio , sys_CLK , button);
    15
    16 output audio;
    17 input sys_CLK;
    18 input button;
    19
    20 reg [23:0] counter4Hz,
    21 counter6MHz;
    22 reg [13:0] count,origin;
    23 reg audiof;
    24
    25 reg clk_6MHz,
    26 clk_4Hz;
    27
    28 reg [4:0] j;
    29 reg [7:0] len;
    30
    31
    32 assign audio= button? audiof : 1'b1 ; //控制开关
    33
    34 always @(posedge sys_CLK) //6MHz分频
    35 begin
    36 if(counter6MHz==4)
    37 begin
    38 counter6MHz=0;
    39 clk_6MHz=~clk_6MHz;
    40 end
    41 else
    42 begin
    43 counter6MHz=counter6MHz+1;
    44 end
    45 end
    46
    47 always @(posedge sys_CLK) //4Hz分频
    48 begin
    49 if(counter4Hz==6250000)
    50 begin
    51 counter4Hz=0;
    52 clk_4Hz=~clk_4Hz;
    53 end
    54 else
    55 begin
    56 counter4Hz=counter4Hz+1;
    57 end
    58 end
    59
    60
    61 always @(posedge clk_6MHz)
    62 begin
    63 if(count==16383)
    64 begin
    65 count=origin;
    66 audiof=~audiof;
    67 end
    68 else
    69 count=count+1;
    70 end
    71
    72
    73 always @(posedge clk_4Hz)
    74 begin
    75 case(j)
    76 'd1:origin='d4916; //low
    77 'd2:origin='d6168;
    78 'd3:origin='d7281;
    79 'd4:origin='d7791;
    80 'd5:origin='d8730;
    81 'd6:origin='d9565;
    82 'd7:origin='d10310;
    83 'd8:origin='d010647; //middle
    84 'd9:origin='d011272;
    85 'd10:origin='d011831;
    86 'd11:origin='d012087;
    87 'd12:origin='d012556;
    88 'd13:origin='d012974;
    89 'd14:origin='d013346;
    90 'd15:origin='d13516; //high
    91 'd16:origin='d13829;
    92 'd17:origin='d14108;
    93 'd18:origin='d11535;
    94 'd19:origin='d14470;
    95 'd20:origin='d14678;
    96 'd21:origin='d14864;
    97 default:origin='d011111;
    98 endcase
    99 end
    100
    101 always @(posedge clk_4Hz) //乐谱
    102 begin
    103 if(len==63)
    104 len=0;
    105 else
    106 len=len+1;
    107 case(len)
    108 0:j=3;
    109 1:j=3;
    110 2:j=3;
    111 3:j=3;
    112 4:j=5;
    113 5:j=5;
    114 6:j=5;
    115 7:j=6;
    116 8:j=8;
    117 9:j=8;
    118 10:j=8;
    119 11:j=6;
    120 12:j=6;
    121 13:j=6;
    122 14:j=6;
    123 15:j=12;
    124 16:j=12;
    125 17:j=12;
    126 18:j=15;
    127 19:j=15;
    128 20:j=15;
    129 21:j=15;
    130 22:j=15;
    131 23:j=9;
    132 24:j=9;
    133 25:j=9;
    134 26:j=9;
    135 27:j=9;
    136 28:j=9;
    137 29:j=9;
    138 30:j=9;
    139 31:j=9;
    140 32:j=9;
    141 33:j=9;
    142 34:j=10;
    143 35:j=7;
    144 36:j=7;
    145 37:j=6;
    146 38:j=6;
    147 39:j=5;
    148 40:j=5;
    149 41:j=5;
    150 42:j=6;
    151 43:j=8;
    152 44:j=8;
    153 45:j=9;
    154 46:j=9;
    155 47:j=3;
    156 48:j=3;
    157 49:j=8;
    158 50:j=8;
    159 51:j=8;
    160 52:j=5;
    161 53:j=5;
    162 54:j=8;
    163 55:j=5;
    164 56:j=5;
    165 57:j=5;
    166 58:j=5;
    167 59:j=5;
    168 60:j=5;
    169 61:j=5;
    170 62:j=5;
    171 63:j=5;
    172 endcase
    173
    174 end
    175 endmodule

    (2)由设计文件生成的.bsf文件,乐曲演奏的外接接口如图1.4所示。

                图1.4  乐曲演奏的外接接口

    (3)分配引脚:

      将sys_CLK信号接时钟,button接按键,audio接蜂鸣器,这里就不贴出具体的引脚图了,大家可以根据自己的开发板对应起来。

    (4)实验结果:

      当打开按键时,就能听到完整的梁祝乐曲了。大家可以从网上下载自己喜欢的音乐,转化为可执行的乐谱。

    PS:本实验应用没有涉及到Nios II软核,可以跟我先前的一篇乐曲播放博文进行比较。Nios II实用之音频控制(里面的图看不见了,比较囧啊,但不影响对博文的阅读)


     

  • 相关阅读:
    中科燕园GIS外包--移动GIS
    创建二维数组
    DSP开发中遇到的问题
    Unity 2D游戏开发教程之精灵的死亡和重生
    Unity 2D游戏开发教程之摄像头追踪功能
    Unity 2D游戏开发教程之2D游戏的运行效果
    Unity 2D游戏开发教程之使用脚本实现游戏逻辑
    Kail Linux渗透测试教程之免杀Payload生成工具Veil
    Kail Linux渗透测试教程之在Metasploit中扫描
    Kail Linux渗透测试教程之网络扫描和嗅探工具Nmap
  • 原文地址:https://www.cnblogs.com/kongtiao/p/2111581.html
Copyright © 2011-2022 走看看