本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿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. 建立一个单链表,并删除链表中值为W的元素

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

  2. JoinPoint

    “JoinPoint对象封装了SpringAop中切面方法的信息,在切面方法中添加JoinPoint参数,就可以获取到封装了该方法信息的JoinPoint对象. ” JoinPoint适用于注解和Sc ...

  3. PS制作恐怖逼真滴血文字

    序言:各位同学们好,今天给大家带来一例恐怖逼真滴血文字效果的制作教程,本人比较喜欢看恐怖游戏,是看不是玩,然后就突发奇想地做了这件作品,最后的效果我很喜欢,而且制作起来难度并不大,在此分享自己在作图时 ...

  4. Python之异常处理(执行python文件时传入参数)

    使用sys模块 使用sys模块里的argv参数,用来保存参数值 import sys #sys.argv的作用是获取到运行python文件时,传入的参数 #默认如果运行python文件不传参数,arg ...

  5. 【转】Restful是什么

    REST的概念是什么 维基百科  表现层状态转换(REST,英文:Representational State Transfer)是Roy Thomas Fielding博士于2000年在他的博士论文 ...

  6. Linux 下面RPM 安装的SQLSERVER 修改字符集的方法

    1. 自己还是太low 2. 遇到问题 先 -h 处理 3. 发现登录报错, 怀疑是字符集的问题: 4. 计划是修改字符集 到 自己的环境可用的状态 使用命令 /opt/mssql/bin/mssql ...

  7. Linux基础学习(11)--Shell编程

    第十一章——Shell编程 一.基础正则表达式 1.正则表达式与通配符(*,?,[ ]): 2.基础正则表达式: 二.字符截取命令 1.cut字段提取命令: 空格分割时,不知道空格有多少个,无法分割行 ...

  8. Springboot中使用Xstream进行XML与Bean 相互转换

    在现今的项目开发中,虽然数据的传输大部分都是用json格式来进行传输,但是xml毕竟也会有一些老的项目在进行使用,正常的老式方法是通过获取节点来进行一系列操作,个人感觉太过于复杂.繁琐.推荐一套简单的 ...

  9. 微信小程序支付功能

    API:wx.requestPayment() { } https://blog.csdn.net/qishubiao/article/details/80804052

  10. Apache ab 单测 分布式

    使用synchronized 处理并发 缺点:无法做到细粒度控制 只适合单点的情况 使用Redis作为分布式锁 setnx命令 设计模式 :使用 !setnx 加锁 getset命令