正点原子 发表于 2023-1-17 09:59:12

《ATK-DFPGL22G之FPGA开发指南_V1.0》第九章 按键控制LED灯实验

本帖最后由 正点原子 于 2023-1-17 09:59 编辑

1)实验平台:正点原子紫光PGL22G开发板
2)购买链接:https://item.taobao.com/item.htm?&id=692368045899
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-340253-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子FPGA交流群:994244016




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

9.1按键简介
按键开关是一种电子开关,属于电子元器件类。我们的开发板上有两种按键开关:第一种是本实验所使用的轻触式按键开关(如图 9.1.1),简称轻触开关。使用时以向开关的操作方向施加压力使内部电路闭合接通,当撤销压力时开关断开,其内部结构是靠金属弹片受力后发生形变来实现通断的;第二种是自锁按键(如图 9.1.2),自锁按键第一次按下后保持接通,即自锁,第二次按下后,开关断开,同时开关按钮弹出来,开发板上的电源键就是这种开关。
图 9.1.1 轻触式按键
图 9.1.2 自锁式按键
9.2实验任务
本节实验任务是使用ATK-DFPGL22G开发板上的KEY1~KEY3按键来控制开发板上的LED0~ LED3四个LED的闪烁方式。没有按键按下时,四个LED全部熄灭;如果按键0按下,则四个LED从右向左呈现流水灯效果;如果按键1按下,则四个LED从左向右呈现流水灯效果;如果按键2按下,则四个LED同时闪烁;如果按键3按下,则四个LED保持全亮。
9.3硬件设计
开发板上按键的原理图如下图所示:
图 9.3.1 按键电路原理图
如图 9.3.1所示,开发板上的四个按键未按下时,输出高电平,按下后,输出低电平。
本实验的管脚分配如下表所示:
表 9.3.1 按键控制LED实验管脚分配
对应的FDC约束语句如下所示:
create_clock -name {clk} -period {20} -waveform {0.000 10.000}
define_attribute {p:led} {PAP_IO_DIRECTION} {OUTPUT}
define_attribute {p:led} {PAP_IO_LOC} {G1}
define_attribute {p:led} {PAP_IO_VCCIO} {1.5}
define_attribute {p:led} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:led} {PAP_IO_DRIVE} {4}
define_attribute {p:led} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:led} {PAP_IO_SLEW} {SLOW}
define_attribute {p:led} {PAP_IO_DIRECTION} {OUTPUT}
define_attribute {p:led} {PAP_IO_LOC} {J7}
define_attribute {p:led} {PAP_IO_VCCIO} {1.5}
define_attribute {p:led} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:led} {PAP_IO_DRIVE} {4}
define_attribute {p:led} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:led} {PAP_IO_SLEW} {SLOW}
define_attribute {p:led} {PAP_IO_DIRECTION} {OUTPUT}
define_attribute {p:led} {PAP_IO_LOC} {J6}
define_attribute {p:led} {PAP_IO_VCCIO} {1.5}
define_attribute {p:led} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:led} {PAP_IO_DRIVE} {4}
define_attribute {p:led} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:led} {PAP_IO_SLEW} {SLOW}
define_attribute {p:led} {PAP_IO_DIRECTION} {OUTPUT}
define_attribute {p:led} {PAP_IO_LOC} {F3}
define_attribute {p:led} {PAP_IO_VCCIO} {1.5}
define_attribute {p:led} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:led} {PAP_IO_DRIVE} {4}
define_attribute {p:led} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:led} {PAP_IO_SLEW} {SLOW}
define_attribute {p:key} {PAP_IO_DIRECTION} {INPUT}
define_attribute {p:key} {PAP_IO_LOC} {G3}
define_attribute {p:key} {PAP_IO_VCCIO} {1.5}
define_attribute {p:key} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:key} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:key} {PAP_IO_DIRECTION} {INPUT}
define_attribute {p:key} {PAP_IO_LOC} {H6}
define_attribute {p:key} {PAP_IO_VCCIO} {1.5}
define_attribute {p:key} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:key} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:key} {PAP_IO_DIRECTION} {INPUT}
define_attribute {p:key} {PAP_IO_LOC} {H5}
define_attribute {p:key} {PAP_IO_VCCIO} {1.5}
define_attribute {p:key} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:key} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:key} {PAP_IO_DIRECTION} {INPUT}
define_attribute {p:key} {PAP_IO_LOC} {F2}
define_attribute {p:key} {PAP_IO_VCCIO} {1.5}
define_attribute {p:key} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:key} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:sys_clk} {PAP_IO_DIRECTION} {INPUT}
define_attribute {p:sys_clk} {PAP_IO_LOC} {B5}
define_attribute {p:sys_clk} {PAP_IO_VCCIO} {3.3}
define_attribute {p:sys_clk} {PAP_IO_STANDARD} {LVCMOS33}
define_attribute {p:sys_clk} {PAP_IO_PULLUP} {TRUE}
define_attribute {p:sys_rst_n} {PAP_IO_DIRECTION} {INPUT}
define_attribute {p:sys_rst_n} {PAP_IO_LOC} {G5}
define_attribute {p:sys_rst_n} {PAP_IO_VCCIO} {1.5}
define_attribute {p:sys_rst_n} {PAP_IO_STANDARD} {LVCMOS15}
define_attribute {p:sys_rst_n} {PAP_IO_PULLUP} {TRUE}
9.4程序设计
按键控制LED系统框图如下图所示:
图 9.4.1 按键控制LED系统框图
在图 9.4.1中,计数器对50MHz时钟进行计数,从而达到计时的目的。计数器在每次计时到0.2秒的时候,就改变LED的显示状态,然后清零并重新开始计数。
根据四个按键(KEY0~KEY3)的状态,分别设置LED的显示模式(是流水灯,或是同时闪烁,或是同时常亮)。
按键控制led模块的代码如下所示:
1   module key_led(
2       input               sys_clk,    //50Mhz系统时钟
3       input               sys_rst_n,    //系统复位,低有效
4       input      key,          //按键输入信号
5       outputregled         //LED输出信号
6       );
7   
8   //reg define   
9   reg cnt;
10regled_control;
11
12//用于计数0.2s的计数器
13always @ (posedge sys_clk or negedge sys_rst_n) begin
14      if(!sys_rst_n)
15          cnt<=24'd9_999_999;
16      else if(cnt<24'd9_999_999)
17          cnt<=cnt+1;
18      else
19          cnt<=0;
20end
21
22//用于led灯状态的选择
23always @(posedge sys_clk or negedge sys_rst_n) begin
24      if (!sys_rst_n)
25          led_control <= 2'b00;
26      else if(cnt == 24'd9_999_999)
27          led_control <= led_control + 1'b1;
28      else
29          led_control <= led_control;
30end
31
32//识别按键,切换显示模式
33always @(posedge sys_clk or negedge sys_rst_n) begin
34      if(!sys_rst_n) begin
35            led<=4'b 0000;
36      end
37      else if(key== 0)//按键1按下时,从右向左的流水灯效果
38          case (led_control)
39            2'b00   : led<=4'b1000;
40            2'b01   : led<=4'b0100;
41            2'b10   : led<=4'b0010;
42            2'b11   : led<=4'b0001;
43            default: led<=4'b0000;
44          endcase
45      else if(key== 0)//按键1按下时,从右向左的流水灯效果
46          case (led_control)
47            2'b00   : led<=4'b0001;
48            2'b01   : led<=4'b0010;
49            2'b10   : led<=4'b0100;
50            2'b11   : led<=4'b1000;
51            default: led<=4'b0000;
52          endcase
53      else if (key==0)//按键2按下时,LED闪烁
54          case (led_control)
55            2'b00   : led<=4'b1111;
56            2'b01   : led<=4'b0000;
57            2'b10   : led<=4'b1111;
58            2'b11   : led<=4'b0000;
59            default: led<=4'b0000;
60          endcase
61      else if (key==0)//按键3按下时,LED全亮
62          led<=4'b1111;
63      else
64          led<=4'b0000;    //无按键按下时,LED熄灭   
65end
66
67endmodule
代码主要分为三个部分,第13至20行对系统时钟计数,当计数时间达0.2s时,计数器清零,同时使led_control在四个状态(00,01,10,11)内依次变化。第33至65行利用case语句实现对按键状态的检测,当不同的按键按下时,led随着led_control的变化,被赋予不同的值。
9.5下载验证
连接开发板的电源和下载器,并打开电源开关。在工程编译之后,将生成的sbit文件下载到开发板中。下载完成之后,开发板上四个LED处于熄灭状态。然后按下KEY1,可以看到四个LED从右向左呈现流水灯效果;按下KEY2,可以看到四个LED同时闪烁盘;按下KEY3,可以看到四个LED保持长亮,如下图所示:
图 9.5.1 实验现象
页: [1]
查看完整版本: 《ATK-DFPGL22G之FPGA开发指南_V1.0》第九章 按键控制LED灯实验