• 易迪拓培训,专注于微波、射频、天线设计工程师的培养
首页 > 电子设计 > PCB设计 > PCB设计 > 基于PLD的矩阵键盘状态机控制

基于PLD的矩阵键盘状态机控制

录入:edatop.com    点击:

讲讲FPGA中矩阵键盘的应用了。这个思维和电路在FPGA中有所不同,在此,在此做详细解释,Bingo用自己设计的成熟的代码作为案例,希望对你有用。

一、FPGA矩阵键盘电路图

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

61.jpg

在上电默认情况下,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

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

[p]

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

[p]

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

[p]

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。

62.jpg

射频工程师养成培训教程套装,助您快速成为一名优秀射频工程师...

天线设计工程师培训课程套装,资深专家授课,让天线设计不再难...

上一篇:基于FPGA的电梯控制器系统设计
下一篇:基于FPGA的智能驱动控制系统设计

射频和天线工程师培训课程详情>>

  网站地图