适用于需要周期性控制某些开关的场合(由led灯闪烁显示开闭)
/* plan1 自动模式默认5min开2s,手动模式下9-1s开闭循环指定时长(由指令3 4确定),闭合后每3分钟开2秒指定次数(or时间),之后恢复5min开2s自动模式
module wash(clk,rst_n,rx_data,rx_int,led1,led2,wash_en);
input clk;
input rst_n;
input rx_int; //触发信号通知接收数据
input [7:0]rx_data; //接收数据
output reg led1,led2,wash_en;
reg en,en4;
reg rx_int1;
reg rx_int2;
reg [47:0]stop;
reg [47:0]stop1;
reg [47:0]stop2;
reg [47:0]cnt;
reg [47:0]cnt2;
reg [47:0]cnt4;
reg [10:0]state;
reg [10:0]flagcnt; //手动模式后3min 2s次数
reg flag; //手动模式标志位
reg [47:0]value1;
reg [47:0]value10;
parameter s0 = 11'b00000000001;
parameter s1 = 11'b00000000010;
parameter s2 = 11'b00000000100;
parameter s3 = 11'b00000001000;
parameter s4 = 11'b00000010000;
parameter s5 = 11'b00000100000;
parameter s6 = 11'b00001000000;
parameter s7 = 11'b00010000000;
parameter s8 = 11'b00100000000;
parameter s9 = 11'b01000000000;
parameter s10 = 11'b10000000000;
parameter s_9 = 450_000_000;
parameter s_10 = 500_000_000;
parameter s_2 = 100_000_000;
parameter s_180 = 48'd9_000_000_000; //s_180 = 9_000_000_000;
parameter s_300 = 48'd15_000_000_000;//s_300 = 15_000_000_000;
parameter s_1 = 50_000_000;
parameter s_60 = 3_000_000_000;
wire rx_int_r;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rx_int1 <= 0;
rx_int2 <= 0;
end
else
begin
rx_int1 <= rx_int;
rx_int2 <= rx_int1;
end
end
assign rx_int_r = ~rx_int1 & rx_int2;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state <= s0;
stop <= 0;
stop1 <= 0;
stop2 <= 0;
end
else
begin
if(rx_int_r)
begin
case(state)
s0 : if(rx_data == 8'b00110011)
state <= s1;
else
begin
state <= s0;
end
s1 : if(rx_data == 8'b00110011)
state <= s1;
else if(rx_data == 8'b01000100)
state <= s2;
else
state <= s0;
s2 : begin
if(rx_data == 8'b11101000) //E8指令进入手动模式
state <= s3;
else if(rx_data == 8'b11100111) //E7指令手动模式强行停止
state <= s7;
else
state <= s0;
end
s3 : begin
stop <= rx_data * s_60;
state <= s4;
end
s4 : begin
stop1 <= rx_data * s_1;
state <= s5;
end
s5 : begin
stop2 <= stop1 + stop;
state <= s6;
end
s6 : state <= s0;
s7 : state <= s0;
endcase
end
end
end
always@ (posedge clk or negedge rst_n)
if( ! rst_n ) begin en <= 0; flag <= 0; cnt2<= 0;flagcnt<= 0;value1<= s_2;value10<= s_300;wash_en <= 0;end
else if (state == s6 ) begin en <= 1; flagcnt<= 0; value1<= s_9;value10<= s_10;end
else if (en == 1 )
begin
if (cnt2 == stop2 || state == s7)
begin
en <= 0;
wash_en <= 1;
flag<= 1;
value1<= s_2;
value10<= s_180;
end
else cnt2 <= cnt2 + 1'b1;
end
else if (flag == 1 && cnt == s_180)
begin
if (flagcnt >= 2 ) begin flag<= 0;value10<= s_300; end //if (flagcnt == 160 )
else flagcnt <= flagcnt + 1'b1;
end
else begin cnt2 <= 0; wash_en <= 0;end
always@ (posedge clk or negedge rst_n)
if( ! rst_n) begin cnt<= 33 'd0; end
else if( cnt2==1) cnt<= 33 'd0;
else
begin
if (cnt >= value10 ) cnt <= 36 'd0;
else cnt <= cnt + 1'b1;
end
always@ (posedge clk or negedge rst_n)
if( ! rst_n) led1<= 0 ;
else
begin
if (cnt >=1 && cnt <=value1 ) led1 <= 1;
else led1 <= 0;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n )
begin
led2 <= 0;
cnt4 <= 0;
end
else if(state == s6)
begin
led2 <= 1;
cnt4 <= 0;
end
else if(led2)
begin
if(cnt4 == stop|| state == s7)
begin
led2 <= 0;
cnt4 <= 0;
end
else
cnt4 <= cnt4 + 1'b1;
end
end
endmodule*/
// plan2 自动模式默认5min开2s n次,之后7min开2s n次,之后之后10min开2s 无限次,手动模式下9-1s开闭循环指定时长(由指令3 4确定)
module wash(clk,rst_n,rx_data,rx_int,led1,led2,wash_en);
input clk;
input rst_n;
input rx_int;
input [7:0]rx_data;
output reg led1;
output reg led2;
output reg wash_en;
reg en,en0,en1,en2;
reg rx_int1;
reg rx_int2;
reg [47:0]stop;
reg [47:0]stop1;
reg [47:0]stop2;
reg [47:0]cnt,cnt2,cnt4;
reg [10:0]state;
reg [10:0]count0,count1,count2;
reg [47:0]value1; //占空比高电平
reg [47:0]value10; //占空比总时长
parameter s0 = 11'b00000000001;
parameter s1 = 11'b00000000010;
parameter s2 = 11'b00000000100;
parameter s3 = 11'b00000001000;
parameter s4 = 11'b00000010000;
parameter s5 = 11'b00000100000;
parameter s6 = 11'b00001000000;
parameter s7 = 11'b00010000000;
parameter s8 = 11'b00100000000;
parameter s9 = 11'b01000000000;
parameter s10 = 11'b10000000000;
/*
parameter s_9 = 9*1_000_0/20; //9*1_000_0/20;用于仿真
parameter s_10 = 10*1_000_0/20; //10*1_000_0/20;
parameter s_2 = 2*1_000_0/20; //2*1_000_0/20;
parameter s_300 = 300*1_000_0/20;//300*1_000_0/20;
parameter s_420 = 420*1_000_0/20;//300*1_000_0/20;
parameter s_600 = 600*1_000_0/20;//300*1_000_0/20;
parameter s_1 = 1*1_000_0/20; //1*1_000_0/20;
parameter s_60 = 60*1_000_0/20; //60*1_000_0/20;
*/
parameter s_9 = 450_000_000; //9秒次数= 9*1_000_000_000/20; 20ns为时钟周期
parameter s_10 = 500_000_000;
parameter s_2 = 100_000_000;
parameter s_300 = 48'd15_000_000_0;//s_300 = 15_000_000_000;
parameter s_420 = 48'd21_000_000_0;//s_420 = 21_000_000_000;
parameter s_600 = 48'd30_000_000_0;//s_600 = 30_000_000_000;
parameter s_1 = 50_000_000;
parameter s_60 = 3_000_000_000;
parameter s_180 = 48'd9_000_000_00; //s_180 = 9_000_000_000;
wire rx_int_r;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rx_int1 <= 0;
rx_int2 <= 0;
end
else
begin
rx_int1 <= rx_int;
rx_int2 <= rx_int1;
end
end
assign rx_int_r = ~rx_int1 & rx_int2; //检测下降沿
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state <= s0;
stop <= 0;
stop1 <= 0;
stop2 <= 0;
end
else
begin
if(rx_int_r)
begin
case(state)
s0 : if(rx_data == 8'b00110011)
state <= s1;
else
begin
state <= s0;
end
s1 : if(rx_data == 8'b00110011)
state <= s1;
else if(rx_data == 8'b01000100)
state <= s2;
else
state <= s0;
s2 : begin
if(rx_data == 8'b11101000) //E8指令进入手动模式
state <= s3;
else if(rx_data == 8'b11100111) //E7指令手动模式强行停止
state <= s7;
else
state <= s0;
end
s3 : begin
stop <= rx_data * s_60;
state <= s4;
end
s4 : begin
stop1 <= rx_data * s_1;
state <= s5;
end
s5 : begin
stop2 <= stop1 + stop;
state <= s6;
end
s6 : state <= s0;
s7 : state <= s0;
endcase
end
end
end
always@ (posedge clk or negedge rst_n)
if( ! rst_n ) begin en <= 0; en0 <= 1;en1 <= 0;en2 <= 0; cnt2<= 0;count0 <= 0;count1 <= 0;value1<= s_2;value10<= s_300;wash_en <= 0;end
else if (state == s6 ) begin en <= 1; cnt2 <= 0;value1<= s_9;value10<= s_10;end
else if (en == 1 )
begin
if (cnt2 == stop2 || state == s7)
begin
en <= 0;
cnt2 <= 0;
wash_en <= 1;
value1<= s_2;
if(en0) value10<= s_300;
else if(en1) value10<= s_420;
else value10<= s_600;
end
else cnt2 <= cnt2 + 1'b1;
end
else if (en0 == 1 && cnt >= s_300)
begin
if (count0 >= 2 ) begin en0<= 0;en1<= 1;value10<= s_420; end
else count0 <= count0 + 1'b1;
end
else if (en1 == 1 && cnt >= s_420)
begin
if (count1 >= 2 ) begin en1<= 0;en2<= 1;value10<= s_600; end
else count1 <= count1 + 1'b1;
end
else begin wash_en <= 0;end
always@ (posedge clk or negedge rst_n)
if( ! rst_n) begin cnt<= 48 'd0; end
else if( cnt2==1) cnt<= 48 'd0;
else
begin
if (cnt >= value10 ) cnt <= 0;
else cnt <= cnt + 1'b1;
end
always@ (posedge clk or negedge rst_n)
if( ! rst_n) led1<= 0 ;
else
begin
if (cnt >=1 && cnt <=value1 ) led1 <= 1;
else led1 <= 0;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n )
begin
led2 <= 0;
cnt4 <= 0;
end
else if(state == s6)
begin
led2 <= 1;
cnt4 <= 0;
end
else if(led2)
begin
if(cnt4 == stop|| state == s7)
begin
led2 <= 0;
cnt4 <= 0;
end
else
cnt4 <= cnt4 + 1'b1;
end
end
endmodule
下图为自动模式led1的示波器波形图(3-4-6s代替5-7-10m = 300-420-600s,2s不变,次数由8-16h = 96-137-无限次 压缩为3-3-无限次,可根据实际需求调整)
下图为手动模式led1+led2的示波器波形图(1m+2s代替5m+5s)