博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于FPGA的数字秒表(数码管显示模块和按键消抖)实现
阅读量:5052 次
发布时间:2019-06-12

本文共 5749 字,大约阅读时间需要 19 分钟。

本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿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 = 19'd49_9999; //0.01s;reg [18:0] cnt;reg clk_en;reg key_o_r;always @(posedge clk or negedge rst_n) begin //control cnt value;    if (~rst_n) begin        cnt <= 0;    end //if    else begin        cnt <= (cnt == CLK_MAX) ? 19'd0 : cnt + 1'b1;        end //elseend //alwaysalways @(posedge clk or negedge rst_n) begin //produce clk_en;    if (~rst_n) begin        clk_en <= 1'b0;    end //if    else begin        clk_en <= (cnt == CLK_MAX) ? 1'b1 : 1'b0;        end //elseend //alwaysreg [7:0] shift_val;always @(posedge clk or negedge rst_n) begin //shift logic;    if (~rst_n) begin        shift_val <= 8'hff;    end //if    else begin        shift_val <= (clk_en) ? {shift_val[6:0],key_i} : shift_val;        end //elseend //alwaysalways @(posedge clk or negedge rst_n) begin    if (~rst_n) begin        key_o_r <= 1'b0;    end //if    else begin        if (shift_val == 8'b1000_0000 && clk_en) begin  //check key pressed negedge;            key_o_r <= 1'b1;        end            else begin            key_o_r <= 1'b0;        end    end //elseend //alwaysassign 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    [23:0]    din              ,  //data from sco model;/*o*/   output   wire    [2:0]     sel              ,  //38 decoder;        output   wire    [7:0]     seg                 //segement;      );parameter MS_MAX = 17'd4_9999; //1ms dynamic refresh;//4_9999;reg          flag_1ms;reg  [16:0]  cnt_1ms;reg  [2:0]   sel_r;reg  [6:0]   seg_r;reg  [3:0]   seg_sel;reg  [2:0]   cnt_sel;wire         dp;  always @(posedge clk or negedge rst_n) begin   //control cnt_1ms value;    if (~rst_n) begin        cnt_1ms <= 0;    end //if    else begin        cnt_1ms <= (cnt_1ms == MS_MAX) ? 16'd0 : cnt_1ms + 1'b1;        end //elseend //alwaysalways @(posedge clk or negedge rst_n) begin //produce the flag_1ms high level;    if (~rst_n) begin        flag_1ms <= 1'b0;    end //if    else begin        flag_1ms <= (cnt_1ms == MS_MAX) ? 1'b1 : 1'b0;        end //elseend //alwaysalways @(posedge clk or negedge rst_n) begin //cnt sel value control;    if (~rst_n) begin        cnt_sel <= 0;    end //if    else begin        cnt_sel <= (cnt_sel == 3'd5 && flag_1ms) ? 3'd0 : (flag_1ms) ? cnt_sel + 1'b1 : cnt_sel;       end //elseend //alwaysalways @(*) begin          //sel logic exchange;        case (cnt_sel)            3'd0: begin sel_r = 3'b101;seg_sel = din[3:0];   end            3'd1: begin sel_r = 3'b100;seg_sel = din[7:4];   end            3'd2: begin sel_r = 3'b011;seg_sel = din[11:8];  end            3'd3: begin sel_r = 3'b010;seg_sel = din[15:12]; end            3'd4: begin sel_r = 3'b001;seg_sel = din[19:16]; end            3'd5: begin sel_r = 3'b000;seg_sel = din[23:20]; end            default: begin sel_r = 3'b111;seg_sel = 4'd10;   end         endcase //case   end //alwaysalways @(*) begin         //display coder;        case (seg_sel)            4'd0: begin seg_r = 7'b100_0000;    end //0;             4'd1: begin seg_r = 7'b111_1001;    end //1;             4'd2: begin seg_r = 7'b010_0100;    end //2;             4'd3: begin seg_r = 7'b011_0000;    end //3;             4'd4: begin seg_r = 7'b001_1001;    end //4;             4'd5: begin seg_r = 7'b001_0010;    end //5;             4'd6: begin seg_r = 7'b000_0010;    end //6;             4'd7: begin seg_r = 7'b111_1000;    end //7;             4'd8: begin seg_r = 7'b000_0000;    end //8;             4'd9: begin seg_r = 7'b001_0000;    end //9;             default: begin seg_r = 7'b100_0000; end //x;            endcase //case    end //alwaysassign dp = !(cnt_sel == 3'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

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

以上。

转载于:https://www.cnblogs.com/kingstacker/p/8001064.html

你可能感兴趣的文章
关于源程序到可运行程序的过程
查看>>
wepy的使用
查看>>
转载:mysql数据库密码忘记找回方法
查看>>
scratch少儿编程第一季——06、人在江湖混,没有背景怎么行。
查看>>
面向对象1
查看>>
在ns2.35中添加myevalvid框架
查看>>
【贪心+DFS】D. Field expansion
查看>>
为什么要使用href=”javascript:void(0);”
查看>>
C# Async与Await的使用
查看>>
Mysql性能调优
查看>>
iOS基础-UIKit框架-多控制器管理-实例:qq界面框架
查看>>
IOS-每个程序员的编程之路上都应该看这11本书
查看>>
自定义tabbar(纯代码)
查看>>
小程序底部导航栏
查看>>
ibatis学习笔记
查看>>
18-ES6(1)
查看>>
poj1611 简单并查集
查看>>
Ubuntu 14.04下安装CUDA8.0
查看>>
跨平台开发 -- C# 使用 C/C++ 生成的动态链接库
查看>>
C# BS消息推送 SignalR介绍(一)
查看>>