logo资料库

数字 PWM 波形发生器设计.docx

第1页 / 共13页
第2页 / 共13页
第3页 / 共13页
第4页 / 共13页
第5页 / 共13页
第6页 / 共13页
第7页 / 共13页
第8页 / 共13页
资料共13页,剩余部分请下载后查看
程序代码 顶层文件 module sr_2193_6( clk, clk1, key_add, key_sub, pwm_out, pwm_number); //顶层文件 input clk,key_add,key_sub; output clk1,pwm_number,pwm_out; wire [7:0] pwm_number; sr_2193_6_1 PWM(clk1,pwm_number,pwm_out); sr_2193_6_2 fpq(clk,clk1); sr_2193_6_3 jsq(clk,key_state1,key_state2,pwm_number); sr_2193_6_4 add(clk, rst, key_add, key_state); sr_2193_6_5 sub(clk, rst, key_sub, key_state); //分频器 //加按键消抖 //减按键消抖 //PWM 波形发生器 //占空比计数 endmodule 分频器 module sr_2193_6_2(clk,clk1); //分频器 //输入端口声明 //输出端口声明 input clk; output clk1; reg clk1; reg [7:0]cnt=10'b0; //变量数据类型声明 initial begin end clk1=0; cnt=0; always@(posedge clk) //偶数分频器设计,输出信号 clk1 为 100kHz,对 clk 进行 500 分频
begin if(cnt==10'd249) begin cnt <= 0; clk1 <= ~clk1; //cnt=249 时重新计数,clk1 取反,得到占空比为 50%的波形信号 end else cnt <= cnt+1; end endmodule 加按键消抖 module sr_2193_6_4(clk, rst, key_add, key_state1); //加按键消抖 input input input output clk; rst; key_add; key_state1; //时钟信号 //复位信号 //加按键输入信号 //加按键稳定状态,低电平为未按下,高电平为按下状态 reg reg reg [3:0] state_n; key_state1; key_temp; //次态 //用于按键上一次状态存储 wire key_posedge; wire key_negedge; //按键上升沿 //按键下降沿 reg reg reg cnt_full; [19:0]cnt; en_cnt; //计数器满时的标志信号 //20 位 2 进制计数器 //使能计数信号 //出现使能计数信号后,才开始计数,其余时刻为清零状态 always@(posedge clk) key_temp <= key_add; assign key_negedge = (key_temp) && (!key_add); assign key_posedge = (!key_temp) && (key_add); //下降沿 //上升沿 //计数器 always@(posedge clk or negedge rst) begin
if(!rst) cnt <= 0; else if(en_cnt) cnt <= cnt + 1'b1; else end cnt<=0; //状态跳转条件 localparam IDLE =4'b0001; localparam S1 =4'b0010; localparam S2 =4'b0100; localparam S3 =4'b1000; //按键没有按下,空闲状态 //按键按下,消除抖动状态 //按键按下,稳定状态 //按键释放,消除抖动状态 //一段式状态机 always@(posedge clk or negedge rst) begin if(!rst) begin state_n <= IDLE; en_cnt <= 1'b0; key_state1 <= 1'b0; end else begin case(state_n) IDLE: begin key_state1 <= 1'b0; if(key_posedge) begin state_n <= S1; en_cnt <= 1'b1; state_n <= IDLE; end else end //使能计数器开始计数 S1: if(cnt_full) begin en_cnt <= 1'b0; //20ms 时间到,计数满后清零,使能计数器进入稳定状态
//如果还没有计完数,就检测到下降沿 //20ms 时间内发生下降沿,使能计数器保持空闲状态(表明只是抖动,不用计数) //key_flag <= 1'b1; key_state1 <= 1'b1; state_n <= S2; end else if(key_negedge) begin en_cnt <= 1'b0; state_n <= IDLE; end else state_n <= state_n; //使能计数器开始计数 //如果还没有计数完,就检测到上升沿 //表示这只是抖动,不用计数,等待下降沿的到来才开始计数 begin key_state1 <= 1'b1; if(key_negedge) begin state_n <= S3; en_cnt <= 1'b1; state_n <= S2; S2: S3: end else end if(cnt_full) begin en_cnt <= 1'b0; state_n <= IDLE; key_state1 <= 1'b1; end else if(key_posedge) begin en_cnt <= 1'b0; state_n <= S2; end else default: state_n <= state_n; begin state_n <= IDLE; end endcase
always@(posedge clk or negedge rst) begin //计数满信号 if(!rst) cnt_full <= 1'b0; else if(cnt == 20'd999_999) else cnt_full <= 1'b1; cnt_full <= 1'b0; end end end endmodule 减按键消抖 module sr_2193_6_5(clk, rst, key_sub, key_state2); //减按键消抖 input input input output clk; rst; key_sub; key_state2; //时钟信号 //复位信号 //减按键输入信号 //减按键稳定状态,低电平为未按下,高电平为按下状态 reg reg [3:0] state_n; key_state2; //次态 reg key_temp; //用于按键上一次状态存储 wire key_posedge; wire key_negedge; //按键上升沿 //按键下降沿 reg reg reg cnt_full; [19:0]cnt; en_cnt; //计数器满时的标志信号 //20 位 2 进制计数器 //使能计数信号 //出现使能计数信号后,才开始计数,其余时刻为清零状态 always@(posedge clk) key_temp <= key_sub; assign key_negedge = (key_temp) && (!key_sub); assign key_posedge = (!key_temp) && (key_sub); //下降沿 //上升沿
//计数器 always@(posedge clk or negedge rst) begin if(!rst) cnt <= 0; else if(en_cnt) cnt <= cnt + 1'b1; else end cnt<=0; //状态跳转条件 localparam IDLE =4'b0001; localparam S1 =4'b0010; localparam S2 =4'b0100; localparam S3 =4'b1000; //按键没有按下,空闲状态 //按键按下,消除抖动状态 //按键按下,稳定状态 //按键释放,消除抖动状态 //一段式状态机 always@(posedge clk or negedge rst) begin if(!rst) begin state_n <= IDLE; en_cnt <= 1'b0; key_state2 <= 1'b0; end else begin case(state_n) IDLE: begin key_state2 <= 1'b0; if(key_posedge) begin state_n <= S1; en_cnt <= 1'b1; state_n <= IDLE; end else end //使能计数器开始计数
//20ms 时间到,计数满后清零,使能计数器进入稳定状态 //如果还没有计完数,就检测到下降沿 //20ms 时间内发生下降沿,使能计数器保持空闲状态(表明只是抖动,不用计数) S1: if(cnt_full) begin en_cnt <= 1'b0; key_state2 <= 1'b1; state_n <= S2; end else if(key_negedge) begin en_cnt <= 1'b0; state_n <= IDLE; end else state_n <= state_n; begin key_state2 <= 1'b1; if(key_negedge) begin state_n <= S3; en_cnt <= 1'b1; state_n <= S2; S2: S3: end else end if(cnt_full) begin en_cnt <= 1'b0; state_n <= IDLE; key_state2 <= 1'b1; end else if(key_posedge) begin en_cnt <= 1'b0; state_n <= S2; end else default: state_n <= state_n; //使能计数器开始计数 //如果还没有计数完,就检测到上升沿 //表示这只是抖动,不用计数,等待下降沿的到来才开始计数
begin state_n <= IDLE; end endcase end end always@(posedge clk or negedge rst) begin //计数满信号 if(!rst) cnt_full <= 1'b0; else if(cnt == 20'd999_999) else cnt_full <= 1'b1; cnt_full <= 1'b0; end endmodule 占空比计数 module sr_2193_6_3(clk,key_state1,key_state2,pwm_number); //占空比计数 //50MHz 时钟信号 input clk; input key_state1,key_state2; output reg[7:0]pwm_number; //加按键,减按键 //占空比 reg[7:0]i; reg[7:0]j; //加计数信号 //减计数信号 initial begin end i=0; j=0; pwm_number=0; //加计数 always@(posedge key_state1) begin if(key_state1 == 1'b1) begin if(i<8'd100)
分享到:
收藏