展开全部
module pwm_test(
input clk , //时钟输入,可在外部设置不同时钟
input rst_n , //低电平复位
input [7:0] f , //频率控制,最大255
input [7:0] d , //占空比控制字,上限100
output pwm_out //PWM输出
);
reg [17:0] count ; //计数
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
count <= 0 ;
end
else if(count >= 17'd100_000) //计数到100K清零
count <= 0 ;
else
count <= count + f; //每次累加频率值
end
assign pwm_out = (count < d*1000)? 1:0 ;//PWM输出
endmodule
思路就是倍频累加。
例如输入时钟100M,频率设为20的时候,计数100K,每次加20,输出频率就是100M/(100K/20)=20K,占空比为20的时候,计数到20K跳变。
至于输入时钟,用Tools->Megawizard Plug-In Manager->I/O->ALTPLL模块设置PLL分频,倍频即可
module keyscan(
input clk ,
input rst_n ,
input [3:0] key,
output reg [7:0] f ,
output reg [7:0] d
);
parameter H = 99 ;
parameter L = 5 ;
//wire [3:0] key2 ;
reg [31:0]count ;
reg clk_div ;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) count <= 32'b0 ;
else if (count==32'd10_000_000)begin
clk_div <= ~clk_div ;
count <= 32'b0 ;
end
else count <= count +32'b1;
end
always @(posedge clk_div or negedge rst_n) begin
if(~rst_n) begin
f <= 8'd20;d <= 8'd30;
end
else
case(key)
4'b0111: begin if(f<H)f <= f + 8'b1;else f <= H;end
4'b1011: begin if(f>L)f <= f - 8'b1;else f <= L;end
4'b1101: begin if(d<H)d <= d + 8'b1;else d <= H;end
4'b1110: begin if(d>L)d <= d - 8'b1;else d <= L;end
default: begin f <= f ; d <= d ;end
endcase
end
endmodule
按键控制,不需要频率控制的话删掉就行
pwm_test PWM_0(
.clk(clk_sel) ,
.rst_n(rst_n) ,
.f(frequency),
.d(duty) ,
.pwm_out(out) ,
);
keyscan KSCAN(
.clk(clk) ,
.rst_n(rst_n) ,
.key(KEY) ,
.f(frequency) ,
.d(duty)
);
PLL_ctrl PLL_ctrl_inst (
.areset ( ~rst_n ),
.inclk0 ( clk ),
.c0 ( clk_100M ),
.c1 ( clk_10M ),
.c2 ( clk_1M ),
.c3 ( clk_100K )
);
顶层把这些模块连起来即可,不动了再问我
input clk , //时钟输入,可在外部设置不同时钟
input rst_n , //低电平复位
input [7:0] f , //频率控制,最大255
input [7:0] d , //占空比控制字,上限100
output pwm_out //PWM输出
);
reg [17:0] count ; //计数
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
count <= 0 ;
end
else if(count >= 17'd100_000) //计数到100K清零
count <= 0 ;
else
count <= count + f; //每次累加频率值
end
assign pwm_out = (count < d*1000)? 1:0 ;//PWM输出
endmodule
思路就是倍频累加。
例如输入时钟100M,频率设为20的时候,计数100K,每次加20,输出频率就是100M/(100K/20)=20K,占空比为20的时候,计数到20K跳变。
至于输入时钟,用Tools->Megawizard Plug-In Manager->I/O->ALTPLL模块设置PLL分频,倍频即可
module keyscan(
input clk ,
input rst_n ,
input [3:0] key,
output reg [7:0] f ,
output reg [7:0] d
);
parameter H = 99 ;
parameter L = 5 ;
//wire [3:0] key2 ;
reg [31:0]count ;
reg clk_div ;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) count <= 32'b0 ;
else if (count==32'd10_000_000)begin
clk_div <= ~clk_div ;
count <= 32'b0 ;
end
else count <= count +32'b1;
end
always @(posedge clk_div or negedge rst_n) begin
if(~rst_n) begin
f <= 8'd20;d <= 8'd30;
end
else
case(key)
4'b0111: begin if(f<H)f <= f + 8'b1;else f <= H;end
4'b1011: begin if(f>L)f <= f - 8'b1;else f <= L;end
4'b1101: begin if(d<H)d <= d + 8'b1;else d <= H;end
4'b1110: begin if(d>L)d <= d - 8'b1;else d <= L;end
default: begin f <= f ; d <= d ;end
endcase
end
endmodule
按键控制,不需要频率控制的话删掉就行
pwm_test PWM_0(
.clk(clk_sel) ,
.rst_n(rst_n) ,
.f(frequency),
.d(duty) ,
.pwm_out(out) ,
);
keyscan KSCAN(
.clk(clk) ,
.rst_n(rst_n) ,
.key(KEY) ,
.f(frequency) ,
.d(duty)
);
PLL_ctrl PLL_ctrl_inst (
.areset ( ~rst_n ),
.inclk0 ( clk ),
.c0 ( clk_100M ),
.c1 ( clk_10M ),
.c2 ( clk_1M ),
.c3 ( clk_100K )
);
顶层把这些模块连起来即可,不动了再问我
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询