ZYNQ-700呼吸灯

参考野火例程

实现呼吸灯即要调整led亮的占比时间,完成视觉上看起来由灭到亮或者由亮到灭的过程。

  • 如果主频为50MHz,理论上一秒钟我们可以控制50_000_000次led的亮和灭,肉眼不可能分辨出来每一次亮灭,如果这50M我们设定为间隔一次亮一次,那么看起来led应该是常亮的,且亮度应该只有全亮的一半。通过这两种设定的比较,其实我们已经实现了pwm控制输出比,接下来需要考虑的是如何实现变化的过程。
  • 上文所述的亮灭最小控制时间是1s/50_000_000(时间除以主频),下文所述方法把单次亮灭的持续时间设定为1us,也就是1us内灯是全亮或全灭的。
  • 将led单次由灭到亮或由亮到灭的变换时间设定为1s。那么接下来就是设定亮的占比。
  • 1s=1000ms=1000_000us,也即1s我们可以控制1_000_000次亮灭。
  • 我们把1s分为1000个阶段,每个阶段可以控制1000次亮灭,那么只需要让第一个阶段亮1次,第二个阶段亮2次,第三个阶段亮3次·····第999个阶段亮999次,第1000各阶段亮1000次,那么这个过程就完成了从全灭到全亮的变化。也即1s的变化中,第1ms亮1us,第2ms亮2us······

design code:

c 复制代码
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/04/13 09:31:22
// Design Name: 
// Module Name: breath_led
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module breath_led#(
    parameter CNT_1US = 6'd49,
    parameter CNT_1MS = 10'd999,
    parameter CNT_1S = 10'd999
)
(
    input sys_clk,
    input sys_rst_n,
    output reg led
);

reg [5:0] cnt_1us;//1us内灯全灭或全亮
reg [9:0] cnt_1ms;//1ms的1000个us,cnt_1s是多少就有多少个us亮
reg [9:0] cnt_1s;//1s内的第几个ms

reg led_state;//0:从灭到亮;1:从亮到灭,用于计算cnt_1s是加还是减

//us计数
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 1'b0)
        cnt_1us <= 6'b0;
    else if(cnt_1us == CNT_1US)
        cnt_1us <= 6'b0;
    else
        cnt_1us <= cnt_1us + 1'b1;
end
//ms计数
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 1'b0)
        cnt_1ms <= 10'b0;
    else if(cnt_1us == CNT_1US && cnt_1ms == CNT_1MS)//这里注意一定是同时满足才清零,下面的判定条件同理
        cnt_1ms <= 10'b0;
    else if(cnt_1us == CNT_1US)
        cnt_1ms <= cnt_1ms + 1'b1;
end
//s计数
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 1'b0)
        cnt_1s <= 10'b0;
    else if(cnt_1us == CNT_1US && cnt_1ms == CNT_1MS && led_state == 1'b0)
        cnt_1s <= cnt_1s + 1'b1;
    else if(cnt_1us == CNT_1US && cnt_1ms == CNT_1MS && led_state == 1'b1)
        cnt_1s <= cnt_1s - 1'b1;
end
//state转换
always @(posedge sys_clk or negedge sys_rst_n) begin
    if(sys_rst_n == 1'b0)
        led_state <= 1'b0;
    else if(cnt_1us == CNT_1US && cnt_1ms == CNT_1MS && cnt_1s == CNT_1S)
        led_state <= 1'b1;
    else if(cnt_1us == 6'b0 && cnt_1ms == 10'b0 && cnt_1s == 10'b0)
        led_state <= 1'b0;
    else
        led_state <= led_state;
end
//led输出逻辑
always @(posedge sys_clk or negedge sys_rst_n)begin
    if(sys_rst_n == 1'b0)
        led <= 1'b1;
    else if(cnt_1ms < cnt_1s)//当前是第几个ms则该ms内就有多少个us是亮的
        led <= 1'b0;
    else
        led <= 1'b1;
end

endmodule

simulation code

c 复制代码
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/04/13 10:17:13
// Design Name: 
// Module Name: vtf_breath_led_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module vtf_breath_led_test(

    );

reg sys_clk;
reg sys_rst_n;
wire led;

initial begin
    sys_clk = 1'b0;
    sys_rst_n <= 1'b0;
#20
    sys_rst_n <= 1'b1;
end

always #10 sys_clk <= ~sys_clk;

breath_led #(
    .CNT_1US(1'b1),
    .CNT_1MS(5'd19),
    .CNT_1S(5'd19)
) bled(
    .sys_clk(sys_clk),
    .sys_rst_n(sys_rst_n),
    .led(led)
);
endmodule
相关推荐
DS小龙哥2 小时前
基于Zynq FPGA的雷龙SD NAND存储芯片性能测试
fpga开发·sd nand·雷龙·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
上理考研周导师11 小时前
第二章 虚拟仪器及其构成原理
fpga开发
FPGA技术实战13 小时前
《探索Zynq MPSoC》学习笔记(二)
fpga开发·mpsoc
bigbig猩猩1 天前
FPGA(现场可编程门阵列)的时序分析
fpga开发
Terasic友晶科技1 天前
第2篇 使用Intel FPGA Monitor Program创建基于ARM处理器的汇编或C语言工程<二>
fpga开发·汇编语言和c语言
码农阿豪1 天前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发·sd nand·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
江山如画,佳人北望1 天前
EDA技术简介
fpga开发
淘晶驰AK1 天前
电子设计竞赛准备经历分享
嵌入式硬件·fpga开发
最好有梦想~1 天前
FPGA时序分析和约束学习笔记(4、IO传输模型)
笔记·学习·fpga开发