奇数分频和PWM波

生成占空比50%的奇数分频

占空比50%的偶数分频,由计数器生成,比如N分频(N为偶数),则计数从0~2*N-1,输出时钟在cnt = N的时候跳转,这样就可以得到占空比50%的方波。

但是,生成奇数分频的占空比50%方波,就不能使用上面的办法了,解决方案是用时钟的上升和下降沿两个信号分别生成一个计数器。如下图所示。
在这里插入图片描述
由pos_cnt==3时生成第一个pos_wave,而neg_cnt == 3时生成第二个neg_wave。最后生成的5分频时钟就是由pos_wave和neg_wave取或得到,这样就可以得到5分频的占空比为50%的时钟。

生成PWM波

首先需要确定的是PWM周期,这里以呼吸灯作为例子。
1、首先确定PWM的周期,也就是一个PWM波的作用时间,这里以2s为例,将这2s分为1000份,则每个pwm周期是2s/1000 = 0.002,也就是2个ms,而因为pwm有高低,将这个pwm周期均分1000份,则每一份的时间是2us。50m时钟的每个周期是20ns,则每个PWM单元由100个时钟脉冲组成。
2、计数方法是,每100个时钟周期得到一个pwm_cyc_cnt,也就是计算有多少个pwm单元。而每1000个pwm单元得到一个pwm周期。
3、pwm波形产生的方法是,当pwm_cyc_cnt>pwm_cnt时,输出拉高,当所有的pwm_cnt计数到999并且有pwm_cyc_cnt时,pwm_flag翻转。pwm波形由低到高输出。
4、verilog中计数器一定要注意1、计数什么时候开始。2、计数什么时候结束。3、计数什么时候清零。 举个栗子,pwm_cyc_cnt 计数结束的时候,是在pwm_cyc_cnt999时clkcnt99,才能保证所有的数都计满。
在这里插入图片描述

module breath_led(
	clk,rst_n,led
	);
	input  		clk;
	input 		rst_n;

	output 		led;

	reg 		led;
	reg			led_flag;


	reg [6:0]  clk_cnt;
	reg [9:0]  pwm_cyc_cnt;
	reg [9:0]  pwm_cnt;

	always @ (posedge clk)begin 
		if(!rst_n)begin 
			clk_cnt <= 0;
		end
		else if(clk_cnt ==  7'd99)begin 
			clk_cnt <= 0;
		end
		else begin 
			clk_cnt <= clk_cnt + 1'b1;
		end
	end

	always @ (posedge clk)begin 
		if(!rst_n)begin 
			pwm_cyc_cnt <= 0;
		end
		else if(clk_cnt == 7'd99 && pwm_cyc_cnt == 10'd999)begin 
			pwm_cyc_cnt <= 0;
		end
		else if(clk_cnt == 7'd99)begin 
			pwm_cyc_cnt <= pwm_cyc_cnt + 1'b1;
		end
	end

	always @ (posedge clk)begin 
		if(!rst_n)begin 
			pwm_cnt <= 0;
		end
		else if(clk_cnt == 7'd99 && pwm_cyc_cnt == 10'd999 && pwm_cnt == 10'd999)begin 
			pwm_cnt <= 0;
		end
		else if(clk_cnt == 7'd99 && pwm_cyc_cnt == 10'd999)begin 
			pwm_cnt <= pwm_cnt + 1'b1;
		end
	end

	always @ (posedge clk)begin 
		if(!rst_n)begin 
			led_flag <= 0;
		end
		else if(clk_cnt == 7'd99 && pwm_cyc_cnt == 10'd999 && pwm_cnt == 10'd999)
			led_flag <= ~ led_flag;
	end

	always @ (posedge clk)begin 
		if(!rst_n)begin 
			led <= 0;
		end
		else if(led_flag)begin 
			if(pwm_cnt < pwm_cyc_cnt)
				led <= 1'b0;
			else 
				led <= 1'b1;
		end
		else begin 
			if(pwm_cnt < pwm_cyc_cnt)
				led <= 1'b1;
			else 
				led <= 1'b0;
		end
	end

endmodule 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值