时间:2026-01-18 来源:FPGA_UCY 关于我们 0
欢迎来到FPGA专栏~定时器设计与蜂鸣器驱动
【FPGA】时序逻辑电路设计目录
![]()
一、前言 实现效果
AC620驱动板载蜂鸣器:
FPGA驱动蜂鸣器
蜂鸣器电子琴:
FPGA-简单蜂鸣器电子琴
定时器与计数器
从一定程度上讲,定时器就是计数器,计数器就是定时器。
关于计数器的设计和使用可以参考上一篇文章:【FPGA零基础学习之旅#3】时序逻辑电路设计-计数器设计和闪烁LED灯
定时器:核心单元本质也是一个计数器,设置一个定时值,启动定时器后,计数器开始计数,计数满后产生计数满标志信号,提示设定的定时时间到达。
计数器:对脉冲信号进行计数,统计一确定时间段内该脉冲信号出现的次数,或者等待指定次数的脉冲信号出现后,产生相应标志。
实验原理图
AC620开发板上蜂鸣器对应的原理图:
![]()
二、实验过程 注意代码的逻辑性
观察以下代码,并进行仿真:
beep.v文件:
module beep(
//端口列表
Clk,
Rst_n,
CNT_ACC,//定时预设值
MODE,//设置一个计数模式控制信号,当该信号为1时,设置为循环定时模式,当该信号为0时,设置为单次定时模式。
CNT_GO,
//在循环定时模式下,该信号(CNT_GO信号)为高电平使能计时,为低电平则停止计时。
//在单次计数模式下,该信号(oneshot信号)的一个单基准时钟周期的脉冲使能一次定时。
CNT_NOW,//输出计数器实时计数值,该值将用于产生特定占空比的方波。
Full_Flag
);
input Clk;
input Rst_n;
input [31:0]CNT_ACC;
input MODE;
input CNT_GO;
output [31:0]CNT_NOW;
output Full_Flag;
//定义一个寄存器
//定义一个32位的寄存器用于计数器
reg [31:0]cnt;
assign CNT_NOW = cnt;
assign Full_Flag = (cnt >= CNT_ACC);
//完整格式:assign Full_Flag = (cnt >= CNT_ACC)?1'b1:1'b0
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
cnt <= 0;
else if(MODE == 1'b1)begin
if((CNT_GO == 1'b1) && (cnt < CNT_ACC))
cnt <= cnt + 1'b1;
else
cnt <= 0;
end
else if(!MODE)begin
if(oneshot)
cnt <= cnt + 1'b1;
else
cnt <= 0;
end
reg oneshot;//单次定时的内部使能信号。
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
oneshot <= 1'b0;
else if(CNT_GO == 1'b1)
oneshot <= 1'b1;
else if(Full_Flag)//cnt >= CNT_ACC
oneshot <= 1'b0;
else
oneshot <= oneshot;//不写该条语句也行,else默认oneshot <= oneshot。
endmodule
beep_tb.v文件:
`timescale 1ns/1ns
`define Clk_period 20
module beep_tb();
reg Clk;
reg Rst_n;
reg [31:0]CNT_ACC;
reg MODE;
reg CNT_GO;
wire [31:0]CNT_NOW;
wire Full_Flag;
beep beep0(
.Clk(Clk),
.Rst_n(Rst_n),
.CNT_ACC(CNT_ACC),
.MODE(MODE),