驱动蜂鸣器 Verilog

1、定时器和计数器

        从一定程度上讲,定时器就是计数器,计数器就是定时器。

        定时器:核心单元本质也是一个计数器,设置一个定时值,启动定时器后,计数器开始计数,计数满后产生计数满标志信号,提示设定的定时时间到达。

计数器:对脉冲信号进行计数,统计一确定时间段内该脉冲信号出现的次数,或者等待指定次数的脉冲信号出现后,产生相应标志。

2、定时器设计基本需求

        本节设计一个定时器,能够支持以下功能

        1) 该定时器的定时时间参数可以通过该模块的一个端口输入,通过调节端口上输入数据的值,就能修改其定时时间。

        2)设置一个计数模式控制信号,当该信号为1时,设置为循环定时模式,当该信号为0时,设置为单次定时模式。

        3)设置一个计数启动信号,在循环定时模式下,该信号为高电平使能计时,为低电平则停止计时。在单次计数模式下,该信号的一个单基准时钟周期的脉冲使能一次定时。

        4)输出计数器实时计数值,该值将用于产生特定占空比的方波。

3、定时器设计功能验证

        蜂鸣器是一种产生声音的器件,广泛应用于报警器、电子玩具、汽车电子设备、定时器等电子产品中作发声器件。

        蜂鸣器按照构造方式的不同,可分为压电式蜂鸣器和电磁式蜂鸣器两种类型。压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器、共鸣箱以及外壳等组成。电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。由于两种蜂鸣器发音原理不同,压电式结构简单耐用但音调单一音色差,适用于报警器等设备。而电磁式由于音色好,所以多用于语音、音乐等设备。

        蜂鸣器按照驱动电路的不同可以分为有源蜂鸣器与无源蜂鸣器。有源蜂鸣器内部带震荡源,所以只要通电就会鸣叫;而无源蜂鸣器内部不带震荡源,因此如果用直流信号无法令其鸣叫,这就需要用200-5K的方波(声音频率)去驱动。

4、实验原理

        在如图电路中,电容C36用于提高电路抗干扰性能;D5起保护三极管的作用,当三极管突然截止时,无源蜂鸣器两端产生的瞬时感应电动势可以通过D1迅速释放掉,避免叠加到三极管集电极上从而击穿三极管;BEEP端口接FPGA输出管脚,使用时只需要在BEEP信号上输入2~5KHz的PWM波,就能驱动蜂鸣器按照既定的频率产生振动信号。

5、实验过程

本次实验主要由以下步骤组成:

        创建Quartus Prime工程

        编写计数器HDL描述文件

        编写计数器测试脚本(testbench)

        对计数器进行功能仿真

        在Quartus Prime中执行布局布线

        对计数器进行时序仿真

        分配引脚并编译得到FPGA配置文件.sof

        配置FPGA并运行

6、代码

module beep_top(
	clk,
	Rst_n,
	beep,
	
	CNT_GO//在循环定时模式下,该信号为高电平使能计时,为低电平则停止计时。在单次计数模式下,该信号的一个单基准时钟周期的脉冲使能一次定时。
	
);

	input clk;
	input Rst_n;
	

	input CNT_GO;
	output beep;
	wire [31:0] CNT_NOW;



beep_test beep_test0(
		.clk(clk),
		.Rst_n(Rst_n),
		
		.CNT_ACC(49999),
		.MODE(1),
		.CNT_GO(CNT_GO),
		
		.CNT_NOW(CNT_NOW),
		.FULL_Flag()
	);
	
	assign beep = (CNT_NOW >= 24999 )? 1'b1:1'b0;
	endmodule
	



 module beep_top(
	clk,
	Rst_n,
	beep,
	
	CNT_GO//在循环定时模式下,该信号为高电平使能计时,为低电平则停止计时。在单次计数模式下,该信号的一个单基准时钟周期的脉冲使能一次定时。
	
);

	input clk;
	input Rst_n;
	

	input CNT_GO;
	output beep;
	wire [31:0] CNT_NOW;



beep_test beep_test0(
		.clk(clk),
		.Rst_n(Rst_n),
		
		.CNT_ACC(49999),
		.MODE(1),
		.CNT_GO(CNT_GO),
		
		.CNT_NOW(CNT_NOW),
		.FULL_Flag()
	);
	
	assign beep = (CNT_NOW >= 24999 )? 1'b1:1'b0;
	endmodule
	

testbench文件
`timescale 1ns/1ns
`define clk_period 20
module beep_test_tb;
	reg clk;
	reg Rst_n;
	
	reg [31:0] CNT_ACC;
	reg MODE;
	reg CNT_GO;
	
	wire [31:0]CNT_NOW;
	wire FULL_Flag;
	
	reg [31:0]cnt;
		beep_test beep_test0(
		.clk(clk),
		.Rst_n(Rst_n),
		
		.CNT_ACC(CNT_ACC),
		.MODE(MODE),
		.CNT_GO(CNT_GO),
		
		.CNT_NOW(CNT_NOW),
		.FULL_Flag(FULL_Flag)
	);
	initial clk = 1;
	always #(`clk_period/2) clk=~clk;
	initial begin
		Rst_n = 0;
		CNT_ACC = 0;
		CNT_GO = 0;

		#(`clk_period*20+1);//保证复位信号的变化不与clk信号边沿重合,方便观察异步复位
		Rst_n = 1;
		#(`clk_period*20);
		//设置预设值为1000,模式为循环模式
		CNT_ACC = 1000;
		MODE = 1;
		#(`clk_period*20);
		CNT_GO = 1;
		#(`clk_period*12000);
		CNT_GO = 0;
		#(`clk_period*20);
		
		//设置预设值为600,模式为循环模式
		CNT_ACC = 1000;
		MODE = 1;
		#(`clk_period*20);
		CNT_GO = 1;
		#(`clk_period*8000);
		CNT_GO = 0;
		#(`clk_period*20);
		
		//设置预设值为1000,模式为单次定时模式
		CNT_ACC = 1000;
		MODE = 0;
		#(`clk_period*20);
		CNT_GO = 1;
		#(`clk_period);
		CNT_GO = 0;
		#(`clk_period*1200);
		
		
		//设置预设值为600,模式为单次定时模式
		CNT_ACC = 600;
		MODE = 0;
		#(`clk_period*20);
		CNT_GO = 1;
		#(`clk_period);
		CNT_GO = 0;
		#(`clk_period*1200);
	
	
		$stop;
	end

7、RTL视图

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发光中请勿扰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值