【再说FPGA】LX9评测(三)呼吸灯实现
0赞对LX9开发板硬件评测后,从这一节开始真正进入FPGA开发的世界。很多开发板的例程中必有跑马灯实验,老跑马也没意思,咱来把新潮的,整一个呼吸灯。
呼吸灯最初是出现在apple公司的笔记本产品中,当合上笔记本的时候,笔记本上的睡眠指示灯会出现呼吸状的闪烁,咱人们惊叹于apple丰富的想象力之余,之后就有很多公司效仿,并且呼吸灯出现在更多的电子产品中,如鼠标、手机。。。
关于呼吸灯的原理,首先了解一下呼吸的特性,如图1中曲线所示,吸气:指数上升曲线,持续约1.5秒;吸气:指数曲线下降,持续约1.5秒。一般成人平均每分钟呼吸16~18次。
图1
然后再介绍2个特性现象:
1. Bloch定律指出进入人眼的光的积分或维持时间与光的强度光成反比。光源越亮,积分时间越短。显示较亮时,给予人眼以较高的时间敏感度,视觉暂留使人眼看到的连续的光序列。如果亮度变化的频率小于人眼的采样频率,就会感到明显的阶梯式的跳变。
2. 视觉暂留现象,物体在快速运动时,当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1~0.4秒左右的图像,这种现象被称为视觉暂留现象。
可以说以上2个特性现象能使我们看到的呼吸灯这种视觉艺术,并且这种视觉艺术只有通过电子工程师之后才能创造出来。
下面正式开始艺术创造之旅:
硬件要求:呼吸灯只需要一个LED灯即可,LX9开发板中有4个红色LED灯,选其一即可。
呼吸灯的FPGA程序设计:呼吸的效果是通过调节LED的暗灭来控制,基本是用PWM实现,如果连接LED的引脚输出高电平,LED亮,反之灭的话,高电平的在PWM一个周期内的占空比大的话,LED灯越亮;占空比小,LED灯越暗。
了解了原理和实现方案,还需要确定一下参数:
LX9开发板的可用的时钟频率是40MHz,初步定PWM周期为0.005秒,计算得到一个PWM周期的时钟周期Ncycle=40MHz x 0.0005s=200,000;如果以2秒进行一次呼吸,呼气和吸气分别有Mtime=200次可调节PWM占空比;占空比调节需要成指数曲线,如图2所示,曲线数据存储在ROM中,通过”./src/e.dat”文件初始化,共有201个数据。
图2
以下为Verilog实现代码:
module BreathLed( input clk_40M, output reg Led ); //Time Parameter parameter Ncycle= 200000; //clk 40MHz ; 1cycle = 200000/40*10^6 = 0.005s parameter Mtime = 200 ; reg [19:0] cnt=0; reg [19:0] curHigh=0; reg up=1'b1; reg [8:0] highcnt; reg [19:0] rom_q[0:200]; initial begin $readmemh("./src/e.dat",rom_q); end always@(posedge clk_40M) begin if(cnt==Ncycle-1) begin if(up==1'b1) begin if(highcnt==Mtime) up<=1'b0; else highcnt<=highcnt+1; end else begin if(highcnt==0) up<=1'b1; else highcnt<=highcnt - 1; end //curHigh<=highcnt * 1000; //linear curve curHigh<=rom_q[highcnt]; //Exp Curve cnt<=0; end else cnt<=cnt+1; if(cnt<=curHigh) Led<=1'b1; else Led<=1'b0; end endmodule
如图3为MAP之后的资源利用情况,
图3
呼吸灯演示视频如下: