OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1194|回复: 0

[国产FPGA] 《ATK-DFPGL22G 之FPGA开发指南》第九章 按键控制LED灯实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4666
金钱
4666
注册时间
2019-5-8
在线时间
1224 小时
发表于 2023-11-4 11:42:00 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2023-11-4 11:41 编辑

第九章  按键控制LED灯实验


1)实验平台:正点原子 ATK-DFPGL22G开发板

2) 章节摘自【正点原子】ATK-DFPGL22G之FPGA开发指南_V1.0


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz-PGL22G.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)FPGA技术交流QQ群:435699340

155537c2odj87vz1z9vj6l.jpg
155537nfqovl2gg9faaol9.png

按键是常用的一种控制器件。生活中我们可以见到各种形式的按键,由于其结构简单,成本低廉等特点,在家电、数码产品、玩具等方面有广泛的应用。本章我们将介绍如何使用按键来控制LED闪烁的方式。
本章包括以下几个部分:
1.1          按键简介
1.2          实验任务
1.3          硬件设计
1.4          程序设计
1.5          下载验证

1.1 按键简介
按键开关是一种电子开关,属于电子元器件类。我们的开发板上有两种按键开关:第一种是本实验所使用的轻触式按键开关(如图 9.1.1),简称轻触开关。使用时以向开关的操作方向施加压力使内部电路闭合接通,当撤销压力时开关断开,其内部结构是靠金属弹片受力后发生形变来实现通断的;第二种是自锁按键(如图 9.1.2),自锁按键第一次按下后保持接通,即自锁,第二次按下后,开关断开,同时开关按钮弹出来,开发板上的电源键就是这种开关。                              
image001.jpg
图 9.1.1 轻触式按键

image003.png
图 9.1.2 自锁式按键

1.2 实验任务
本节实验任务是使用ATK-DFPGL22G开发板上的KEY1~KEY3按键来控制开发板上的LED0~ LED3四个LED的闪烁方式。没有按键按下时,四个LED全部熄灭;如果按键0按下,则四个LED从右向左呈现流水灯效果;如果按键1按下,则四个LED从左向右呈现流水灯效果;如果按键2按下,则四个LED同时闪烁;如果按键3按下,则四个LED保持全亮。

1.3 硬件设计
开发板上按键的原理图如下图所示:
image005.png
图 9.3.1 按键电路原理图

如图 9.3.1所示,开发板上的四个按键未按下时,输出高电平,按下后,输出低电平。

本实验的管脚分配如下表所示:
QQ截图20231104114058.png
表 9.3.1 按键控制LED实验管脚分配

