原创 【博客大赛】LX9开发板呼吸灯实现

2013-3-4 22:51 1508 22 22 分类: FPGA/CPLD 文集: xilinx FPGA

         LX9开发板硬件评测后,从这一节开始真正进入FPGA开发的世界。很多开发板的例程中必有跑马灯实验,老跑马也没意思,咱来把新潮的,整一个呼吸灯。

         呼吸灯最初是出现在apple公司的笔记本产品中,当合上笔记本的时候,笔记本上的睡眠指示灯会出现呼吸状的闪烁,咱人们惊叹于apple丰富的想象力之余,之后就有很多公司效仿,并且呼吸灯出现在更多的电子产品中,如鼠标、手机。。。

         关于呼吸灯的原理,首先了解一下呼吸的特性,如图1中曲线所示,吸气:指数上升曲线,持续约1.5秒;吸气:指数曲线下降,持续约1.5秒。一般成人平均每分钟呼吸16~18次。

20130304224716198001.jpg

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个数据。

20130304224722273002.png

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];
                  
                   cnt<=0;
         end
         else
                   cnt<=cnt+1;
        
         if(cnt<=curHigh)
                   Led<=1'b1;
         else
                   Led<=1'b0;
end
endmodule

         如图3MAP之后的资源利用情况,

20130304224730298003.jpg

3

呼吸灯演示视频如下:

文章评论0条评论)

登录后参与讨论
我要评论
0
22
关闭 站长推荐上一条 /2 下一条