本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多。

感谢

感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周。老师的经验还是可以的,优化了自己的代码也学习了新的知识。北京是个好地方,故宫没有想象中的那么大,但人真是多到密集恐惧症。至芯科技的最小开发板设计的一般般。。。

言归正传,本次主要实现数字数码管的主要功能,按键触发:秒表开始,暂停,记录,回显。一共四个按键,第一个按键控制全局复位,第二个按键控制秒表的开始与暂停,第三个按键控制秒表在运行中按下记录,第四个按键控制秒表在暂停的时候,记录的数据可以按一下则顺序回显一个数据,一共三个数据。

秒表可以从00:00:00 -- 59:59:99 , 6位数码管。

设计功能分解

至芯的板子数码管那位选采用了三八译码器,由于一般不用数码管,二进制转bcd的方法就不在这里阐述(不用也不会,至芯科技直接用了除号等不符合设计规范的编码实现)。直接采用到9则进1的方式,由于采用单时钟域,时序对齐还是需要特别注意的。

按键消抖模块设计

系统时钟50MHZ,采用时钟使能的方式10ms采样一个值,用一个8bit的移位寄存器实现消抖并只检测下降沿(按键按下为低电平),当按键按下产生1个系统时钟周期的高电平。

代码仅供学习使用:

//************************************************
// Filename : debounce.v
// Author : kingstacker
// Company : School
// Email : kingstacker_work@163.com
// Device : Altera cyclone4 ep4ce6f17c8
// Description : when the key is pressed ,porduce 1 period clk high;
//************************************************
module debounce ( //use shift reg logic;
/*i*/ input wire clk ,
input wire rst_n ,
input wire key_i ,
/*o*/ output wire key_o
);
parameter CLK_MAX = 'd49_9999; //0.01s;
reg [:] cnt;
reg clk_en;
reg key_o_r;
always @(posedge clk or negedge rst_n) begin //control cnt value;
if (~rst_n) begin
cnt <= ;
end //if
else begin
cnt <= (cnt == CLK_MAX) ? 'd0 : cnt + 1'b1;
end //else
end //always
always @(posedge clk or negedge rst_n) begin //produce clk_en;
if (~rst_n) begin
clk_en <= 'b0;
end //if
else begin
clk_en <= (cnt == CLK_MAX) ? 'b1 : 1'b0;
end //else
end //always
reg [:] shift_val;
always @(posedge clk or negedge rst_n) begin //shift logic;
if (~rst_n) begin
shift_val <= 'hff;
end //if
else begin
shift_val <= (clk_en) ? {shift_val[:],key_i} : shift_val;
end //else
end //always
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
key_o_r <= 'b0;
end //if
else begin
if (shift_val == 'b1000_0000 && clk_en) begin //check key pressed negedge;
key_o_r <= 'b1;
end
else begin
key_o_r <= 'b0;
end
end //else
end //always
assign key_o = key_o_r; endmodule

6位数码管动态显示模块设计

数码管由于dp位需要控制,本模块中dp位逻辑单独了出来,动态显示1ms刷新数码管,6个管需要6ms,注意间隔不要太大,否则会闪烁,太紧也没有必要,保证数据对齐,采用组合逻辑实现:

//************************************************
// Filename : led_display.v
// Author : kingstacker
// Company : School
// Email : kingstacker_work@163.com
// Device : Altera cyclone4 ep4ce6f17c8
// Description :on board ok; one clk domain;input din is bcd ;
//************************************************
module led_display (
/*i*/ input wire clk ,
input wire rst_n ,
input wire [:] din , //data from sco model;
/*o*/ output wire [:] sel , //38 decoder;
output wire [:] seg //segement;
);
parameter MS_MAX = 'd4_9999; //1ms dynamic refresh;//4_9999;
reg flag_1ms;
reg [:] cnt_1ms;
reg [:] sel_r;
reg [:] seg_r;
reg [:] seg_sel;
reg [:] cnt_sel;
wire dp;
always @(posedge clk or negedge rst_n) begin //control cnt_1ms value;
if (~rst_n) begin
cnt_1ms <= ;
end //if
else begin
cnt_1ms <= (cnt_1ms == MS_MAX) ? 'd0 : cnt_1ms + 1'b1;
end //else
end //always
always @(posedge clk or negedge rst_n) begin //produce the flag_1ms high level;
if (~rst_n) begin
flag_1ms <= 'b0;
end //if
else begin
flag_1ms <= (cnt_1ms == MS_MAX) ? 'b1 : 1'b0;
end //else
end //always
always @(posedge clk or negedge rst_n) begin //cnt sel value control;
if (~rst_n) begin
cnt_sel <= ;
end //if
else begin
cnt_sel <= (cnt_sel == 'd5 && flag_1ms) ? 3'd0 : (flag_1ms) ? cnt_sel + 'b1 : cnt_sel;
end //else
end //always
always @(*) begin //sel logic exchange;
case (cnt_sel)
'd0: begin sel_r = 3'b101;seg_sel = din[:]; end
'd1: begin sel_r = 3'b100;seg_sel = din[:]; end
'd2: begin sel_r = 3'b011;seg_sel = din[:]; end
'd3: begin sel_r = 3'b010;seg_sel = din[:]; end
'd4: begin sel_r = 3'b001;seg_sel = din[:]; end
'd5: begin sel_r = 3'b000;seg_sel = din[:]; end
default: begin sel_r = 'b111;seg_sel = 4'd10; end
endcase //case
end //always
always @(*) begin //display coder;
case (seg_sel)
'd0: begin seg_r = 7'b100_0000; end //0;
'd1: begin seg_r = 7'b111_1001; end //1;
'd2: begin seg_r = 7'b010_0100; end //2;
'd3: begin seg_r = 7'b011_0000; end //3;
'd4: begin seg_r = 7'b001_1001; end //4;
'd5: begin seg_r = 7'b001_0010; end //5;
'd6: begin seg_r = 7'b000_0010; end //6;
'd7: begin seg_r = 7'b111_1000; end //7;
'd8: begin seg_r = 7'b000_0000; end //8;
'd9: begin seg_r = 7'b001_0000; end //9;
default: begin seg_r = 'b100_0000; end //x;
endcase //case
end //always assign dp = !(cnt_sel == 'd2 || cnt_sel == 3'd4); //dp produce logic;
assign seg = {dp,seg_r};
assign sel = sel_r; endmodule

sco模块就没啥意思了,本文主要讲述按键消抖的实现方式以及数码管动态显示的问题。

如果需要整体源码,请上github查看:git@github.com:kingstacker/second_counter.git

再次感谢至芯科技公司以及李老师。

以上。

基于FPGA的数字秒表(数码管显示模块和按键消抖)实现的更多相关文章

  1. 基于FPGA的数字识别的实现

    欢迎大家关注我的微信公众号:FPGA开源工作室     基于FPGA的数字识别的实现二 作者:lee神 1 背景知识 1.1基于FPGA的数字识别的方法 通常,针对印刷体数字识别使用的算法有:基于模版 ...

  2. 基于FPGA的LCD+CMOS视频采集显示使用小结

    基于FPGA的LCD+CMOS视频采集显示 液晶显示器采用扫描模式,RGB888 电源采用:+5V供电 usb供电有时候会出现供电不足的问题 显示器接口有两种选择:16bit或24bit  分别对应 ...

  3. 09B-独立按键消抖实验02——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献   实验目的: 1.复习按键的设计 2.用模块化设计的方式实现每次按下按键0,4个LED显示状态以二进制加法格式加1,每次按下按键1,4个LED显示状态以二进制加法格式减 ...

  4. FPGA学习笔记(八)—— 状态机设计实例之独立按键消抖

    ###### [该随笔中部分内容转载自小梅哥] ######### 独立按键消抖自古以来在单片机和FPGA中都是个不可避免的问题,首先,解释一下什么叫做按键抖动,如图,按键在按下和松开的那个瞬间存在大 ...

  5. 我的 FPGA 学习历程(11)—— 实验:按键消抖

    按键是一个输入设备,在理论上可以归为开关一类,理想的按键波形如下: 然而由于按键的机械特性,断开和闭合动作是不可能在一瞬间完成的,实际的波形如下: 抖动期间电平处于临界值,由于晶振的频率相当的高,数字 ...

  6. 09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线--普利斯队长精心奉献   实验目的: 1.复习状态机的设计思想并以此为基础实现按键消抖 2.单bit异步信号同步化以及边沿检测 3.在激励文件中学会使用随机数发生函数$random 4.仿真模 ...

  7. FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用

    一 简述 最近恶补基础知识,借了<<Verilog传奇>>,<基于FPGA的嵌入式图像处理系统设计>和<<基千FPGA的数字图像处理原理及应用>& ...

  8. 基于FPGA的key button等开关消抖,按键消抖电路设计

    最近要用上一个key消抖的功能.于是找到了之前写的并放入博客的程序,发现居然全部有问题.http://www.cnblogs.com/sepeng/p/3477215.html —— 有问题,包括很多 ...

  9. fpga Verilog hdl 按键消抖 部分程序讲解

    module debounce(clk_in,rst_in,key_in,key_pulse,key_state); input clk_in;//system clock input rst_in; ...

随机推荐

  1. [LeetCode] Rank Scores -- 数据库知识(mysql)

    Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ra ...

  2. Python-random模块-59

    random模块: 随机数模块 >>> import random #随机小数 >>> random.random() # 大于0且小于1之间的小数 0.76643 ...

  3. H5 69-清除浮动方式四

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 大连CCPC D - A Simple Math Problem

    #include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> ...

  5. 【RSYSLOG】Log4x To Rsyslog Config

    Log4x To Rsyslog Config Log4net配置 <!--RemoteSyslogAppender--> <appender name="remoteSy ...

  6. 第五章 动态SQL 批量操作

    用于实现动态SQL的元素主要有 if trim where set choose(when.otherwise) foreach MyBatis  缓存 一级缓存 在test类中 调用相同的方法 第二 ...

  7. mysql之整型数据int

    mysql数据库设计,其中,对于数据性能优化,字段类型考虑很重要,mysql整型bigint.int.mediumint.smallint 和 tinyint的语法介绍,如下:1.bigint 从 - ...

  8. Mysql占用CPU过高如何优化?(转)

    原文:http://bbs.landingbj.com/t-0-241441-1.html MySQL处在高负载环境下,磁盘IO读写过多,肯定会占用很多资源,必然CP会U占用过高. 占用CPU过高,可 ...

  9. 使用node操作mongodb

    let mongodb = require('mongodb'); let MongodbClient = mongodb.MongoClient; MongodbClient.connect('mo ...

  10. Oracle 创建外部表

    Oracle 外部表能迅速的将海量的数据导入到数据库里面,外部表的创建使用步骤如下: 1 创建一个Directory:必须用sys用户创建,用户存放外部数据文件. create directory D ...