Verilog/CPLD代码之按键控制流水灯
2017-03-07 00:09
1691 查看
实验现象:按键控制流水灯启停与移动方向,sw1_n控制流水灯启停,
sw2_n控制流水灯左移,sw3_n控制流水灯右移,间隔1s
module Key_to_LED_verilog(
clk,rst_n,sw1_n,sw2_n,sw3_n,
led
);
input clk; //50MHZ时钟
input rst_n; //复位
input sw1_n,sw2_n,sw3_n; //按键,sw1_n启停,sw2_n左移,sw3_n右移
output[7:0] led; //LED 0-亮,1-灭
reg led_dir; //1--left, 0--right
reg led_on; //1--on, 0--off
//////////////////////////////
//LED移位控制程序
reg [25:0]cnt; //计数寄存器
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) cnt <= 26'd0;
else if(cnt == 26'd50000000) cnt <= 26'd0; //如果计数值达到50M(1s),计数归零
else cnt <= cnt + 1'b1; //计数值不到50M,自动加1
end
reg [7:0]led_r;//8位LED状态寄存器
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) led_r <= 8'b11111110; //复位初值
else if(cnt == 26'd50000000 && led_on) //如果计数值达到50M(1s)且led_on=1,允许移位
begin
if(led_dir)led_r <= {led_r[0],led[7:1]}; //LED状态寄存器移位
else led_r <= {led_r[6:0],led[7]}; //LED状态寄存器移位
end
end
assign led = led_r;
///////////////////////////////
//3位按键程序
reg[19:0] cntkey; //计数寄存器
always @ (posedge clk or negedge rst_n)
if (!rst_n) cntkey <= 20'd0; //异步复位
else cntkey <= cntkey + 1'b1;
reg [2:0]low_sw;
always @(posedge clk or negedge rst_n)
if (!rst_n) low_sw <= 3'b111;
else if (cntkey == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中cnt == 20'hfffff
low_sw <= {sw3_n,sw2_n,sw1_n};
reg [2:0]low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
always @ ( posedge clk or negedge rst_n )
if (!rst_n) low_sw_r <= 3'b111;
else low_sw_r <= low_sw;
wire [2:0]led_ctrl = low_sw_r[2:0] & (~low_sw[2:0]);
//////////////////////////////////////
//判断键值与功能
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin
led_on = 1'b0;
led_dir = 1'b0;
end
else
begin
if(led_ctrl[0]) led_on <= ~led_on;
if(led_ctrl[1]) led_dir <= 1'b1;
if(led_ctrl[2]) led_dir <= 1'b0;
end
endmodule
sw2_n控制流水灯左移,sw3_n控制流水灯右移,间隔1s
module Key_to_LED_verilog(
clk,rst_n,sw1_n,sw2_n,sw3_n,
led
);
input clk; //50MHZ时钟
input rst_n; //复位
input sw1_n,sw2_n,sw3_n; //按键,sw1_n启停,sw2_n左移,sw3_n右移
output[7:0] led; //LED 0-亮,1-灭
reg led_dir; //1--left, 0--right
reg led_on; //1--on, 0--off
//////////////////////////////
//LED移位控制程序
reg [25:0]cnt; //计数寄存器
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) cnt <= 26'd0;
else if(cnt == 26'd50000000) cnt <= 26'd0; //如果计数值达到50M(1s),计数归零
else cnt <= cnt + 1'b1; //计数值不到50M,自动加1
end
reg [7:0]led_r;//8位LED状态寄存器
always @(posedge clk or negedge rst_n)
begin
if(!rst_n) led_r <= 8'b11111110; //复位初值
else if(cnt == 26'd50000000 && led_on) //如果计数值达到50M(1s)且led_on=1,允许移位
begin
if(led_dir)led_r <= {led_r[0],led[7:1]}; //LED状态寄存器移位
else led_r <= {led_r[6:0],led[7]}; //LED状态寄存器移位
end
end
assign led = led_r;
///////////////////////////////
//3位按键程序
reg[19:0] cntkey; //计数寄存器
always @ (posedge clk or negedge rst_n)
if (!rst_n) cntkey <= 20'd0; //异步复位
else cntkey <= cntkey + 1'b1;
reg [2:0]low_sw;
always @(posedge clk or negedge rst_n)
if (!rst_n) low_sw <= 3'b111;
else if (cntkey == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中cnt == 20'hfffff
low_sw <= {sw3_n,sw2_n,sw1_n};
reg [2:0]low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
always @ ( posedge clk or negedge rst_n )
if (!rst_n) low_sw_r <= 3'b111;
else low_sw_r <= low_sw;
wire [2:0]led_ctrl = low_sw_r[2:0] & (~low_sw[2:0]);
//////////////////////////////////////
//判断键值与功能
always @(posedge clk or negedge rst_n)
if (!rst_n)
begin
led_on = 1'b0;
led_dir = 1'b0;
end
else
begin
if(led_ctrl[0]) led_on <= ~led_on;
if(led_ctrl[1]) led_dir <= 1'b1;
if(led_ctrl[2]) led_dir <= 1'b0;
end
endmodule
相关文章推荐
- 用FPGA实现8'bitSRAM读写控制的Verilog代码
- 黑金开发板状态机实现的可用按键控制的流水灯
- FIFO 的控制逻辑---verilog代码
- 32学习之中断 外部中断 按键控制流水灯不同速度
- 按键控制流水灯快慢及其方向
- 用C#代码控制快捷键 如:自动按键
- 按键控制流水灯启动,停止,加速,减速
- 用C代码写贪吃蛇游戏--用按键控制蛇移动
- wince6.0 +S3C6410 中断处理例子(按键控制LED灯)+应用程序控制LED流水灯
- 发一个用状态机实现的按键检测是VERILOG代码
- 毕设 !!!(红色代码为电机控制,为什么按下按键电机转动一段时间以后,自己又停了呢,理论上不按停止应该一直转啊???!!!)
- LED_1_3(按键多模式控制流水灯)
- FPGA按键去抖verilog代码
- CPLD/FPGA/Verilog_如何写代码减少逻辑单元的使用数量
- 基于mini2440按键控制电子相册(裸机代码)
- P1口外接8个LED,通过按键控制,实现左右移动的流水灯
- 基于STM32CT117E竞赛板(STM32f103RB)按键控制LED流水灯
- Verilog/CPLD代码之共阳数码管显示
- STM32F103(按键控制流水灯方向)
- 基于mini2440的按键中断控制LED(裸机代码)