基于FPGA的数字秒表(数码管显示模块和按键消抖)实现
本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿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的数字秒表(数码管显示模块和按键消抖)实现的更多相关文章
- 基于FPGA的数字识别的实现
欢迎大家关注我的微信公众号:FPGA开源工作室 基于FPGA的数字识别的实现二 作者:lee神 1 背景知识 1.1基于FPGA的数字识别的方法 通常,针对印刷体数字识别使用的算法有:基于模版 ...
- 基于FPGA的LCD+CMOS视频采集显示使用小结
基于FPGA的LCD+CMOS视频采集显示 液晶显示器采用扫描模式,RGB888 电源采用:+5V供电 usb供电有时候会出现供电不足的问题 显示器接口有两种选择:16bit或24bit 分别对应 ...
- 09B-独立按键消抖实验02——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习按键的设计 2.用模块化设计的方式实现每次按下按键0,4个LED显示状态以二进制加法格式加1,每次按下按键1,4个LED显示状态以二进制加法格式减 ...
- FPGA学习笔记(八)—— 状态机设计实例之独立按键消抖
###### [该随笔中部分内容转载自小梅哥] ######### 独立按键消抖自古以来在单片机和FPGA中都是个不可避免的问题,首先,解释一下什么叫做按键抖动,如图,按键在按下和松开的那个瞬间存在大 ...
- 我的 FPGA 学习历程(11)—— 实验:按键消抖
按键是一个输入设备,在理论上可以归为开关一类,理想的按键波形如下: 然而由于按键的机械特性,断开和闭合动作是不可能在一瞬间完成的,实际的波形如下: 抖动期间电平处于临界值,由于晶振的频率相当的高,数字 ...
- 09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习状态机的设计思想并以此为基础实现按键消抖 2.单bit异步信号同步化以及边沿检测 3.在激励文件中学会使用随机数发生函数$random 4.仿真模 ...
- FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用
一 简述 最近恶补基础知识,借了<<Verilog传奇>>,<基于FPGA的嵌入式图像处理系统设计>和<<基千FPGA的数字图像处理原理及应用>& ...
- 基于FPGA的key button等开关消抖,按键消抖电路设计
最近要用上一个key消抖的功能.于是找到了之前写的并放入博客的程序,发现居然全部有问题.http://www.cnblogs.com/sepeng/p/3477215.html —— 有问题,包括很多 ...
- fpga Verilog hdl 按键消抖 部分程序讲解
module debounce(clk_in,rst_in,key_in,key_pulse,key_state); input clk_in;//system clock input rst_in; ...
随机推荐
- 2018 Multi-University Training Contest 2
题目链接:2018 Multi-University Training Contest 2 6318 Swaps and Inversions 题意:sum=x*逆序个数+交换次数*y,使sum最小 ...
- vue入门(一)
通过JS引用vue就不说了,重点说一下使用npm搭建vue脚手架. (以下是windows系统下的操作,win7+) npm是个命令行工具,在搭建vue脚手架之前首先要安装nodeJS,下面是node ...
- mysql数据从windows导出,再导入到linux
从windows导出时,要注意字符集最好和linux的一致,如linux字符集一般为utf8,则导出时可以加上参数--default-character-set=utf8指定字符集,然后导入到linu ...
- 简单封装mongodb
首先安装mongodb npm i mongodb --save 简单封装,在modules目录下新建db.js var MongoClient=require('mongodb').MongoCl ...
- php获取URL扩展名
一切拿代码来说话: 举例:'http://www.sina.com.cn/abc/de/fg.php?id=1': $url = 'http://www.sina.com.cn/abc/de/fg.p ...
- [转帖]cnblog 新闻 : 亚太云计算市场报告:腾讯位列前五 份额首超谷歌
亚太云计算市场报告:腾讯位列前五 份额首超谷歌 投递人 itwriter 发布于 2019-03-18 12:06 评论(1) 有213人阅读 原文链接 [收藏] « » 美国市场研究机构 Syner ...
- POJ1108_Split Windows 解题报告
Split Windows 题目链接:http://poj.org/problem?id=1108 题目大意: 给你一棵二叉树的先序遍历,有三种字符:|.-.A~Z,然后用窗口表示出来,|: 表示将当 ...
- Angular 双向数据绑定
<!DOCTYPE html><html ng-app="myApp"><head lang="en"> <meta ...
- js获取非行间样式/写入样式(行间)
<!--DOCTYPE html--> <html> <head> <meta charset="utf-8" /> <sty ...
- linux重装系统,如何保存硬盘中的内容
以前没有太关注重装系统如何保留下硬盘中的内容.但是最近有一些文件在重装系统后确实需要继续保留下来,于是花了点时间了解下磁盘分区相关的东东. 参考 http://blog.csdn.net/openn/ ...