FPGA(4)晶振与计数器 -- 实现定时器(led定时闪烁、蜂鸣器频率控制(单响)、蜂鸣器报警(频带控制,多响))

目录

一、FPGA的晶振与定时器

二、定时器(led闪烁、蜂鸣器频率控制)

1、时钟上升沿、复位下降沿触发

2、复位,计数器清零

3、计数满1s时,计数器清零

4-1、led闪烁(每秒)

4-2、蜂鸣器响(每毫秒)

代码

三、蜂鸣器报警(多响)

1、初始化 

2、计数

3、蜂鸣器控制

代码


 

一、FPGA的晶振与定时器

FPGA的晶振是50MHz,50MHz = 50_000_000Hz = 1/50_000_000s = 20ns

每次时钟(clk)上升沿(posedge)每50Mhz(20ns)到来一次

always@(posedge clk)

基于这个原理,就可以愉快地做定时的操作了。

首先要知道:2^26 = 67_108_864 > 50_000_000,所以可以设置二进制长度2^26。(即宽26)

reg [25:0] cnt

        这里涉及到的蜂鸣器,和单片机的又不太一样,我自己尝试了一下直接给电平,它是响不了的,想让它响好像只能给控制频率,让它响。

注:人耳能听到的频率是90hz到15khz,所以你的驱动源频率须在此范围之内才能听到。

二、定时器(led闪烁、蜂鸣器频率控制)

1、时钟上升沿、复位下降沿触发

//led灯定时(1s)
always@ (posedge clk, negedge rst_n)

2、复位,计数器清零

//按下复位键
	if (!rst_n)
		cnt <= 1'b0;

3、计数满1s时,计数器清零

//计数满1s
	else if(cnt != 26'd49_999_999)	//定时到1hz(即1s)
		cnt <= cnt + 1'b1;

4-1、led闪烁(每秒)

//led闪烁:1s计数满
	else
	begin 
		led <= ~led;
		cnt <= 1'b0;
	end

4-2、蜂鸣器响(每毫秒)

//蜂鸣器定频率
always@ (posedge clk)
begin
	//计数满
	if(!(cnt % 26'd49_999))			//定时到1khz(即1ms)
			beep <= ~beep;				
end

代码

//定时(led灯闪烁、蜂鸣器频率控制)
//FPGA晶振是50MHz(即20ns)
module my_and(clk, rst_n, beep, led);

input clk, rst_n;
output reg beep;
output reg led;

reg [25:0] cnt;

//led灯定时(1s)
always@ (posedge clk, negedge rst_n)
begin
	//按下复位键
	if (!rst_n)
		cnt <= 1'b0;
		
	//计数满1s
	else if(cnt != 26'd49_999_999)	//定时到1hz(即1s)
		cnt <= cnt + 1'b1;

	//led闪烁:1s计数满
	else
	begin 
		led <= ~led;
		cnt <= 1'b0;
	end
end

//蜂鸣器按频率响
always@ (posedge clk)
begin
	//计数满
	if(!(cnt % 26'd49_999))			//定时到1khz(即1ms)
			beep <= ~beep;				
end

endmodule

三、蜂鸣器报警(多响)

这里实验效果是:响4声、停一会。

实验原理:蜂鸣器响是通过根据频率控制的,如果想让它断断续续地鸣叫,可以给它限值频带频带范围内控制它响,不在频带范围内就不让它响

这里由于需要响四声,停一下,我设置通频带范围:

1、27'd0~27'd6_250_000;

2、d12_500_000~27'd18_750_000;

3、27'd25_000_000~27'd31_250_000;

4、27'd37_500_000~27'd43_750_000;

周期:100MHz(2s)

1、初始化 

//蜂鸣器报警(频带控制)
module my_and(clk, rst_n, beep);

input clk, rst_n;
output reg beep;
reg [28:0] cnt;

initial
begin
	cnt <= 1'b0;
	beep <= 1'b0;
end

2、计数

周期2s(28'd99_999_999从0开始算的,即100MHz) 

//计数
always@(posedge clk, negedge rst_n)
begin
	if(!rst_n)
	begin 
		cnt <= 1'b0;
	end
	
	else if(cnt != 28'd99_999_999)	//2s
		cnt <= cnt + 1'b1;
		
	else 
		cnt <= 1'b0;		//清空
end

3、蜂鸣器控制

设置了四个频带,在频带范围就响,不在就不响。

//蜂鸣器控制
always@(posedge clk)
begin 
	//第一个频带(第一声)
	if(cnt < 27'd6_250_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end
	//第二个频带(第二声)
	else if(cnt > 27'd12_500_000 && cnt < 27'd18_750_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end
	//第三个频带(第三声)
	else if(cnt > 27'd25_000_000 && cnt < 27'd31_250_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end
	//第四个频带(第四声)
	else if(cnt > 27'd37_500_000 && cnt < 27'd43_750_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end

end 

代码

//蜂鸣器报警(频带控制)
module my_and(clk, rst_n, beep);

input clk, rst_n;
output reg beep;
reg [28:0] cnt;

initial
begin
	cnt <= 1'b0;
	beep <= 1'b0;
end


//计数
always@(posedge clk, negedge rst_n)
begin
	if(!rst_n)
	begin 
		cnt <= 1'b0;
	end
	
	else if(cnt != 28'd99_999_999)	//2s
		cnt <= cnt + 1'b1;
		
	else 
		cnt <= 1'b0;		//清空
end


//蜂鸣器控制
always@(posedge clk)
begin 
	//第一个频带(第一声)
	if(cnt < 27'd6_250_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end
	//第二个频带(第二声)
	else if(cnt > 27'd12_500_000 && cnt < 27'd18_750_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end
	//第三个频带(第三声)
	else if(cnt > 27'd25_000_000 && cnt < 27'd31_250_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end
	//第四个频带(第四声)
	else if(cnt > 27'd37_500_000 && cnt < 27'd43_750_000)
	begin
		if(cnt%27'd49_999==0)
			beep <= ~beep;
	end

end 

endmodule

你可能感兴趣的:(#,FPGA,嵌入式硬件,fpga,EDA)