【【萌新的FPGA学习之呼吸灯实验】】

萌新的FPGA学习之呼吸灯实验

呼吸灯最早由苹果公司发明并应用于笔记本睡眠提示上,其一经展出,立刻吸引众多科技厂商争相效
仿,并广泛用于各种电子产品中,尤其是智能手机。呼吸灯其实是在微处理器的控制下,由暗渐亮、然后
再由亮渐暗,模仿人呼吸方式的 LED 灯。
呼吸灯实际展示的效果就是一个 LED 灯的亮度由亮到暗,再由暗到亮的变化过程,并且该过程是循环
往复的,像呼吸一样那么有节奏。 呼吸灯是采用 PWM 的方式,在固定的频率下,通过调整占空比来控制
LED 灯亮度的变化。
PWM(Pulse Width Modulation),即脉冲宽度调制,它是利用微处理器输出的 PWM 信号对模拟电路进
行控制的一种非常有效的技术,广泛应用于测量、通信、功率控制等领域。
我在遥控小车控速的时候用PWM控制齿轮的转速 达到控制速度的目的
在由计数器产生固定周期的 PWM 信号下,如果其占空比为 0,则 LED 灯不亮;如果其占空比为100%,则 LED 灯最亮。将占空比从 0 到 100%,再从 100%到 0 不断变化,就可以实现 LED 灯的“呼吸”效果。
【【萌新的FPGA学习之呼吸灯实验】】_第1张图片

实验目的:
本节实验任务是使用正点原子 ZYNQ 开发板(核心板)上的 PL LED,实现呼吸灯的效果,即由暗渐亮,然后再由亮渐暗。
我们采用了非常非常 非常巧妙的一般人学不来的方法
本实验中我们将由暗到亮的渐变过程定义为 2s,接下来我们将这 2s 分成 1000 份,就是由暗到亮的渐
变过程中有 1000 个亮度过渡,每一份过渡时间为 2ms;接下开我们再将每一份过渡时间 2ms 均分为 1000
份,每份时间为 2us,我们以 2us 为单位递减 2ms 中的高电平的占空比,随着高电平占空比的不断减少,led
灯的亮度不断变暗。
接下来我们定义一个计数器 cnt_2us,用来产生 2us 的时间;再定义一个计数 cnt_2ms,在 2us 的计数基
础上进行 2ms 计数;最后定义一个计数器 cnt_2s,在 2ms 的计数基础上进行 2s 的计数。
20ns的100倍是 2us 我们以2us 作为最小间隔 1000倍就是2ms 再 1000倍就是 2s 2s是整个呼吸灯的时间

实现要点

我们会惊奇的通过设计控制了 cnt_2ms 和 cnt_2s 都是1000个 我们这样就可以在后续的比较中这么设定
既然 1ms=1000us 那么 cnt_2us 计数从0到999然后把ms+1 诸如此类 接下来 0到999个ms 就计数1s
我们把cnt_2s分段成1000个阶段 既然cnt_ms也是从0转到999才使得cnt_2s +1 那么我们能不能这么设计 假定0是渐亮
那么一开始cnt_2s=0 cnt_2ms从0转到999 1转的时间是2us 那么这一轮 一次都不亮
接下来cnt_2s=1 接下来cnt_2ms 从0转到999 就会有1下的时间小于cnt_2s 那么就会亮2us
以此类推 当cnt_2s=999 cnt_2ms 从0到999 都会小于cnt_2s 就会一直常亮

 module breath_led(
input sys_clk , //系统时钟 50MHz
 input sys_rst_n , //系统复位,低电平有效
output reg led //LED 灯
 );
 
 //parameter define
 parameter CNT_2US_MAX = 7'd100; 
 parameter CNT_2MS_MAX = 10'd1000;
 parameter CNT_2S_MAX = 10'd1000;

 //reg define
 reg [6:0] cnt_2us;
 reg [9:0] cnt_2ms; 
 reg [9:0] cnt_2s; 
 reg inc_dec_flag; //亮度递增/递减 0:递增 1:递减

 //*****************************************************
 //** main code
 //*****************************************************

 //cnt_2us:计数 2us
 always@(posedge sys_clk or negedge sys_rst_n) begin
 if(!sys_rst_n)
 cnt_2us <= 7'b0;
 else if(cnt_2us == (CNT_2US_MAX - 7'b1 ))
 cnt_2us <= 7'b0;
 else
 cnt_2us <= cnt_2us + 7'b1;
 end

 //cnt_2ms:计数 2ms
 always@(posedge sys_clk or negedge sys_rst_n) begin
 if(!sys_rst_n)
 cnt_2ms <= 10'b0;
 else if(cnt_2ms == (CNT_2MS_MAX - 10'b1)
 && cnt_2us == (CNT_2US_MAX - 7'b1))
 cnt_2ms <= 10'b0;
 else if(cnt_2us == CNT_2US_MAX - 7'b1)
 cnt_2ms <= cnt_2ms + 10'b1;
 else
 cnt_2ms <= cnt_2ms;
 end
//cnt_2s:计数 2s
 always@(posedge sys_clk or negedge sys_rst_n) begin
 if(!sys_rst_n)
 cnt_2s <= 10'b0;
 else if(cnt_2s == (CNT_2S_MAX - 10'b1)
 && cnt_2ms == (CNT_2MS_MAX - 10'b1)
 && cnt_2us == (CNT_2US_MAX - 7'b1))
 cnt_2s <= 10'b0;
 else if(cnt_2ms == (CNT_2MS_MAX - 10'b1)
 && cnt_2us == (CNT_2US_MAX - 7'b1))
 cnt_2s <= cnt_2s + 10'b1;
 else
 cnt_2s <= cnt_2s; 
 end

 //inc_dec_flag 为低电平,led 灯由暗变亮,inc_dec_flag 为高电平,led 灯由亮变暗
 always@(posedge sys_clk or negedge sys_rst_n) begin
 if(!sys_rst_n)
 inc_dec_flag <= 1'b0;
 else if(cnt_2s == (CNT_2S_MAX - 10'b1)
 && cnt_2ms ==( CNT_2MS_MAX - 10'b1)
 && cnt_2us == (CNT_2US_MAX - 7'b1))
 inc_dec_flag <= ~inc_dec_flag;
 else
 inc_dec_flag <= inc_dec_flag;
 end

 //led:输出信号连接到外部的 led 灯
 always@(posedge sys_clk or negedge sys_rst_n) begin
 if(!sys_rst_n)
 led <= 1'b0;
 else if((inc_dec_flag == 1'b1 && cnt_2ms >= cnt_2s)
 || (inc_dec_flag == 1'b0 && cnt_2ms <= cnt_2s))
 led <= 1'b1;
 else
 led <= 1'b0;
 end

 endmodule

你可能感兴趣的:(FPGA学习,fpga开发,学习)