惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 【当耐特】
MongoDB | Blog
MongoDB | Blog
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
T
The Blog of Author Tim Ferriss
B
Blog
小众软件
小众软件
T
Tailwind CSS Blog
MyScale Blog
MyScale Blog
I
InfoQ
Engineering at Meta
Engineering at Meta
Blog — PlanetScale
Blog — PlanetScale
P
Proofpoint News Feed
H
Help Net Security
雷峰网
雷峰网
S
SegmentFault 最新的问题
V
Visual Studio Blog
爱范儿
爱范儿

博客园 - yf.x

超声波测距#倒车雷达#DE10-Lite 按键计数器#DE10-Lite 按键消抖#DE10-Lite 流水呼吸灯v2#DE10-Lite 流水呼吸灯-v1#DE10-Lite 流水灯#DE10-Lite#Verilog HDLBits_review 2015fsm 补码FSM-HDLbits 串行数据流输出其中的数据位-HDLbits 串行数据接收判断-HDLbits 输出PS2数据流-HDLbits PS2数据流检测状态机-HDLbits 独热码状态机-HDLbits 旅鼠4-HDLbits 旅鼠游戏3-HDLbits 旅鼠游戏2-HDLbits 旅鼠游戏--HDLbits 水库水位控制问题-HDLbits 康威生命游戏-hdlbits
呼吸灯-#DE10-Lite
yf.x · 2026-03-28 · via 博客园 - yf.x

这是一个适用于 FPGA/CPLD 的 Verilog 呼吸灯代码,采用 PWM 原理实现。代码默认板载时钟为 50MHz,呼吸周期为 4 秒(2 秒渐亮,2 秒渐暗),LED 高电平点亮。

设计原理

通过三个级联计数器,将一个 2 秒的时间划分为 2ms 的 1000 个小段。再用一个线性递增/递减的计数值作为比较阈值,通过改变 PWM 占空比,实现 LED 亮度的平滑变化。

引脚分配

信号名

管脚名

管脚号

clk

MAX10_CLK1_50

P11

rst_n

KEY0

B8

led

LEDR9

B11

仿真结果

image

module led_breath_v2(
    input clk,
    input rst_n,
    output led
    );
    
    parameter T_2us = 100;
    parameter T_2ms = 1000;
    parameter T_2s = 1000;
    
    reg [6:0] cnt_2us;
    reg [9:0] cnt_2ms;
    reg [9:0] cnt_2s;
    
    //2us counter
    always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                cnt_2us <= 0;
            else
                if(cnt_2us < T_2us - 1)
                    cnt_2us <= cnt_2us + 1;
                else
                    if(cnt_2us == T_2us - 1)
                        cnt_2us <= 0;
                    else
                        cnt_2us <= cnt_2us;
        end
        
    wire flag_2us;
    
    assign flag_2us = (cnt_2us == T_2us - 1) ? 1'b1 : 1'b0;
    
    //2ms counter
    always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                cnt_2ms <= 0;
            else
                if(cnt_2ms < T_2ms - 1 && flag_2us)
                    cnt_2ms <= cnt_2ms + 1;
                else
                    if(cnt_2ms == T_2ms - 1 && flag_2us)
                        cnt_2ms <= 0;
                    else
                        cnt_2ms <= cnt_2ms;
        end
        
    wire flag_2ms;
    
    assign flag_2ms = (cnt_2ms == T_2ms - 1 && flag_2us) ? 1'b1 : 1'b0;
    
    //2s counter
    always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                cnt_2s <= 0;
            else
                if(cnt_2s < T_2s - 1 && flag_2ms)
                    cnt_2s <= cnt_2s + 1;
                else
                    if(cnt_2s == T_2s - 1 && flag_2ms)
                        cnt_2s <= 0;
                    else
                        cnt_2s <= cnt_2s;
        end
        
    
    wire led_temp;
    
    assign led_temp = (cnt_2s > cnt_2ms) ? 1'b1 : 1'b0;
    
    reg change_en;
    //呼-吸切换
    always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                change_en <= 1'b0;
            else 
                if(cnt_2s == T_2s - 1 && flag_2ms)
                    change_en <= ~change_en;
                else
                    change_en <= change_en;
        end
        
    assign led = (!change_en) ? led_temp : ~led_temp;
    
endmodule