目录
前言
该工程实现了频率可调的LED呼吸灯,分为了三个模块,一个顶层
提示:以下是本篇文章正文内容,下面案例可供参考
一、呼吸灯是啥?
玩转电路从点亮一个芯片开始,啊,不对,是点亮一个LED开始,哈哈哈。几乎所有语言的学习开始都是点亮led,或者Hello word,开始认识世界。慢慢的就是接触按键,按键消抖,这种类型的项目。作为学习,该项目把按键消抖和呼吸灯结合到一起。记录一下吧
二、模块划分
1、顶层模块
代码如下(示例):
//======================================================================
//Company :
//Filenam : .v
//Author : HX
//Created On : 2024-03-13 11:03
//Last Modified :
//Description : The project is divided into three modules:
// U1 is the PLL module,
// U2 is the PWM module,
// U3 is the button jitter reduction and blink frequency control module
//======================================================================
`timescale 1ns / 1ps
module breath_led(
input clk , // clk 50Mhz
input rst_n , // system reset
input key , // input button
output [3:0] led // ouput four led,"0" active
);
wire clk_50M ; //
wire [15:0] Blink_Speed ; // blink frequency control
PLL u1_PLL(
.clk_out1( ), // output clk_out1 25Mhz
.clk_out2(clk_50M ), // output clk_out2 50Mhz
.clk_out3( ), // output clk_out3 100Mhz
.clk_out4( ), // output clk_out4 200Mhz
.reset (~rst_n ), // input reset "1"active
.locked ( ), // output locked
.clk_in1 (clk ) // input clk_in1 50Mhz
);
led_pwm u2_led_pwm(
.clk (clk_50M ), // input clk 50Mhz
.rst_n (rst_n ), // input reset
.Blink_Speed(Blink_Speed), // blink frequency control
.led (led ) // output led,"0"active
);
led_key u3_led_key(
.clk (clk_50M ), // input clk 50Mhz
.rst_n (rst_n ), // input reset
.key (key ), // input button
.Blink_Speed (Blink_Speed) // blink frequency control
);
endmodule
分了三个模块,PLL,按键消抖和PWM调波
2.按键消抖模块
代码如下(示例):
`timescale 1ns / 1ps
//======================================================================
//Company :
//Filenam : .v
//Author : HX
//Last Modified : 2024-03-13 11:34
//Last Modified : 2023-12-14 18:10
//Description : button jitter reduction module
// blink frequency control module
//
//
//=====================================================================
module led_key(
input clk , // system clk 50Mhz
input rst_n , // system reset
input key , // input button
output reg [15:0] Blink_Speed // output blink freqyency control
);
parameter FREQ = 50 ; // ferquency ()Mhz
parameter TIME_MAX = 20 ; // button running timem
// parameter TIME_MAX = 1 ; // button running timem (1 ms for simulation test)
localparam TIME_VAL = TIME_MAX * FREQ * 1000 ; //the cycle of running time
reg key_value ; // buttom active
reg key_flag ; // buttom be pressed
reg [ 19:0 ] key_cnt ; // buttom Shake free count
reg key_r1 ; // reg1 key
reg key_r2 ; // reg2 key
reg [ 2:0 ] blink_cnt ; // blink frequency count
/**************************************************************************
//take two beats for key
//generata key_value and key_flag
**************************************************************************/
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
key_r1 <= 1'b1;
key_r2 <= 1'b1;
end
else begin
key_r1 <= key;
key_r2 <= key_r1;
end
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
key_cnt <= 20'd0;
end
else begin
if( key_r2 == !key_r1)begin
key_cnt <= TIME_VAL;
end
else begin
if( key_cnt > 20'd0)
key_cnt <= key_cnt - 1'b1;
else
key_cnt <= 20'd0;
end
end
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
key_value <= 1'b1;
key_flag <= 1'b0;
end
else if (key_cnt == 20'd1)begin
key_value <= key;
key_flag <= 1'b1;
end
else begin
key_value <= key_value;
key_flag <= 1'b0;
end
end
/**************************************************************************
//generate blink count and Blink_Speed
**************************************************************************/
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
blink_cnt <= 3'd0;
end
else if(key_flag&&!key_value)begin
blink_cnt <= blink_cnt + 1'b1;
end
else begin
blink_cnt <= blink_cnt ;
end
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
Blink_Speed <= 16'd25;
end
else
case(blink_cnt)
3'd0 : Blink_Speed <= 16'd25;
3'd1 : Blink_Speed <= 16'd50;
3'd2 : Blink_Speed <= 16'd100;
3'd3 : Blink_Speed <= 16'd200;
3'd4 : Blink_Speed <= 16'd500;
3'd5 : Blink_Speed <= 16'd1000;
3'd6 : Blink_Speed <= 16'd5;
3'd7 : Blink_Speed <= 16'd10;
default : Blink_Speed <= 16'd25;
endcase
end
endmodule
该模块实现了按键消抖的功能,每次按键按下控制led的闪烁频率控制字输出至Pwm模块
3、PWM模块
//====================================================================== //Company : //Filenam : .v //Author : HX //Created On : 2024-03-13 11:34 //Last Modified : 2024-03-13 11:34 //Description :PWM module // // //====================================================================== `timescale 1ns / 1ps module led_pwm( input clk , // system clk 50Mhz input rst_n , // system reset input [ 15:0 ] Blink_Speed , // input blink frequency output [ 3:0 ] led // output led "0" active ); reg [ 15:0 ] period_cnt ; // 1kHz-1ms:1000_000/20=50000 reg [ 15:0 ] duty_cycle ; // 1% increase in each cycle:50000*1%=500; reg inc_dec_flag ; // the flag that from bright to dark or from dark to bright //0:from dark to bright reg [ 15:0 ] r_Blink_Speed ; // cache one shot assign led = (period_cnt >= duty_cycle) ? 4'b1010 : 4'b0101; /************************************************************************** //PWM: the cycle sets to 1ms //compare period_cnt and duty_cycle with in this 1ms //EX: the duty cycle is 10% in this 1ms,the meaning is led bright 0.1ms // the duty cycle is 20% in next 1ms,the meaning is led bright 0.2ms // ... // the duty cycle is 100% in next 1ms,the meaning is led bright 1ms // Within 10ms, the light gradually changes from dark to bright **************************************************************************/ always@(posedge clk or negedge rst_n) begin if(!rst_n) r_Blink_Speed <= 16'd50; else r_Blink_Speed <= Blink_Speed; end always@(posedge clk or negedge rst_n) begin if(!rst_n) period_cnt <= 16'd0; else if (period_cnt == 16'd50000) period_cnt <= 16'd0; else period_cnt <= period_cnt + 1'b1; end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin duty_cycle <= 16'd0; inc_dec_flag <= 1'b0; end else begin if(period_cnt == 16'd50000) begin if(inc_dec_flag == 1'b0)begin if(duty_cycle == 16'd50000) begin inc_dec_flag <= 1'b1; end else begin duty_cycle <= duty_cycle + r_Blink_Speed; end end else begin if(duty_cycle == 16'd0) begin inc_dec_flag <= 1'b0; end else begin duty_cycle <= duty_cycle - r_Blink_Speed; end end end end end endmodule
总结
很简单的有个小功能,仿真就不放了,加油