当前位置:   article > 正文

FPGA项目(4)--基于FPGA的电子琴_fpga电子琴

fpga电子琴

        本次设计是基于FPGA的电子琴,设计要求如下:

         本次我采用modelsim仿真的方式验证设计功能的正确性。工作时钟选择50MHZ。

        所谓电子琴,本质就是用按键控制蜂鸣器发出不同频率的声音。我们平时所接触的音乐,从低音到高音,从哆瑞咪发到嗦啦西,都有相应的频率与之对应。音符与频率对应关系如下:

         所以整个设计的思路就是,按下按键,控制蜂鸣器的管脚产生相应频率的方波即可。下面首先给出整个设计的总体rtl视图,然后再根据此图讲解各个模块

        

         首先,clock_gen模块的作用就是对系统时钟进行分频,系统时钟是50M,分频产生两个时钟,一个1M,一个1K。具体代码如下所示,分频细节不做具体介绍。

        

  1. module clock_gen(
  2. input clk, //50M时钟
  3. input rst_n,
  4. output reg clk_1M,
  5. output reg clk_1k
  6. );
  7. parameter div_factor_1MHz = 6'd25; //1MHz 分频系数
  8. parameter div_factor_1K = 9'd500; //1K 分频系数
  9. reg [15:0] cnt1;
  10. always @ (posedge clk or negedge rst_n)
  11. begin
  12. if (!rst_n)begin
  13. cnt1 <= 0;
  14. clk_1M <= 0;
  15. end else
  16. if(cnt1 == div_factor_1MHz-1)begin
  17. cnt1 <= 1'b0;
  18. clk_1M <= ~ clk_1M;
  19. end else
  20. cnt1 <= cnt1 + 1'b1;
  21. end
  22. reg [8:0] cnt2;
  23. always @ (posedge clk_1M or negedge rst_n)
  24. begin
  25. if (!rst_n)begin
  26. cnt2 <= 0;
  27. clk_1k <= 0;
  28. end else
  29. if(cnt2 == div_factor_1K-1)begin
  30. cnt2 <= 1'b0;
  31. clk_1k <= ~clk_1k;
  32. end else
  33. cnt2 <= cnt2 + 1'b1;
  34. end
  35. endmodule

        Key_input模块,以1KHZ信号为驱动时钟,处理按键信息,将按键输入的信息经过延时消抖以后,再编码输出。按键默认电平为高电平(1),也就是说,按键不按下为1,按下为0其中,按键为十位宽。最高三位代表的是音高,即决定低音,中音,高音。低七位代表的是音符。实现代码如下:

        

  1. module key_input(
  2. input clk_1k,
  3. input rst_n,
  4. input [9:0] key_in,
  5. output reg [9:0] key_val
  6. );
  7. parameter delay_time = 8'd20; //delay20ms
  8. reg [7:0] cnt;
  9. reg [1:0] state;
  10. always @(posedge clk_1k or negedge rst_n)
  11. begin
  12. if(!rst_n)begin
  13. key_val <= 10'b0000000000;
  14. cnt <= 0;
  15. state <= 0;
  16. end else
  17. case(state)
  18. 2'd0 : begin//check
  19. key_val <= 10'b0000000000;
  20. if(key_in==10'b1111111111)
  21. state <= 0;
  22. else
  23. state <= 1;
  24. end
  25. 2'd1 : //delay
  26. if(cnt < delay_time-1)begin
  27. cnt <= cnt + 1'b1;
  28. state <= 1;
  29. end else begin
  30. cnt <= 8'd0;
  31. state <= 2;
  32. end
  33. 2'd2 :begin //check again
  34. case(key_in)
  35. 10'b1111111110 : key_val <= 10'b0000000001;
  36. 10'b1111111101 : key_val <= 10'b0000000010;
  37. 10'b1111111011 : key_val <= 10'b0000000100;
  38. 10'b1111110111 : key_val <= 10'b0000001000;
  39. 10'b1111101111 : key_val <= 10'b0000010000;
  40. 10'b1111011111 : key_val <= 10'b0000100000;
  41. 10'b1110111111 : key_val <= 10'b0001000000;
  42. 10'b1101111111 : key_val <= 10'b0010000000;
  43. 10'b1011111111 : key_val <= 10'b0100000000;
  44. 10'b0111111111 : key_val <= 10'b1000000000;
  45. default : key_val <= 10'b0000000000;
  46. endcase
  47. state <= 3;
  48. end
  49. 2'd3 : begin //waiting key up
  50. if(key_in==10'b1111111111)
  51. state <= 0;
  52. else
  53. state <= 3;
  54. end
  55. endcase
  56. end
  57. endmodule

        Key_process模块,主要是从编码好的按键信息中,提取出音高、音符信息。并将两种信息合并,组合成为一个变量TN,将其传递后后面的模块,用于蜂鸣器发声。

        

  1. module key_processor(
  2. input clk,
  3. input rst_n,
  4. input [9:0] key,
  5. output [4:0] TN
  6. );
  7. reg[2:0] notes;
  8. always@(posedge clk or negedge rst_n)
  9. begin
  10. if(!rst_n)
  11. notes <= 3'b000;
  12. else
  13. if(key[0] == 1'b1)
  14. notes <= 3'b001;
  15. else if(key[1] == 1'b1)
  16. notes <= 3'b010;
  17. else if(key[2] == 1'b1)
  18. notes <= 3'b011;
  19. else if(key[3] == 1'b1)
  20. notes <= 3'b100;
  21. else if(key[4] == 1'b1)
  22. notes <= 3'b101;
  23. else if(key[5] == 1'b1)
  24. notes <= 3'b110;
  25. else if(key[6] == 1'b1)
  26. notes <= 3'b111;
  27. else
  28. notes <= 3'b000;
  29. end
  30. reg[1:0] register;
  31. always@(posedge clk or negedge rst_n)
  32. begin
  33. if(!rst_n)
  34. register <= 2'b00;
  35. else
  36. if(key[7] == 1'b1)
  37. register <= 2'b00;
  38. else if(key[8] == 1'b1)
  39. register <= 2'b01;
  40. else if(key[9] == 1'b1)
  41. register <= 2'b10;
  42. else
  43. register <= register;
  44. end
  45. assign TN = {register,notes};
  46. endmodule

        Speaker模块是电子琴发声的关键模块,它根据音高、音符信息,决定电子琴具体产生多少频率的声音。

  1. //蜂鸣器驱动
  2. module speaker(
  3. input clk ,
  4. input rst_n ,
  5. input [4:0] TN ,
  6. output spks
  7. );
  8. reg [10:0] temp;
  9. always@(posedge clk)
  10. begin
  11. case(TN)
  12. //
  13. 5'b00001 : temp <= 11'd1908; //低音 1
  14. 5'b00010 : temp <= 11'd1701; //低音 2
  15. 5'b00011 : temp <= 11'd1515; //低音 3
  16. 5'b00100 : temp <= 11'd1433; //低音 4
  17. 5'b00101 : temp <= 11'd1276; //低音 5
  18. 5'b00110 : temp <= 11'd1136; //低音 6
  19. 5'b00111 : temp <= 11'd1012; //低音 7
  20. //
  21. 5'b01001 : temp <= 11'd956; //中音 1
  22. 5'b01010 : temp <= 11'd852; //中音 2
  23. 5'b01011 : temp <= 11'd759; //中音 3
  24. 5'b01100 : temp <= 11'd716; //中音 4
  25. 5'b01101 : temp <= 11'd638; //中音 5
  26. 5'b01110 : temp <= 11'd568; //中音 6
  27. 5'b01111 : temp <= 11'd506; //中音 7
  28. //
  29. 5'b10001 : temp <= 11'd478; //高音 1
  30. 5'b10010 : temp <= 11'd426; //高音 2
  31. 5'b10011 : temp <= 11'd379; //高音 3
  32. 5'b10100 : temp <= 11'd358; //高音 4
  33. 5'b10101 : temp <= 11'd319; //高音 5
  34. 5'b10110 : temp <= 11'd284; //高音 6
  35. 5'b10111 : temp <= 11'd253; //高音 7
  36. default : temp <= 0; //静音
  37. endcase
  38. end
  39. reg [10:0] cnt;
  40. reg wave;
  41. always@(posedge clk or negedge rst_n)
  42. begin
  43. if(!rst_n)begin
  44. cnt <= 11'd0;
  45. wave <= 0;
  46. end else begin
  47. if(temp != 0)begin
  48. if(cnt >= temp-1)begin
  49. cnt <= 11'd0;
  50. wave <= ~ wave;
  51. end else
  52. cnt <= cnt + 1'b1;
  53. end else
  54. wave <= 0;
  55. end
  56. end
  57. assign spks = wave;
  58. endmodule

        这里最关键的是延迟变量temp如何选择的问题。以低音1为例,它的频率为262,speaker模块的驱动时钟是1M,而方波又是由等宽的高电平和低电平共同组成。所以要让spks取反,应该延迟的时间是1M/(262*2)=1908

           接下来就是进行modelsim仿真。仿真分析:

    

         低音 5,对应程序内的编码(TN)为 00101,输出方波频率(spks)为392,与上表对照可知,结果正确

       

         中音4,对应程序内的编码(TN)为 01100,输出方波频率(spks)为698,与上表对照可知,结果正确

         高音7,对应程序内的编码(TN)为 10111,输出方波频率(spks)为1.97k,与上表对照可知,结果正确

        

        完整的工程文件如下:(私我,便宜拿)

基于FPGA的电子琴设计仿真资源-CSDN文库icon-default.png?t=N7T8https://download.csdn.net/download/guangali/88640298     

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/411169
推荐阅读
相关标签
  

闽ICP备14008679号