专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
FPGA
【正点原子FPGA连载】第八章 按键控制LED灯实验
2020-01-30 15:49
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
FPGA
7779
1
1
本帖最后由 正点原子 于 2019-5-20 22:37 编辑
1)实验平台:正点原子开拓者FPGA开发板
2)平台购买地址:
https://item.taobao.com/item.htm?id=579749209820
3)全套实验源码+手册+视频下载地址:
http://www.openedv.com/thread-281143-1-1.html
4)
对正点原子FPGA感兴趣的同学可以加群讨论:
712557122
点击加入:
5)关注正点原子公众号,获取最新资料更新
第八章 按键控制LED灯实验
按键是常用的一种控制器件。 生活中我们可以见到各种形式的按键,由于其结构简单,成本低廉等特点, 在家电、数码产品、玩具等方面有广泛的应用。 本章我们将介绍如何使用按键控制多个LED的亮灭。
本章包括以下几个部分:
8.1
按键简介
8.2
实验任务
8.3
硬件设计
8.4
程序设计
8.5
下载验证
8.1
按键简介
按键开关是一种电子开关,属于电子元器件类。 我们的开发板上有两种按键开关: 第一种是本实验所使用的轻触式按键开关(如图 8.1.1) ,简称轻触开关。 使用时以向开关的操作方向施加压力使内部电路闭合接通,当撤销压力时开关断开,其内部结构是靠金属弹片受力后发生形变来实现通断的;第二种是自锁按键(如图 8.1.2) , 自锁按键第一次按下后保持接通,即自锁,第二次按下后,开关断开,同时开关按钮弹出来, 开发板上的电源键就是这种开关。
图 8.1.1 轻触式按键
图 8.1.2 自锁式按键
8.2
实验任务
使用开拓者开发板上的四个按键控制四个LED灯。不同按键按下时, 四个LED灯显示不同效果。
8.3
硬件设计
如图 8.3.1所示,本实验使用四个按键开关控制四个LED灯。
图
8.3.1
按键电路原理图
如上图所示, 开发板上的5个按键未按下时,输出高电平, 按下后,输出低电平。本实验中,系统时钟、 复位按键、 按键和LED灯的管脚如下表所示。
表
8.3.1
触摸按键控制
LED
管脚分配图
8.4
程序设计
我们程序设计最终实现的效果为: 无按键按下时, LED灯全灭; 按键1按下时, LED灯显示自右向左的流水效果;按键2按下时, LED灯显示自左向右的流水效果;按键3按下时,四个LED灯同时闪烁; 按键4按下时, LED灯全亮。
LED在流水效果和闪烁效果在时间间隔均为0.2秒, 因此需要在程序中定义一个0.2s的计数器, 即每隔0.2s,状态计数器加一。根据当前按键的状态选择不同的显示模式,不同的显示模式下四个led灯的亮灭随状态计数器的值改变,从而呈现出不同的显示效果。
图 8.4.1 系统框图
按键控制led模块的代码如下所示:
1
module
key_led
(
2
input
sys_clk
,
//50Mhz系统时钟
3
input
sys_rst_n
,
//系统复位,低有效
4
input
[
3
:
0
]
key
,
//按键输入信号
5
output reg
[
3
:
0
]
led
//LED输出信号
6
);
7 8
//reg define
9
reg
[
23
:
0
]
cnt
;
10
reg
[
1
:
0
]
led_control
;
11
12
//用于计数0.2s的计数器
13
always
@
(
posedge
sys_clk
or negedge
sys_rst_n
)
begin
14
if
(!
sys_rst_n
)
15
cnt
<=
24'd 9_999_999
;
16
else if
(
cnt
<
24'd 9_999_999
)
17
cnt
<=
cnt
+
1
;
18
else
19
cnt
<=
0
;
20
end
21
22
//用于led灯状态的选择
23
always
@(
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
;
30
end
31
32
//识别按键,切换显示模式
33
always
@(
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
]==
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
[
1
]==
0
)
//按键2按下时,从左向右的流水灯效果
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
[
2
]==
0
)
//按键3按下时, 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
[
3
]==
0
)
//按键4按下时, LED全亮
62
led
=
4'b1111
;
63
else
64
led
<=
4'b0000
;
//无按键按下时, LED熄灭
65
end
66
67
endmodule
代码主要分为三个部分, 第12至20行对系统时钟计数,当计数时间达0.2s时,计数器清零,同时使led_control在四个状态(00,01,10,11) 内依次变化。第33至65行利用case语句实现对按键状态的检测, 当不同的按键按下时, led随着led_control的变化, 被赋予不同的值。大家可以发现, 本次实验和流水灯实验计数时间都是0.2s,本次实验的计数器最大可以计数到9_999_999, 而流水灯实验中计数器的值最大可以计数到10_000_000。事实上,这两个实验计数器都是从0开始计数的, 本次实验从0计数到9_999_999,需要10_000_000个时钟周期,而系统时钟为20ns,所以计数的时间为0.2s,而流水灯实验从0计数到10_000_000需要10_000_001个时钟周期,因此其计数时间实际上比0.2s要多出20ns。
为了验证我们的程序,我们在modelsim内对代码进行仿真。
Testbench模块代码如下:
1
`timescale
1
ns
/
1
ns
2
module
tb_key_led
();
3 4
parameter
T
=
20
;
5 6
reg
[
3
:
0
]
key
;
7
reg
sys_clk
;
8
reg
sys_rst_n
;
9
reg
key_value
;
10
11
wire
[
3
:
0
]
led
;
12
13
initial begin
14
key
<=
4'b1111
;
//按键初始状态为全断开
15
sys_clk
<=
1'b0
;
//初始时钟为低电平
16
sys_rst_n
<=
1'b0
;
//复位信号初始为低电平
17
#
T sys_rst_n
<=
1'b1
;
//一个时钟周期后复位信号拉高
18
19
#
600_000_020
key
[
0
] <=
0
;
//0.6s时按下按键1
20
#
800_000_000
key
[
0
] <=
1
;
21
key
[
1
] <=
0
;
//0.8s后松开按键1,按下按键2
22
#
800_000_000
key
[
1
] <=
1
;
23
key
[
2
] <=
0
;
//0.8s后松开按键2,按下按键3
24
#
800_000_000
key
[
2
] <=
1
;
25
key
[
3
] <=
0
;
//0.8s后松开按键3,按下按键4
26
#
800_000_000
key
[
3
] <=
1
;
//0.8s后松开按键4
27
28
end
29
30
always
# (
T
/
2
)
sys_clk
<= ~
sys_clk
;
31
key_led u_key_led
(
32
.
sys_clk
(
sys_clk
),
33
.
sys_rst_n
(
sys_rst_n
),
34
.
key
(
key
),
35
.
led
(
led
)
36
);
37
38
endmodule
图 8.4.2 仿真图像
观察代码,结合波形分析可知。 14至16行代码为对时钟信号、 复位信号、 按键信号赋初始值, 默认为按键全断开。 第0.6s时按下按键key0(kye[0]由高电平变为低电平) ,可观察到led3至led0依次点亮, 呈现自右向左的流水效果;按键key1断开的同时按下按键key2, 可观察到led0至led3依次点亮, 呈现自左向右的流水效果;按键key2断开的同时按下按键key3s, 可观察到led0至led3呈现闪烁效果;按键key3断开的同时按下按键key4, 可观察到led0至led3保持全亮。
8.5
下载验证
首先我们打开按键控制LED工程, 在工程所在的路径下打开key_led/par文件夹, 在里面找到“key_led.qpf” 并双击打开。注意工程所在的路径名只能由字母、 数字以及下划线组成,不能出现中文、空格以及特殊字符等。 key_led工程打开后如图 8.5.1所示。
图 8.5.1 打开工程
工程打开后通过点击工具栏中的“Programmer” 图标(图中红框位置)打开下载界面。下载界面如图 8.5.2所示,查看图中是否已经加载下载文件(sof文件) 。如果没有,则需要通过点击“Add File” 按钮添加流水灯工程中key_led/par/output_files目录下的
“key_led.sof” 文件。
图 8.5.2 下载界面
如下图 8.5.3所示。将下载器一端连接电脑, 另一端与开发板上的JTAG下载口相连接,如下图所示。然后连接电源线并打开电源开关。
图 8.5.3 开发板实物图
开发板电源打开后,在程序下载界面点击“Hardware Setup” ,在弹出的对话框中选择当前的硬件连接为“USB-Blaster” 。 然后点击“Start” 将工程编译完成后得到的sof文件下载到开发板中。
下载完成后,就可以利用按键来控制LED了,如图 8.5.3所示
发送
看不清?
0条回答
一周热门
更多
>
相关问题
如何用FPGA驱动LCD屏?
5 个回答
请教一下各位专家如何用FPGA做eDP接口?
6 个回答
FPGA CH7301c DVI(显示器数字接口)没有数字输出
7 个回答
100颗FPGA的板子,开开眼界
6 个回答
求教自制最小系统版
10 个回答
基于FPGA的X射线安检设备控制器
2 个回答
CycolneIVGX核心板,可扩展PCIE,光纤接口,大家来鉴赏一下
6 个回答
关于VHDL或Verllog程序稳定性的问题
11 个回答
相关文章
嵌入式领域,FPGA的串口通信接口设计,VHDL编程,altera平台
0个评论
Xilinx的FPGA开发工具——ISE开发流程
0个评论
基于FPGA的详细设计流程
0个评论
干货分享,FPGA硬件系统的设计技巧
0个评论
一种通过FPGA对AD9558时钟管理芯片进行配置的方法
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
FPGA
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
一周热门 更多>