[FPGA]Verilog利用PWM调制完成RGB三色彩虹呼吸灯
概述
实现彩虹呼吸灯
题目就是这么简短,但这是目前我碰到的最有意思的一道题目,因为他有无数种解决方法,并且每一种都是那么高级或者巧妙,比如
可以利用3路不同初相的PWM调制信号驱动三颗RGB灯重叠呼吸
利用1路PWM信号以及状态机,将一个周期分为3个状态,分别是[R降G升B灭],[R灭,G降,B升]和[R升,G灭,B降],依次往复实现重叠呼吸
将PWM拆分为3段,分别为升,降,灭,在不同时间周期性的输送给RGB实现重叠呼吸
当然,不只这几种,还有更高级的方法或者生成语句也可以更加简练的完成题目,在这里,我将采取上面罗列的几种方法的一种折中方案,采取"拆分PWM","三元运算符实现单行条件信号分配","监视模块内运行情况并以监视信号作为状态转换的触发条件"来实现彩虹呼吸灯.
题目分析
题目只有七个字:"实现彩虹呼吸灯",其中"呼吸两个字",已经确定了这个实验和脉宽调制扯不开干系,另外"彩虹"也说明这个实验需要很多的色彩,单单靠单色LED是完成不了的,一定需要三色RGB完成,并且只是让R,G,B三个LED交替呼吸,也达不到"彩虹"的效果,所以需要让三色灯按照一定的规律重叠呼吸,这里为了方便,我按照下图示意的样式进行编程
QF84u6.png
(抱歉画工实在欠缺,咳咳)
意思就是在R灯最亮时,G灯开始升,R灯开始降,在G灯最亮时,R灯已灭,B灯开始升,G灯开始降,以此类推.
通过这个图也可以容易的分成三个情况,用以实现状态机.
PWM
PWM是个啥?
PWM( Pulse width modulation )就是脉冲宽度调制,是一种通过数字信号对模拟信号控制的有效技术.简单来说,规律的进行脉宽调制,比如将一束方波的占空比不断减小,那么这束方波的有效值也相应的减小,占空比增大,有效值也增大,借此来对LED的亮度进行控制,加以周期性的增减,即可实现呼吸灯.
呼吸灯只是PWM的一个具体应用.
PWM咋实现?
在之前的学习早已接触过PWM调制的实现方法,在这里直接给出代码,可以通过注释回忆PWM实现过程
module PWM
(input CLK
,input FLAG//标志位,控制输出的PWM是升还是降(1升0降)
,output STT//监视信号(脉冲)
,output PWM
);
reg[24:0]cnt1;
reg[24:0]cnt2;
parameter freq=2400;//通过这个freq来控制PWM的周期
reg stt;//监视状态
always@(posedge CLK)
if(cnt2==freq-1)//cnt2满,则状态为1(只持续一个时钟周期)
stt<=1'b1;
else
stt<=1'b0;
assign STT=stt;
always@(posedge CLK)
if(cnt1>=freq-1)//满则清零
cnt1<=1'b0;
else
cnt1<=cnt1+1'b1;
always@(posedge CLK)
if(cnt1==freq-1)//cnt1满,以cnt1从空到满为一个周期执行操作
if(FLAG)//升的情况
if(cnt2>=freq-1)
cnt2<=1'b0;
else
cnt2<=cnt2+1'b1;//升
else//降的情况
if(cnt2<=0)
cnt2<=freq-1;
else
cnt2<=cnt2-1'b1;//降
else
cnt2<=cnt2;
assign PWM=(cnt1