说明:板子时钟频率200MHz,pwm波周期为1ms,频率为1k的方波信号;
功能:使用计数器延时的方法,延迟150ms输出pwm波
`timescale 1ns / 1ns
module optional_pwm_module
(
input clk, input rst_n, input[2:0]Option_Key,
output pwm_out
);
//定义200MHz频率定时3.9us的常量
parameter SEGMENT=10'd780; //200MHz跳多少下得到3.9us
reg[1:0] pwm_out;
reg[9:0] C1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
C1<=10'd0;
else if(C1==SEGMENT)
C1<=10'd0;
else
C1<=C1+1'b1;
//3.9us计数器,产生1k脉冲的周期为1ms将其分成256块
reg[7:0]System_Seg;
/*System_Seg是自动递增的pwm块,每3.9us都会自动递增
* 当增加到0-255时说明1ms计时结束即一个周期结束,然后又从下一个周期开始*/
always@(posedge clk or negedge rst_n)
if(!rst_n)
System_Seg<=8'd0;
else if(System_Seg==8'd255)
System_Seg<=8'd0;
else if(C1==SEGMENT)
System_Seg<=System_Seg+1'b1;
/*************************按键控制产生pwm脉冲的模块 ***************************************/
reg[7:0]Option_Seg;
always@(posedge clk or negedge rst_n)
if(!rst_n)
Option_Seg<=8'd0;
else if(Option_Key[2]) //Key Up=Segment+10
if(Option_Seg<8'd245)Option_Seg<=Option_Seg+8'd10;
else Option_Seg<=8'd255;
else if(Option_Key[1]) //Key_Down=SEGMENT-10
if(Option_Seg>8'd10)Option_Seg<=Option_Seg-8'd10;
else Option_Seg<=8'd0;
else if(Option_Key[0])
Option_Seg<=8'd127;
reg[17:0] Count1; //用来对延迟计数,18位寄存器用于进行1ms的计时;
reg[6:0] T100MS; //100ms计数器用来使pwm延迟100ms输出
always@(posedge clk or negedge rst_n)
if(!rst_n) Count1<=18'd0;
else if(Count1>=18'd199_999) //1ms counter
Count1<=18'd0;
else begin Count1<=Count1+18'd1;end
always@(posedge clk or negedge rst_n) //延迟100ms输出
if(!rst_n)
begin
T100MS<=7'd0;
pwm_out<=1'b0;
end
else if(T100MS>=7'd99)
begin
T100MS<=7'd0;
// pwm_out<=1'b0;
assign pwm_out= (System_Seg<Option_Seg)?1'b1:1'b0;
end
else begin
pwm_out<=1'b0;
// assign pwm_out= (System_Seg<Option_Seg)?1'b1:1'b0;
T100MS<=T100MS+7'd1;
end
// always@(posedge clk or negedge rst_n)
当System_Seg计数器从0-127递增时,由于Ssystem_Seg<Option_Seg,
// assign pwm_out= (System_Seg<Option_Seg)?1'b1:1'b0;
Option_Seg相当于一个对比常量,当system_seg<option_seg时pwm_out为高电平,反之为低电平。
endmodule
其他生成PWM延迟的方法
//用多位寄存器移位传输数据
input pulse_in;
wire pulse_out;
reg[9:0] pulse_tmp;
reg[3:0] Count; //10ns延迟输出pulse_out
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
pulse_tmp<=10'd0;
else if(Count>=4'd0&&Count<=4'd10)
pulse_tmp<=10'd0;
pulse_in==1'b0;
else(Count>=4'd10)
pulse_in==1'b1
pulse_tmp<={pulse_tmp[8:0],pulse_in};
end
assign pulse_out<=pulse_tmp[9];
//计数器延时
//原理为采样到输入脉冲后将flag信号置为1,开始计数,计数到需要的延时
//后,输出一个脉冲信号,同时清除计数,清零flag信号
module pusle_delay(
input clk,
input rst_n,
input Delay_In,
output Delay_Out
);
reg[7:0] delay_plus;
reg Delay_plus;
reg plus_flag;
assign Delay_Out=Delay_plus;
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
plus_flag<=1'b0;
else if(Delay_In==1'b1)
plus_flag<=1'b1;
else if(delay_plus[7:0]==16'h8)
plus_flag<=1'0;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
delay_plus[7:0]<=8'd0;
Delay_plus<=1'b0;
end
else if(delay_plus[7:0]==16'h87&plus_flag==1'b1)//延时时间
begin
delay_plus[7:0]<=8'd0;
Delay_plus<=1'b1;
end
else if(plus_flag==1'b1)begin
Delay_plus<=1'b0;
delay_plus[7:0]<=delay_plus[7:0]+1'b1;
end
else begin
delay_plus[7:0]<=8'd0;
Delay_plus<=1'b0;
end
end
endmodule