在一家作嵌入式公司实习已经两个月了,须要学习整理的东西不少。决定坚持写一些总结,留下一些记忆更有意义。呼吸灯这个题目刚拿到没有思路,网上的参考示例也没有找到合适的,不过最后找到一个YHXT机构(不是广告,很简单的实现了这个功能,放到博客一块儿学习。控制LED的亮度变化,就是要控制电压,让电压高低变化,是一个电压从低到高再到低的一个线性变换过程。这里用PWM控制电压最合适。产生PWM须要分别产生载波信号和调制信号,最后对二者的大小进行比较产生pwm。学习
载波:用cnt1计数器生成一个锯齿波就是载波。这里计数器cnt1从0开始计数到N,计数到最大值再次从0开始计数,不断的循环计数。cnt1的最大值是N-1。根据你的时钟(系统时钟,FPGA的工做时钟,大多状况是50mhz,我这里用的是40mhz,25ns)来计数,每来一次时钟上升沿计数器加一。那么从0到N-1,所需的时间就是N*T。这个就是一个锯齿波的周期。spa
调制信号:呼吸灯是一个亮度又低到高再到低的过程,这里再用一个计数器cnt2生成一个三角波,这个三角波的周期就是呼吸灯工做一次的周期。三角波计数器从0到最大值N ,至关于对调制信号N等份,每个等份是一个载波周期。这里有一个公式 N^2 * T = 呼吸灯周期/2 。知道呼吸灯周期和时钟的状况下容易获得计数器最大值N。(这里为了方便,我设置整个led周期5s,T = 25ns,则N = 10000。)这里至关于cnt1计数到最大值,cnt2加一。当cnt2从0计数到N-1的过程就是一个上升的斜线,由N-1递减到0就是降低的斜线。在cnt2计数到最大值时设置一个标志位信号flag,flag为1,表明开始递减。blog
大小比较:经过载波和调制信号的大小比较,就能够生成一个pwm波。载波大于调制信号时,pwm = 0,载波小于调制信号时,pwm =1。input
verilog逻辑代码:博客
module hxled(clk,led1,led2);it input clk;//系统时钟40mhzio output led1; reg [13:0]cnt1; //cnt2 assign led1 = (cnt1 < cnt2)?1'b1:1'b0;//大小比较 endmodule |
testbench文件:
`timescale 1ns/1ps reg clk; hxled u1( initial clk = 1; endmodule |
此次波形比较简单就不分析仿真波形了,板级验证经过,要注意quartus软件的操做。不一样的工做时钟能够更改一下计数器值,也能够加入复位信号。若是实验现象不明显多是计数器值设置的问题。
再次感谢YH学堂 此次学习 了解如何用计数器产生载波信号 调制信号 如何产生PWM 以及控制呼吸灯的原理。