具有启动、停止、递增和清除功能的秒表
该项目使用了基于Lattice MXO2的小脚丫FPGA核心板和WebIDE开发平台,实现了具有启动、停止、递增和清除功能的秒表的设计,它的主要功能为:由四个按键分别控制启动、停止、递增和清除功能的秒表,有准确的计数功能。
标签
嵌入式系统
FPGA
显示
开发板
克比尔
更新2024-04-01
西安电子科技大学
201

1 项目需求

使用七段显示器作为输出设备,在小脚丫FPGA核心板上创建一个2位数秒表。 秒表应从 0.0 秒计数到 9.9秒,然后翻转,计数值每0.1秒精确更新一次。

秒表使用四个按钮输入:开始、停止、增量和清除(重置)。 开始输入使秒表开始以10Hz时钟速率递增(即每0.1秒计数一次); 停止输入使计数器停止递增,但使数码管显示当前计数器值; 每次按下按钮时,增量输入都会导致显示值增加一次,无论按住增量按钮多长时间; 复位/清除输入强制计数器值为零。

2 设计思路

学习stepfpga的示例代码发现计数控制刷新可以用时钟触发always语句来实现,剩下的就是用chatgpt做辅助,按照这个主程序思路再加上按键消抖代码和分频器代码(输出计数所需刷新频率)。

3 所用工具和设备

基于Lattice MXO2的小脚丫FPGA核心板,WebIDE开发平台(pc端编写代码),open ai chatgpt

4 主要代码部分解析

4.1按键消抖代码

按键消抖代码主要参考stepfpga上的示例,这是在主程序上的引用(debounce文件是按键消抖模块的代码),分别是开始键和暂停键

debounce  U2 (
.clk(clk),
.rst(rst),
.key(hold),
.key_pulse(hold_pulse)
);
debounce U3 (
.clk(clk),
.rst(rst),
.key(hold2),
.key_pulse(hold2_pulse)
);

4.2分频器

输出周期为0.1秒的分频时钟信号,以下为主程序的引用(divide文件也是引用的分频器代码)

divide #(.WIDTH(32),.N(1200000)) U1 ( 
.clk(clk),
.rst_n(rst),
.clkout(clk1h)
);

4.3开启/暂停标志位的控制

  //按键动作标志信号产生
always @(posedge hold_pulse or posedge hold2_pulse) begin
if (!rst) begin
hold_flag <= 1;
end else begin
// 如果按下 hold,设置 hold_flag 为 1
if (hold_pulse) begin
hold_flag <= 1;
end
// 如果按下 hold2,设置 hold2_flag 为 1
if (hold2_pulse) begin
hold_flag <= 0;
end
end
end

两个按键分别控制标志位取两个相反值

4.4主循环

主循环则是简单的逻辑,分频器触发一次循环,小数位增加一次,增加到9时个位加一并且小数位清零,最后到9.9时都清零重新开始

	always @ (posedge clk1h or negedge rst) begin



if (!rst == 1) begin
cnt_ge <= 4'd0;
cnt_shi <= 4'd0;
end
else if(hold_flag == 1) begin
//
if (!rst == 1) begin
// 初始化状态
incf <= 0;
end else begin
// 检测按键按下事件
if (!inc && incf) begin
// 处理按键按下事件,只允许增加一次
if (cnt_ge == 9 && cnt_shi == 9) begin
// 达到最大值时归零
cnt_ge <= 4'd0;
cnt_shi <= 4'd0;
end else if (cnt_ge == 9) begin
// 个位满十进位
cnt_shi <= cnt_shi + 1;
cnt_ge <= 4'd0;
end else begin
// 正常增加
cnt_ge <= cnt_ge + 1;
end
// 标记按键已处理
incf <= 0;
end else if (inc) begin
// 标记按键已按下
incf <= 1;
end
end

// No need to do anything here since registers will hold their values
end
else if(cnt_ge == 9) begin
if(cnt_shi == 9) begin
cnt_shi <= 4'd0;
end else begin
cnt_shi <= cnt_shi + 1;
end
cnt_ge <= 4'd0;
end


else begin
cnt_ge <= cnt_ge + 1;
end
end

这其中标志为1时执行递增按键的代码,即暂停键按下开始识别递增按键,识别到时小数位加一,数码管变化逻辑跟前面提到的主循环逻辑差不多,只是这次通过按键来触发,还利用incf标志位来控制按键长按时也只增加一位

else if(hold_flag == 1) begin
//
if (!rst == 1) begin
// 初始化状态
incf <= 0;
end else begin
// 检测按键按下事件
if (!inc && incf) begin
// 处理按键按下事件,只允许增加一次
if (cnt_ge == 9 && cnt_shi == 9) begin
// 达到最大值时归零
cnt_ge <= 4'd0;
cnt_shi <= 4'd0;
end else if (cnt_ge == 9) begin
// 个位满十进位
cnt_shi <= cnt_shi + 1;
cnt_ge <= 4'd0;
end else begin
// 正常增加
cnt_ge <= cnt_ge + 1;
end
// 标记按键已处理
incf <= 0;
end else if (inc) begin
// 标记按键已按下
incf <= 1;
end
end

// No need to do anything here since registers will hold their values
end

5 实现功能示例


6 遇到的主要困难

6.1主循环代码的编写

主循环中的基本代码是循环一次小数位增加一次,其中逻辑需要严密,每一种情况都要考虑到,不然数码管会乱码显示。除此以外主循环代码中还要加入暂停时的递增案键部分代码,最开始简单拼凑时数码管不显示,尝试了几次修正后数码管显示但按键失灵,只好从头重新编写主循环代码,将两个模块一起带着写,最后写完在gpt的帮助下修正完全才得以运行。

6.2chatgpt的使用

chatgpt的使用不是很顺利,需要经过一系列的操作才能勉强进入官网,再加上服务器不稳定,时常遇到chat卡住的问题

6.3数码管小数点的添加

整个代码写完才发现小数点忘了点亮,于是随意更改了数码管的输出变量导致整个数码管乱码,排查了一系列可能的问题之后发现是数组大小不匹配和表达的二进制位数不匹配。

7 未来的计划建议

该项目完成了所要求任务的所有需求,在此基础上更有扩展的想法

1.扩展其代码,实现更为复杂且实用的时钟功能,可通过按键控制数码管显示的信息种类如时,分,秒,日期等。

2.扩展外设,可以不仅限于数码管的显示,尝试在oled屏幕上显示并设计一个精巧的页面




附件下载
archive (1).zip
基于WebIDE平台的Verilog代码开发
团队介绍
西安电子科技大学23级学生
团队成员
克比尔
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号