对应的FDC约束语句如下所示:
  1. create_clock -name {clk} [get_ports {sys_clk}]-period {20} -waveform {0.000 10.000}
  2. define_attribute {p:led[3]}{PAP_IO_DIRECTION} {OUTPUT}
  3. define_attribute {p:led[3]}{PAP_IO_LOC} {G1}
  4. define_attribute {p:led[3]} {PAP_IO_VCCIO}{1.5}
  5. define_attribute {p:led[3]}{PAP_IO_STANDARD} {LVCMOS15}
  6. define_attribute {p:led[3]}{PAP_IO_DRIVE} {4}
  7. define_attribute {p:led[3]}{PAP_IO_PULLUP} {TRUE}
  8. define_attribute {p:led[3]}{PAP_IO_SLEW} {SLOW}
  9. define_attribute {p:led[2]} {PAP_IO_DIRECTION}{OUTPUT}
  10. define_attribute {p:led[2]}{PAP_IO_LOC} {J7}
  11. define_attribute {p:led[2]}{PAP_IO_VCCIO} {1.5}
  12. define_attribute {p:led[2]}{PAP_IO_STANDARD} {LVCMOS15}
  13. define_attribute {p:led[2]}{PAP_IO_DRIVE} {4}
  14. define_attribute {p:led[2]} {PAP_IO_PULLUP}{TRUE}
  15. define_attribute {p:led[2]}{PAP_IO_SLEW} {SLOW}
  16. define_attribute {p:led[1]}{PAP_IO_DIRECTION} {OUTPUT}
  17. define_attribute {p:led[1]}{PAP_IO_LOC} {J6}
  18. define_attribute {p:led[1]}{PAP_IO_VCCIO} {1.5}
  19. define_attribute {p:led[1]}{PAP_IO_STANDARD} {LVCMOS15}
  20. define_attribute {p:led[1]}{PAP_IO_DRIVE} {4}
  21. define_attribute {p:led[1]}{PAP_IO_PULLUP} {TRUE}
  22. define_attribute {p:led[1]}{PAP_IO_SLEW} {SLOW}
  23. define_attribute {p:led[0]}{PAP_IO_DIRECTION} {OUTPUT}
  24. define_attribute {p:led[0]} {PAP_IO_LOC}{F3}
  25. define_attribute {p:led[0]}{PAP_IO_VCCIO} {1.5}
  26. define_attribute {p:led[0]}{PAP_IO_STANDARD} {LVCMOS15}
  27. define_attribute {p:led[0]}{PAP_IO_DRIVE} {4}
  28. define_attribute {p:led[0]}{PAP_IO_PULLUP} {TRUE}
  29. define_attribute {p:led[0]}{PAP_IO_SLEW} {SLOW}
  30. define_attribute {p:key[3]}{PAP_IO_DIRECTION} {INPUT}
  31. define_attribute {p:key[3]}{PAP_IO_LOC} {G3}
  32. define_attribute {p:key[3]}{PAP_IO_VCCIO} {1.5}
  33. define_attribute {p:key[3]}{PAP_IO_STANDARD} {LVCMOS15}
  34. define_attribute {p:key[3]} {PAP_IO_PULLUP}{TRUE}
  35. define_attribute {p:key[2]}{PAP_IO_DIRECTION} {INPUT}
  36. define_attribute {p:key[2]}{PAP_IO_LOC} {H6}
  37. define_attribute {p:key[2]}{PAP_IO_VCCIO} {1.5}
  38. define_attribute {p:key[2]}{PAP_IO_STANDARD} {LVCMOS15}
  39. define_attribute {p:key[2]}{PAP_IO_PULLUP} {TRUE}
  40. define_attribute {p:key[1]}{PAP_IO_DIRECTION} {INPUT}
  41. define_attribute {p:key[1]}{PAP_IO_LOC} {H5}
  42. define_attribute {p:key[1]}{PAP_IO_VCCIO} {1.5}
  43. define_attribute {p:key[1]}{PAP_IO_STANDARD} {LVCMOS15}
  44. define_attribute {p:key[1]}{PAP_IO_PULLUP} {TRUE}
  45. define_attribute {p:key[0]}{PAP_IO_DIRECTION} {INPUT}
  46. define_attribute {p:key[0]}{PAP_IO_LOC} {F2}
  47. define_attribute {p:key[0]}{PAP_IO_VCCIO} {1.5}
  48. define_attribute {p:key[0]}{PAP_IO_STANDARD} {LVCMOS15}
  49. define_attribute {p:key[0]}{PAP_IO_PULLUP} {TRUE}
  50. define_attribute {p:sys_clk}{PAP_IO_DIRECTION} {INPUT}
  51. define_attribute {p:sys_clk}{PAP_IO_LOC} {B5}
  52. define_attribute {p:sys_clk}{PAP_IO_VCCIO} {3.3}
  53. define_attribute {p:sys_clk}{PAP_IO_STANDARD} {LVCMOS33}
  54. define_attribute {p:sys_clk}{PAP_IO_PULLUP} {TRUE}
  55. define_attribute {p:sys_rst_n}{PAP_IO_DIRECTION} {INPUT}
  56. define_attribute {p:sys_rst_n}{PAP_IO_LOC} {G5}
  57. define_attribute {p:sys_rst_n}{PAP_IO_VCCIO} {1.5}
  58. define_attribute {p:sys_rst_n}{PAP_IO_STANDARD} {LVCMOS15}
  59. define_attribute {p:sys_rst_n}{PAP_IO_PULLUP} {TRUE}
复制代码

1.4 程序设计
按键控制LED系统框图如下图所示:
image007.png
图 9.4.1 按键控制LED系统框图

