FPGA按键去抖程序

来源:本站
导读:目前正在解读《FPGA按键去抖程序》的相关信息,《FPGA按键去抖程序》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《FPGA按键去抖程序》的详细说明。
简介:代码是特权同学的,我将其理解后加上了注释。去抖的原理和单片机是一样的,即通过延时来过滤掉按键抖动产生的毛刺信号。不同的是判断按键按下的条件不同,单片机通常是已知按键不按时IO口的电平(如高电平),当IO口电平发生改变时(如低电平),则开启定时器进行延时,延时20ms后再次读取IO口的电平,若仍为低电平,则说明有按键按下;若为高电平,则说明是按键抖动,没有按键按下。

FPGA的采样频率很高,它可以在每个时钟周期的上升沿到来时对IO口的电平进行一次读取。通过读取相邻2个时钟周期内IO口的电平值并进行比较,若电平值发生改变(此代码中是判断电平从0变为1),则计数器清零,若持续20ms后电平值没有发生改变,则读取按键的键值,同时将这一键值存储起来,当下一个20ms后再次读取键值,将2次键值进行比较,若键值发生改变,则说明按键有动作(要么按下,要么松手)。此代码中是判断键值从0变为1,即松手检测。

// 按键去抖

// 实现一个简单的三个按键分别控制三个发光二极管亮或暗的控制。

// 例如,按键1控制发光二极管1。上电初始发光二极管1不亮,

// 当检测到按键1被按下后,发光二极管1则点亮,

// 按键1再次被按下时,发光二极管1则不亮,如此反复。

// 该实验需要把握好按键消抖检测的设计技巧。

// 注:此代码的按键操作是包括松手检测的,

// 即按键按下后要等到松手才算一次按键操作

module key_debounce(

clk,rst_n,

key1_n,key2_n,key3_n,

led1_n,led2_n,led3_n

);

input clk;

input rst_n;

input key1_n,key2_n,key3_n;

output led1_n,led2_n,led3_n;

reg [2:0] key_rst;

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

key_rst <= 3'b111;

else

key_rst <= {key3_n,key2_n,key1_n}; // 读取当前时刻的按键值

end

reg [2:0] key_rst_r;

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

key_rst_r <= 3'b111;

else

key_rst_r <= key_rst; // 将上一时刻的按键值进行存储

end

wire [2:0]key_an = key_rst_r & (~key_rst); // 当键值从0到1时key_an改变

//wire [2:0]key_an = key_rst_r ^ key_rst; // 注:也可以这样写

reg [19:0] cnt; // 延时用计数器

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

cnt <= 20'd0;

else if(key_an)

cnt <= 20'd0;

else

cnt <= cnt + 20'd1;

end

reg [2:0] key_value;

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

key_value <= 3'b111;

else if(cnt == 20'hfffff) // 2^20*1/(50MHZ)=20ms

key_value <= {key3_n,key2_n,key1_n}; // 去抖20ms后读取当前时刻的按键值

end

reg [2:0] key_value_r;

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

key_value_r <= 3'b111;

else

key_value_r <= key_value; // 将去抖前一时刻的按键值进行存储

end

wire [2:0] key_ctrl = key_value_r & (~key_value); // 当键值从0到1时key_ctrl改变

reg d1;

reg d2;

reg d3;

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin // 一个if内有多条语句时不要忘了begin end

d1 <= 0;

d2 <= 0;

d3 <= 0;

end

else

begin

if(key_ctrl[0]) d1 <= ~d1;

if(key_ctrl[1]) d2 <= ~d2;

if(key_ctrl[2]) d3 <= ~d3;

end

end

assign led1_n = d1? 1'b1:1'b0; // 此处只是为了将LED输出进行翻转,RTL级与下面注释代码无差别

assign led2_n = d2? 1'b1:1'b0;

assign led3_n = d3? 1'b1:1'b0;

endmodule

提醒:《FPGA按键去抖程序》最后刷新时间 2024-03-14 01:09:37,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《FPGA按键去抖程序》该内容的真实性请自行鉴别。