原理部分讲解了呼吸灯的实现原理。下面通过代码讲解如何实现LED呼吸的效果。
首先定义变量cnt1和cnt2;cnt1是对单位时间周期内系统时钟进行计数,cnt2是对单位时间周期(即cnt1)进行计数,那么cnt1*cnt2=25M,。然后定义变量flag,每过1秒翻转1次,则可以在flag的不同状态控制LED是渐亮还是渐灭。
具体的LED在1个单位时间周期内亮的时间持续多少个系统时钟周期,是通过cnt1和cnt2的值比较判断的。由于cnt2是逐1自加的,那么每次在cnt1从1累加到4999的过程中,cnt2是不变的,而且每次cnt1累加的过程中,cnt2总比前一个值大1;那么,在cnt1累加的过程中,小于cnt2的值的时候,控制led亮,在cnt2累加的过程中即可实现led逐渐变亮。逐渐变暗的过程同理,只需控制cnt1大于cnt2的时候led亮即可。
代码如下:
//-------------------cnt1--------------------//
//对系统时钟进行计数
always@(posedge clk_25M or negedge rst_n)
if(!rst_n)
cnt1<=13'd0;
else if(cnt1==13'd4999)
cnt1<=13'd0;
else
cnt1<=cnt1+1'd1;
//------------------cnt2-------------------//
//对cnt1进行计数
always@(posedge clk_25M or negedge rst_n)
if(!rst_n)
cnt2<=13'd0;
else if((cnt1==13'd4999)&&(cnt2==13'd4999))
cnt2<=13'd0;
else if(cnt1==13'd4999)
cnt2<=cnt2+1'd1;
//-----------------flag--------------------//
//flag为1时led逐渐变亮,flag为0时逐渐变暗
reg flag;
always@(posedge clk_25M or negedge rst_n)
if(!rst_n)
flag<=1'd0;
else if((cnt2==13'd0)&&(cnt1==13'd0))
flag<=~flag;
//-----------------led--------------------//
//控制LED在哪个范围内亮和灭
always@(posedge clk_25M or negedge rst_n)
if(!rst_n)
led_r<=1'd1;
else if((flag==1'd1)&&(cnt2<cnt1))
led_r<=1'd0;
else if((flag==1'd0)&&(cnt2>cnt1))
led_r<=1'd0;
else
led_r<=1'd1;