实战训练2 基于verilog按键消抖设计.docx

上传人:小飞机 文档编号:3435458 上传时间:2023-03-13 格式:DOCX 页数:4 大小:38.18KB
返回 下载 相关 举报
实战训练2 基于verilog按键消抖设计.docx_第1页
第1页 / 共4页
实战训练2 基于verilog按键消抖设计.docx_第2页
第2页 / 共4页
实战训练2 基于verilog按键消抖设计.docx_第3页
第3页 / 共4页
实战训练2 基于verilog按键消抖设计.docx_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《实战训练2 基于verilog按键消抖设计.docx》由会员分享,可在线阅读,更多相关《实战训练2 基于verilog按键消抖设计.docx(4页珍藏版)》请在三一办公上搜索。

1、实战训练2 基于verilog按键消抖设计实战训练2 基于verilog按键消抖设计 键盘的分类 键盘分编码键盘和非编码键盘。键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。而靠软件编程来识别的称为非编码键盘。 在单片机组成的各种系统中,用的最多的是非编码键盘。也有用到编码键盘的。非编码键盘有分为:独立键盘和行列式键盘。 按键在闭合和断开时,触点会存在抖动现象: 从上面的图形我们知道,在按键按下或者是释放的时候都会出现一个不稳定的抖动时间的,那么如果不处理好这个抖动时间,我们就无法处理好按键编码,所以如何才能有效的消除按键抖动呢? 经典的verilo

2、g键盘扫描程序 /当三个独立按键的某一个被按下后,相应的LED被点亮;再次按下后,LED熄灭,按键控制LED亮灭 timescale 1ns/1ns module keyscan( clk, rst_n, sw1_n, sw2_n, sw3_n, /output led_d3, led_d4, led_d5 ); input clk; /主时钟信号,48MHz input rst_n; /复位信号,低有效 input sw1_n,sw2_n,sw3_n; /三个独立按键,低表示按下 output led_d3,led_d4,led_d5; / - reg 19:0 cnt; /计数寄存器 /发

3、光二极管,分别由按键控制 always (posedge clk or negedge rst_n) if (!rst_n) cnt = 20d0; else /异步复位 cnt = cnt + 1b1; reg 2:0 low_sw; always (posedge clk or negedge rst_n) if (!rst_n) low_sw = 3b111; else if (cnt = 20hfffff) /满20ms,将按键值锁存到寄存器low_sw中 low_sw = sw3_n,sw2_n,sw1_n; / - reg 2:0 low_sw_r; /每个时钟周期的上升沿将low

4、_sw信号锁存到low_sw_r中 always ( posedge clk or negedge rst_n ) if (!rst_n) low_sw_r = 3b111; else low_sw_r = low_sw; 周期 wire 2:0 led_ctrl = low_sw_r2:0 & ( low_sw2:0); reg d1; reg d2; reg d3; /当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟 always (posedge clk or negedge rst_n) if (!rst_n) begin d1 = 1b0; d2 = 1b0

5、; d3 = 1b0; end else begin /某个按键值变化时,LED将做亮灭翻转 if ( led_ctrl0 ) d1 = d1; if ( led_ctrl1 ) d2 = d2; if ( led_ctrl2 ) d3 = d3; end assign led_d5 = d1 ? 1b1 : 1b0; assign led_d3 = d2 ? 1b1 : 1b0; assign led_d4 = d3 ? 1b1 : 1b0; endmodule /LED翻转输出 也许初看起来这段代码似乎有点吃力,好多的always好多的wire啊,而我们通常用得最多的判断转移好像不是主流。

6、的确是这样,一个好的verilog代码,用多个always语句来分摊一个大的always来执行,会使得综合起来更快,这也是接前两篇日志说到代码优化的一个值得学习的方面。其次是wire连线很多,你要是仔细研究代码,不难发现所有的锁存器的连线关系编程者都考虑到了,这样就不会平白无故的生成意想不到的寄存器了,这也是一个优秀代码的必备要素。 上面说的是代码风格,下面就看程序的编程思想吧。前两个always语句里其实是做了一个20ms的计数,每隔20ms就会读取键值,把这个键值放到寄存器low_sw中,接下来的一个always语句就是把low_sw的值锁存到low_sw_r里,这样以来,low_sw和l

7、ow_sw_r就是前后两个时钟周期里的键值了,为什么要这样呢?看下一个语句吧: wire 2:0 led_ctrl = low_sw_r2:0 & ( low_sw2:0); 仔细分析,你会发现当没有键按下时,low_sw=low_sw_r=3b111,此时的led_ctrl=3b000;只有当low_sw和low_sw_r的某一位分别为0和1时,才可能使led_ctrl的值改变。那么这意味着当键值由1跳变到0时才可能把led_ctrl拉高。回顾前面的20ms赋键值,也就是说每20ms内如果出现按键被按下,那么有一个时钟周期里led_ctrl是会被拉高的,而再看后面的程序,led_ctrl的置高就使得相应的LED灯的亮灭做一次改变,这就达到了目的。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号