当前位置:   article > 正文

FPGA实现花样彩灯

FPGA实现花样彩灯

写的第一篇博客,只是用作个人学习的简单记录,如有错误还请大家指出。

按键消抖的部分参考了《勇敢的芯 伴你玩转Altera FPGA》。

按键功能
复位键小灯全灭
key[0]小灯向左依次点亮
key[1]小灯向右依次点亮
key[2]1,3位的小灯闪烁
key[3]2,4位的小灯闪烁

按键消抖原理:采用打拍的方式,与原按键信号组合得到下降沿标志,设置一个计时20ms的计数器,当下降沿有效时(即存在抖动时),计数器的值会清零,这样设置就可以避免采到抖动时错误的键值。一旦计数器的值达到了最大值,就对当前所有的按键值做一次锁存。最后可以通过获得的键值来选择流水灯的变化模式。

  1. //---------按键消抖--------------//
  2. module key_debounce(
  3. input wire clk,
  4. input wire rst_n,
  5. input wire [3:0] key_in,
  6. output reg [3:0] key_flag,
  7. output reg [3:0] key_value
  8. );
  9. parameter CNT_MAX = 1_000_000; //1000_000
  10. wire key;
  11. reg key_reg;
  12. wire key_neg;
  13. reg [19:0] cnt_20ms;
  14. reg cnt_flag;
  15. reg [3:0] key_value_reg;
  16. //按键触发判断 按键在未按下时,为高电平
  17. assign key = (key_in[0] & key_in[1] & key_in[2] & key_in[3]);
  18. //检测下降沿
  19. always @(posedge clk or negedge rst_n) begin
  20. if(!rst_n) begin
  21. key_reg <= 1'b1;
  22. end
  23. else begin
  24. key_reg <= key;
  25. end
  26. end
  27. assign key_neg = ~key & key_reg;
  28. //20ms计数器
  29. always @(posedge clk or negedge rst_n) begin
  30. if(!rst_n) begin
  31. cnt_20ms <= 20'b0;
  32. end
  33. else if(key_neg) begin
  34. cnt_20ms <= 20'b0;
  35. end
  36. else begin
  37. cnt_20ms <= (cnt_20ms == CNT_MAX-1) ? 20'b0 : cnt_20ms + 1'b1;
  38. end
  39. end
  40. //完成20ms计数标志
  41. always @(posedge clk or negedge rst_n) begin
  42. if(!rst_n) begin
  43. cnt_flag <= 1'b0;
  44. end
  45. else if(cnt_20ms == CNT_MAX-1) begin
  46. cnt_flag <= 1'b1;
  47. end
  48. else begin
  49. cnt_flag <= 1'b0;
  50. end
  51. end
  52. //采集按键数据
  53. always @(posedge clk or negedge rst_n) begin
  54. if(!rst_n) begin
  55. key_value <= 4'b1111;
  56. end
  57. else if(cnt_flag) begin
  58. key_value <= key_in;
  59. end
  60. end
  61. always @(posedge clk or negedge rst_n) begin
  62. if(!rst_n) begin
  63. key_value_reg <= 4'b1111;
  64. end
  65. else begin
  66. key_value_reg <= key_value;
  67. end
  68. end
  69. //输出对应的按键控制值
  70. always @(posedge clk or negedge rst_n) begin
  71. if(!rst_n) begin
  72. key_flag <= 4'b0;
  73. end
  74. else begin
  75. key_flag <= ~key_value & key_value_reg;
  76. end
  77. end
  78. endmodule

流水灯原理:采用的开发板晶振是50MHz,所对应的时钟周期也就是20ns,我想让小灯每隔200ms发生变化,因此需要定义一个从0记到(10000000-1)的24位计数器,以及一个控制小灯状态变化的2位状态计数器。当没有按键按下时,计数器会归零,当计数记到最大值时,状态计数器加一,当状态计数器记到最大值3时,会自动归零,以实现小灯在四个状态内的循环变化。

  1. //--------------状态转换----------------//
  2. reg [23:0] cnt;
  3. reg [1:0] interval_flag;
  4. always @(posedge clk or negedge rst_n) begin
  5. if(!rst_n) begin
  6. cnt <= 24'b0;
  7. end
  8. else if(key_value == 4'b1111) begin
  9. cnt <= 24'b0;
  10. end
  11. else begin
  12. cnt <= (cnt == INTERVAL - 1'b1) ? 24'b0 : cnt + 1'b1;
  13. end
  14. end
  15. always @(posedge clk or negedge rst_n) begin
  16. if(!rst_n) begin
  17. interval_flag <= 1'b0;
  18. end
  19. else if(cnt == INTERVAL - 1'b1) begin
  20. interval_flag <= interval_flag + 1'b1;
  21. end
  22. else if(key_value == 4'b1111) begin
  23. interval_flag <= 2'b0;
  24. end
  25. else begin
  26. interval_flag <= interval_flag;
  27. end
  28. end

小灯的四种模式

  1. //---------------模式选择-------------------//
  2. always @(posedge clk or negedge rst_n) begin
  3. if(!rst_n) begin
  4. led_out <= 4'b0000;
  5. end
  6. else begin
  7. if(key_value[0] ==1'b0) begin
  8. case(interval_flag)
  9. 2'd0: led_out <= 4'b0001;
  10. 2'd1: led_out <= 4'b0010;
  11. 2'd2: led_out <= 4'b0100;
  12. 2'd3: led_out <= 4'b1000;
  13. endcase
  14. end
  15. else if(key_value[1] ==1'b0) begin
  16. case(interval_flag)
  17. 2'd0: led_out <= 4'b1000;
  18. 2'd1: led_out <= 4'b0100;
  19. 2'd2: led_out <= 4'b0010;
  20. 2'd3: led_out <= 4'b0001;
  21. endcase
  22. end
  23. else if(key_value[2] ==1'b0) begin
  24. led_out <= (interval_flag < 2'd2) ? 4'b1010 : 4'b0000;
  25. end
  26. else if(key_value[3] ==1'b0) begin
  27. led_out <= (interval_flag < 2'd2) ? 4'b0101 : 4'b0000;
  28. end
  29. else if(key_value == 4'b1111)begin
  30. led_out <= 4'b0000;
  31. end
  32. end
  33. end

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

闽ICP备14008679号