在图 9.4.1中,计数器对50MHz时钟进行计数,从而达到计时的目的。计数器在每次计时到0.2秒的时候,就改变LED的显示状态,然后清零并重新开始计数。

根据四个按键(KEY0~KEY3)的状态,分别设置LED的显示模式(是流水灯,或是同时闪烁,或是同时常亮)。

按键控制led模块的代码如下所示:
  1. 1  module key_led(
  2. 2       input              sys_clk  ,    //50Mhz系统时钟
  3. 3       input              sys_rst_n,    //系统复位,低有效
  4. 4       input        [3:0  key,          //按键输入信号
  5. 5       output  reg  [3:0  led           //LED输出信号
  6. 6       );
  7. 7  
  8. 8  //reg define     
  9. 9  reg  [23:0 cnt;
  10. 10 reg  [1:0  led_control;
  11. 11
  12. 12 //用于计数0.2s的计数器
  13. 13 always @ (posedge sys_clk or negedge sys_rst_n) begin
  14. 14      if(!sys_rst_n)
  15. 15          cnt<=24'd9_999_999;
  16. 16      else if(cnt<24'd9_999_999)
  17. 17          cnt<=cnt+1;
  18. 18      else
  19. 19          cnt<=0;
  20. 20 end
  21. 21
  22. 22 //用于led灯状态的选择
  23. 23 always @(posedge sys_clk or negedge sys_rst_n) begin
  24. 24      if (!sys_rst_n)
  25. 25          led_control <= 2'b00;
  26. 26      else if(cnt == 24'd9_999_999)
  27. 27          led_control <= led_control + 1'b1;
  28. 28      else
  29. 29          led_control <= led_control;
  30. 30 end
  31. 31
  32. 32 //识别按键,切换显示模式
  33. 33 always @(posedge sys_clk or negedge sys_rst_n) begin
  34. 34      if(!sys_rst_n) begin
  35. 35            led<=4'b 0000;
  36. 36      end
  37. 37      else if(key[0]== 0)  //按键1按下时,从右向左的流水灯效果
  38. 38          case (led_control)
  39. 39              2'b00   : led<=4'b1000;
  40. 40              2'b01   : led<=4'b0100;
  41. 41              2'b10   : led<=4'b0010;
  42. 42              2'b11   : led<=4'b0001;
  43. 43              default  : led<=4'b0000;
  44. 44          endcase
  45. 45      else if(key[1]== 0)  //按键1按下时,从右向左的流水灯效果
  46. 46          case (led_control)
  47. 47              2'b00   : led<=4'b0001;
  48. 48              2'b01   : led<=4'b0010;
  49. 49              2'b10   : led<=4'b0100;
  50. 50              2'b11   : led<=4'b1000;
  51. 51              default  : led<=4'b0000;
  52. 52          endcase
  53. 53      else if (key[2]==0)  //按键2按下时,LED闪烁
  54. 54          case (led_control)
  55. 55              2'b00   : led<=4'b1111;
  56. 56              2'b01   : led<=4'b0000;
  57. 57              2'b10   : led<=4'b1111;
  58. 58              2'b11   : led<=4'b0000;
  59. 59              default  : led<=4'b0000;
  60. 60          endcase
  61. 61      else if (key[3]==0)  //按键3按下时,LED全亮
  62. 62          led<=4'b1111;
  63. 63      else
  64. 64          led<=4'b0000;    //无按键按下时,LED熄灭   
  65. 65 end
  66. 66
  67. 67 endmodule
复制代码
代码主要分为三个部分,第13至20行对系统时钟计数,当计数时间达0.2s时,计数器清零,同时使led_control在四个状态(00,01,10,11)内依次变化。第33至65行利用case语句实现对按键状态的检测,当不同的按键按下时,led随着led_control的变化,被赋予不同的值。

1.5 下载验证
连接开发板的电源和下载器,并打开电源开关。在工程编译之后,将生成的sbit文件下载到开发板中。下载完成之后,开发板上四个LED处于熄灭状态。然后按下KEY1,可以看到四个LED从右向左呈现流水灯效果;按下KEY2,可以看到四个LED同时闪烁盘;按下KEY3,可以看到四个LED保持长亮,如下图所示:
image009.png
图 9.5.1 实验现象


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 17:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表