您的位置 首页 传感器

【从零开始走进FPGA】 根据PLD的矩阵键盘状态机操控

讲过了独立按键检测,理所当然应该讲讲FPGA中矩阵键盘的应用了。这个思维和电路在FPGA中有所不同,在此,在此做详细解释,Bingo用自己设计的成熟的代码作为案例,希望对你有用。一、FPG

  讲过了独立按键检测,天经地义应该讲讲FPGA中矩阵键盘的应用了。这个思维和电路在FPGA中有所不同,在此,在此做具体解说,Bingo用自己规划的老练的代码作为事例,期望对你有用。

  一、FPGA矩阵键盘电路图

  在FPGA中的电路,与单片机相同,如下所示:

  

wps_clip_image-30864

 

  在上电默许情况下,L[3:0] =4”b1,由于上拉了3.3V,而默许情况下H.[3:0]为低电平;一旦有某一个按键被按下,就是是的该路电路流向该按键的H,是的L检测不到电流。因而能够经过对每一行H输出的操控,来检索是哪一个按键被按下了,这也原理和单片机中一样,仅仅写法不一样算了。

  二、FPGA矩阵键盘FSM

  1. 代码

  代码如下所示,采用了三段式状况机来描绘矩阵键盘。本模块方式与上一张按键消颤动相同,便利移植。

  /*************************************************

  * Module Name : matrix_key_design.v

  * Engineer : Crazy Bingo

  * Target Device : EP2C8Q208C8

  * Tool versions : Quartus II 11.0

  * Create Date : 2011-6-26

  * Revision : v1.0

  * Description :

  **************************************************/

  module matrix_key_design

  (

  input clk,

  input rst_n,

  input [3:0] col_data,

  output reg [3:0] row_data,

  output key_flag, //the mark of key is pressed

  output reg [3:0] key_value

  );

  //generate for 2ms signal

  reg [19:0] cnt; //fffff,≈50Hz 20ms

  always @(posedge clk or negedge rst_n)

  begin

  if(!rst_n)

  cnt <= 0;

  else

  cnt <= cnt+1’b1;

  end

  /*****************************************************

  * R3 >—0—-1—-2—-3

  * | | | |

  * R2 >—4—-5—-6—-7

  * | | | |

  * R1 >—8—-9—-A—-B

  * | | | |

  * R0 >—C—-D—-E—-F

  * | | | |

  * C3 C2 C1 C0

  *****************************************************/

  parameter SCAN_IDLE = 3’b000;

  parameter SCAN_JITTER= 3’b001;

  parameter SCAN_COL0 = 3’b011;

  parameter SCAN_COL1 = 3’b010;

  parameter SCAN_COL2 = 3’b110;

  parameter SCAN_COL3 = 3’b100;

  parameter SCAN_READ = 3’b101;

  parameter SCAN_JTTTER2= 3’b111;

  reg [2:0] current_state;

  reg [2:0] next_state;

  always@(posedge clk or negedge rst_n)

  begin

  if(!rst_n)

  current_state <= SCAN_IDLE;

  else if(cnt == 20’hfffff)

  current_state <= next_state;

  end

  always@*

  begin

  case(current_state)

  SCAN_IDLE : //init

  if(col_data != 4’b1111) next_state = SCAN_JITTER;

  else next_state = SCAN_IDLE;

  SCAN_JITTER: //escape the jitter

  if(col_data != 4’b1111) next_state = SCAN_COL0;

  else next_state = SCAN_IDLE;

  SCAN_COL0 : //1th row

  if(col_data != 4’b1111) next_state = SCAN_READ;

  else next_state = SCAN_COL1;

  SCAN_COL1 : //2th row

  if(col_data != 4’b1111) next_state = SCAN_READ;

  else next_state = SCAN_COL2;

  SCAN_COL2 : //3th row

  if(col_data != 4’b1111) next_state = SCAN_READ;

  else next_state = SCAN_COL3;

  SCAN_COL3 : //4th row

  if(col_data != 4’b1111) next_state = SCAN_READ;

  else next_state = SCAN_IDLE;

  SCAN_READ : //lock the vaule

  if(col_data != 4’b1111) next_state = SCAN_JTTTER2;

  else next_state = SCAN_IDLE;

  SCAN_JTTTER2: //when your hand is gone

  if(col_data != 4’b1111) next_state = SCAN_JTTTER2;

  else next_state = SCAN_IDLE;

  endcase

  end

  reg [3:0] col_data_r;

  reg [3:0] row_data_r;

  reg key_flag_r0;

  always@(posedge clk or negedge rst_n)

  begin

  if(!rst_n)

  begin

  row_data <= 4’b0000;

  Key_flag_r0 <= 0;

  end

  else if(cnt == 20’hfffff)

  begin

  case(next_state)

  SCAN_IDLE : begin

  row_data <= 4’b0000;

  key_flag_r0 <= 0;

  end

  //SCAN_JITTER:

  SCAN_COL0 : row_data <= 4’b1110;

  SCAN_COL1 : row_data <= 4’b1101;

  SCAN_COL2 : row_data <= 4’b1011;

  SCAN_COL3 : row_data <= 4’b0111;

  SCAN_READ : begin

  row_data_r <= row_data;

  col_data_r <= col_data;

  key_flag_r0 <= 1;

  end

  //SCAN_JTTTER2:

  default:; //default vaule

  endcase

  end

  end

  always @(posedge clk or negedge rst_n)

  begin

  if(!rst_n)

  key_value <= 0;

  else if(cnt == 20’hfffff)

  begin

  if(key_flag_r0 == 1’b1) //the mark of key is pressed

  begin

  case ({row_data_r,col_data_r}) //row_data Row, col_data Col

  8’b0111_0111: key_value <= 4’h0;

  8’b0111_1011: key_value <= 4’h1;

  8’b0111_1101: key_value <= 4’h2;

  8’b0111_1110: key_value <= 4’h3;

  8’b1011_0111: key_value <= 4’h4;

  8’b1011_1011: key_value <= 4’h5;

  8’b1011_1101: key_value <= 4’h6;

  8’b1011_1110: key_value <= 4’h7;

  8’b1101_0111: key_value <= 4’h8;

  8’b1101_1011: key_value <= 4’h9;

  8’b1101_1101: key_value <= 4’hA;

  8’b1101_1110: key_value <= 4’hB;

  8’b1110_0111: key_value <= 4’hC;

  8’b1110_1011: key_value <= 4’hD;

  8’b1110_1101: key_value <= 4’hE;

  8’b1110_1110: key_value <= 4’hF;

  default : key_value <= key_value;

  endcase

  end

  else

  key_value <= key_value;

  end

  end

  //Capture the falling endge

  reg key_flag_r2,key_flag_r1;

  always@(posedge clk or negedge rst_n)

  begin

  if(!rst_n)

  begin

  key_flag_r1 <= 0;

  key_flag_r2 <= 0;

  end

  else

  begin

  key_flag_r1 <= key_flag_r0;

  key_flag_r2 <= key_flag_r1;

  end

  end

  assign key_flag = key_flag_r2 & ~key_flag_r1; //when your hand is gone

  endmodule

  2. 状况机阐明

  (1)以下是该电路的state machine。

  

wps_clip_image-15561

 

  (2)模块可分为一下几个状况:

  

image

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/chuanganqi/116810.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部