FPGA|CPLD|ASICwilliam hill官网
直播中

苏永志

6年用户 69经验值
擅长:可编程逻辑
私信 关注
[问答]

如何用verilog语言实现按键按一次是开始,再按一次是暂停

`按键是按下后自动弹起的 没法根据按键的高低电平判断按键是开始状态还是暂停状态 这个应该怎么实现按键两种状态的判断呢 求解` pause.png

回帖(8)

苏永志

2017-11-7 15:39:27
大神赶紧知道我一下呀 如何判断状态
举报

钟哥

2017-11-8 15:14:17
本帖最后由 钟哥30 于 2017-11-8 15:17 编辑

使用边沿检测试试
reg key1,key2;
wire key_pos,key_neg;
always@(posedge clk) begin
  if(!rse_n) begin
    key1 <= 1'b1;    key2 <= 1'b1;
  end
  else begin
    key1 <= key;//key连接按键的IO口
    key2 <= key1;
  end
end
assign key_neg = key2&&(!key1);
assign key_pos = (!key2) && key1;
举报

冷锋

2017-11-8 17:38:22
接楼上
reg key_state;
always @ (posedge clk or posedge rst)
begin
    if (rst == 1)
        key_state <= 1'b0;
    end
    else if(key_pos == 1'b1)
    begin
        key_state  <= ~key_state ;
    end
end
key_state  应该就是你要的信号吧
举报

苏永志

2017-11-10 18:04:05
引用: 钟哥30 发表于 2017-11-8 15:14
使用边沿检测试试
reg key1,key2;
wire key_pos,key_neg;

这是监测上升沿和下降沿的,按键不是自锁按键,按下后自动弹起,这个解决了,用状态机写的
举报

苏永志

2017-11-10 18:19:00
module control_cnt(clk_100hz,reset,on_off,pause);
input clk_100hz,reset,on_off;
output reg pause;
reg [1:0] current_state;
reg [1:0] next_state;
parameter [1:0] clear=2'b00;
parameter [1:0] on=2'b01;
parameter [1:0] off=2'b10;
always@(posedge clk_100hz or negedge reset)
begin
   if(!reset)
     current_state<=clear;
   else
     current_state<=next_state;
end
always@(current_state or on_off or reset)
begin
   case(current_state)
           clear:
             begin
                    if(!reset)
                           begin
                                  next_state=clear;
                                  pause=0;
                                end
                         else
                          begin
                           if(on_off)
                            begin
                                  next_state=on;
                                  pause=1;
                                 end
                           else
                            begin
                                  next_state=clear;
                                  pause=0;
                                 end
                    end
                 end
                on:
                  begin
                    if(!reset)
                           begin
                                 next_state=clear;
                                 pause=0;
                                end
                         else
                           begin
                             if(on_off)
                              begin
                                     next_state=off;
                                     pause=0;
                                   end
                                  else
                                   begin
                                          next_state=on;
                                          pause=1;
                                        end
                                end
                  end
                off:
                  begin
                    if(!reset)
                           begin
                                     next_state=clear;
                                     pause=0;
                                end
                    else
                           begin
                            if(on_off)
                                   begin
                                      next_state=on;
                                          pause=1;
                                        end
                                 else
                                   begin
                                           next_state=off;
                                                pause=0;
                                        end
                          end       
                  end
                default:    next_state=off;
         endcase
  end
endmodule

最后用了状态机控制输出pause信号,同一个非自锁开关按键作开始和暂停键,低电平表示开始,高电平表示暂停
举报

qpalzmal

2017-11-10 20:26:56
按键按下做一个去抖动后提上升沿,产生一个脉冲信号,当检测到该脉冲给计数器加1。当脉冲到来且计数器最低位为0则产生start信号,当脉冲到来且计数器最低位为1则产生stop信号
举报

钟哥

2017-11-13 08:44:11
本帖最后由 钟哥30 于 2017-11-13 09:16 编辑
引用: 无影000 发表于 2017-11-10 18:19
module control_cnt(clk_100hz,reset,on_off,pause);
input clk_100hz,reset,on_off;
output reg pause;

首先在第一个always里面你已经做了复位信号发生时状态机切换处理了第二个里面就不用再写关于复位状态切换了,你这样看上去有点累赘了。
其次你这个on_off就是连接的那个按键吧,若按键默认连接的就是高电平,你这个pause结果不就是一个方波嘛你看啊,上电完成初始化后,你写的应该是处于on状态机,然后检测on_off电平状态为1的话状态机调到off状态并且pause == 1,然后下一个clk在off状态机里面继续检测on_ff为1的话又跳会on状态并且paus == 0,如果按键默认上拉至高电平,不是无论你有没有操作按键,你的pause都在高低电平之间进行切换,产生一个方波嘛,怎么适合你的需求了,可以采用边沿检测的方式实现你的功能的,当边沿检测发生了,并且判断当前状态跳转值下一个状态否则维持当前状态。
图片是我对你那程序的一个仿真,你看我只是吧on_ff一直拉高,是不是pause就是一个周期性的方波。On_ff为高模拟的是你的按键默认接高电平或者你的按键是按键下去为高点平状态,但是我长按 该按键,所以我认为按键这样要么延时消抖处理要么边沿检测吧(我推荐边沿,可以在上边边沿检测处多定义几级寄存器然后级联就可以做到误操作排除了)
1 举报

苏永志

2017-11-13 20:40:25
嗯 on_off信号是检测下降沿延时20ms后取值得到的值 是不是再用边沿检测得到一个持续一个时钟的脉冲信号 用这个脉冲信号作为状态机的触发信号 这样是不是更好一点 这样就不会有持续on_off信号的存在了吧 然后把on_off触发改成那个脉冲触发
举报

更多回帖

发帖
×
20
完善资料,
赚取积分