使用PWM技术实现呼吸灯。利用占空比每1ms递增1us的占空比来点亮LED。没隔1s实现灯由逐渐变亮到逐渐变暗,或者逐渐变暗到逐渐变量的转换。使用的语言是verilog。
module led_breath //#( // parameter LED_WIDTH = 4 //) ( input clk, //global clock input rst_n, //global reset output led_data ); //----------------------------------- //counter for 1us localparam T1US = 6'd100; //localparam T1US = 6'd5; //just for simulation reg [5:0] delay_1us_cnt; always @ ( posedge clk or posedge rst_n ) begin if ( rst_n ) delay_1us_cnt <= 6'd0; else if ( delay_1us_cnt < T1US ) delay_1us_cnt <= delay_1us_cnt + 1'b1; else delay_1us_cnt <= 6'd1; end wire delay_1us = ( delay_1us_cnt == T1US ) ? 1'b1 : 1'b0; //----------------------------------- //counter for 1ms localparam T1MS = 10'd1000; //localparam T1MS = 10'd100; //just for simulation reg [9:0] delay_1ms_cnt; always @ ( posedge clk or posedge rst_n ) begin if ( rst_n ) delay_1ms_cnt <= 10'd0; else if ( delay_1us ) delay_1ms_cnt <= ( delay_1ms_cnt < T1MS ) ? ( delay_1ms_cnt + 1'b1 ) : 10'd1; else delay_1ms_cnt <= delay_1ms_cnt; end wire delay_1ms = ( delay_1ms_cnt == T1MS && delay_1us ) ? 1'b1 : 1'b0; //----------------------------------- //counter for 1s localparam T1S = 10'd1000; //localparam T1S = 10'd100; //just for simulation reg [9:0] delay_1s_cnt; always @ ( posedge clk or posedge rst_n ) begin if ( rst_n ) delay_1s_cnt <= 10'd0; else if ( delay_1ms ) delay_1s_cnt <= ( delay_1s_cnt < T1S ) ? ( delay_1s_cnt + 1'b1 ) : 10'd1; else delay_1s_cnt <= delay_1s_cnt; end wire delay_1s = ( delay_1s_cnt == T1S && delay_1ms ) ? 1'b1 : 1'b0; //----------------------------------- //PWM parameter wire [9:0] duty_cnt = delay_1ms_cnt; wire [9:0] period_cnt = delay_1s_cnt; //----------------------------------- //switch mode reg display_mode; always @ ( posedge clk or posedge rst_n ) begin if ( rst_n ) display_mode <= 1'b0; else if ( delay_1s ) display_mode <= ~ display_mode; else display_mode <= display_mode; end //----------------------------------- //generate PWM reg pwm_on; always @ ( posedge clk or posedge rst_n ) begin if ( rst_n ) pwm_on <= 1'b0; else case ( display_mode ) 1'b0: pwm_on <= ( duty_cnt < period_cnt ) ? 1'b1 : 1'b0; 1'b1: pwm_on <= ( duty_cnt < period_cnt ) ? 1'b0 : 1'b1; default:; endcase end //----------------------------------- //output to LED assign led_data = pwm_on; endmodule