前言
最近在北邮沉迷学习数电,第一个验收的实验是实现循环自动计数的计数器。就这次实验写一个小结回顾,也希望能给后来人启发。
实验要求
完成一个计数值为00~19的计数器的设计和仿真,并下载到实验板上验证。要求如下:
- 计数值每秒加1,加到19后回0
BTN0
为暂停键,按一下计时停止,再按一下计时继续,要求为BTN0
设计防抖电路- 在数码管
DISP1
和DISP0
上显示计数结果 BTN7
为复位键,无论何时按下计数值都回到00
- 实验板上时钟选择
100Hz
系统分析
输入输出端口设计
首先,我们先设计系统的输入和输出。
输入显然有两个:暂停按钮 btn0
和复位按钮 reset
。
输出是数码管,但是我们发现数码管共用一个输入端口,所以为了实现多位数字显示,我们需要用 扫描 的方式显示。于是我们定义输出为 seg
,位选为 cat
。
我们可以定义整个顶层模块如下:
系统模块设计
按键消抖模块
由于按键动作的时刻和按下时间长短随机,并且存在开关簧片反弹导致电平抖动,我们需要设计一个按键消抖模块。一般抖动时间小于 20ms
,所以我们只需要检测高电平持续的长度大于20ms(实验里取30ms为检测时间)时再置高电平即可。
可见,btn0
是原始的按键输入波形, cnt_3
的作用是基于 clk
实现计数,每当 clk
到上升沿时,若高电平则+1,计数到3后则 stable_flag
置高电平,同时 press
产生一个周期的高电平。
cnt_3
为什么要计数到3呢?因为 clk
频率是 100Hz ,频率是周期的倒数,所以简单换算如下:clk
来一个上升沿, cnt_3
+1,则当 cnt_3
为3时显然时间就过去了30ms。
消抖模块对应代码如下:
复位功能设计
我们采用异步复位( posedge clk or posedge reset
里面用 or
),当reset按下时就立刻执行复位操作。因为复位功能显然优先级最高,所以所有 always
块内我们都先验证 reset
的状态。
数码管的显示
如图,要使得共阴极数码管点亮,需要改变的是阳极的状态。而阳极是多个数码管共用的,所以我们借助人 视觉暂留 的特点,用扫描的方式显示所有数字(类似显示屏的原理)。
可见,我们使用 select
区分当前显示的是十位还是个位。译码器负责转换数字到数码管阳极状态的映射关系,扫描控制电路负责控制不同位数数码管的点亮与否。
代码实现
最后,整个代码如下:
实验用板如图,引脚对应如下。
大佬!能不能请教一下你的博客搭建使用的是什么工具呀!你的博客很丝滑欸!!!
用的Typecho哦,比wordpress轻量些
大部分丝滑动画是前端做的
赞(。^▽^)