Chapter002-FPGA学习之按键控制LED灯和蜂鸣器

硬件原理

在正点原子开发板中,LED模块高电平驱动,蜂鸣器也是高电平驱动,按键按下,对应引脚为低电平;

原理图如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

以上设备与FPGA引脚的对照表如下:

设备引脚名称对应FPGA引脚
按键PL_KEY0L14
蜂鸣器BEEPM14
LED0PL_LED0H15
LED1PL_LED1L15
复位sys_rstN16
时钟sys_clkU18

设计目标

本次设计目标是使用按键控制蜂鸣器和两个LED灯

按键每按下一次,蜂鸣器由响变为不响,或由不响变为响;

按键每按下一次,LED灯的状态变化一次,状态有(00-01-11-10)四种。

理论的逻辑图如下:
在这里插入图片描述

代码编辑

Verilog语言的代码包括以下几个部分:

  1. 底层硬件基础功能模块;
  2. 子模块关联功能模块;
  3. 约束代码;

首先需要完成基础功能模块,过于基础的功能模块在仿真验证以及实际验证后形成文档及源码,并将接口设计明确后直接留由以后使用,开发人员只需负责更高层的模块设计即可;

使用由上而下的设计思路:

最高层的模块分析:

输入内容

  • 系统时钟
  • 系统复位(低电平有效)
  • 按键引脚

输出内容

  • 2个LED灯
  • 蜂鸣器

预计包含模块

  • 按键消抖模块
  • 按键控制LED模块
  • 按键控制Beep模块

注意:LED和BEEP模块所说的按键控制实际为电平控制,可由其他模块输出对应电平进行控制,并不是只能由按键控制;

故可得到顶层模块代码(KEY_LED_BEEP.v)如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/07/06 20:43:04
// Design Name: 
// Module Name: KEY_LED_BEEP
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module KEY_LED_BEEP(
    input   sys_clk,
    input   sys_rst_n,
    
    input   key,
    output  [1:0] led,
    output  beep
    );
    
//wire define
wire    key_value;
wire    key_flag;
    
    
/************************************
             main code
************************************/
    
//例化按键功能
KEY_Debounce u_key_debounce(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    
    .key            (key),
    .key_value      (key_value),
    .key_flag       (key_flag)
    );    
    
//例化蜂鸣器功能
BEEP_Control u_beep_control(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    
    .key_value      (key_value),
    .key_flag       (key_flag),
    .beep           (beep)    
    );   
 
 
 //例化LED功能
 LED_Control u_led_control(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n),
    
    .key_value      (key_value),
    .key_flag       (key_flag),
    .led           (led)
    );
    
endmodule

按键消抖功能代码(KEY_Debounce.v)如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/07/06 21:13:25
// Design Name: 
// Module Name: KEY_Debounce
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module KEY_Debounce(
    input   sys_clk,
    input   sys_rst_n,
    
    input   key,
    output  reg key_value,
    output  reg key_flag
    );
    
//reg define
reg [19:0]  cnt;
reg         key_reg;

/************************************
                main code
**************************************/

//按键消抖[出现按键状态变化则使能计数器递减,计数器递减至0需要耗时20ms,计数器减至1则完成消抖,发送最后的key电平]
always @ (posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin
        cnt <= 20'd0;
        key_reg <= 1'b1;
    end
    else begin
        key_reg <= key;
        if(key_reg != key)begin
            cnt <= 20'd100_0000;//计数器延时20ms
        end
        else begin
            if(cnt > 20'd0)
                cnt <= cnt - 1'b1;
            else
                cnt <= 20'd0;
        end
    end
end

//发送消抖后的按键数据
always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin
        key_value <= 1'b1;
        key_flag <= 1'b0;
    end    
    else if(cnt == 20'd1)begin
        key_value <= key;
        key_flag <= 1'b1;
    end
    else begin
        key_value <= key_value;
        key_flag <= 1'b0;
    end
end

endmodule

按键控制蜂鸣器功能代码(BEEP_Control.v)如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/07/06 20:47:45
// Design Name: 
// Module Name: BEEP_Control
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module BEEP_Control(
    input   sys_clk,
    input   sys_rst_n,
    
    input   key_value,
    input   key_flag,
    output  reg beep
    );
    
always @ (posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        beep <= 1'b1;
    else if(key_flag&&(key_value == 1'b0))
        beep <= ~beep;       
end
    
endmodule

按键控制LED功能代码(LED_Control.v)如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/07/06 20:51:29
// Design Name: 
// Module Name: LED_Control
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module LED_Control(
    input   sys_clk,
    input   sys_rst_n,
    
    input   key_value,
    input   key_flag,
    output  reg [1:0] led
    );
    
always @ (posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin
        led <= 2'b00;
    end
    else if(key_flag&&(key_value == 1'b0))
         case(led)
            2'b00:led <= 2'b10;
            2'b10:led <= 2'b11;
            2'b11:led <= 2'b01;
            2'b01:led <= 2'b00;
            default: ;
        endcase
end
    
endmodule

由于顶层模块已经例化了基础模块内容,形成了关联,故写完代码后在Source设计中会变为如下形式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A2rxVxup-1657117777106)(003_KEY控制LED和蜂鸣器.assets/1657117326824.png)]

继续添加约束代码

#IO约束
set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports {beep}]
set_property -dict {PACKAGE_PIN L14 IOSTANDARD LVCMOS33} [get_ports {key}]
set_property -dict {PACKAGE_PIN H15 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN L15 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]

#时钟约束
create_clock -name clk -period 20 [get_ports sys_clk] 

此时生成二进制流,并进行下载(不知到怎么下载的见Chapter001)

实验结果

请忽略我的胖手,发个GIF作为实验结果,没有声音,大家见谅!
请添加图片描述

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值