您的位置:首页 > 其它

键盘扫描程序 FPGA

2013-03-05 14:36 274 查看
原文地址:键盘扫描程序 FPGA作者:luqiang200006
    
下面是一个4*4的矩阵键盘,是我们老师为了给我们练手而买的,今天上午老师让我们编写了键盘扫描程序,并用板上的LED显示出来。这里有三个程序,前面两个是别人写的,后面一个是我自己写的。

 


网上下的程序如下:

module key

  (clk,  //50MHZ

   reset,

  
row,   //行

  
col,   //列

   key_value 
//键值

   );

input clk,reset;

input [3:0] row;

output [3:0] col;

output [3:0] key_value;

reg [3:0] col;

reg [3:0] key_value;

reg [5:0] count;//delay_20ms

reg [2:0] state;  //状态标志

reg key_flag;   //按键标志位

reg clk_500khz;  //500KHZ时钟信号

reg [3:0] col_reg;  //寄存扫描列值

reg [3:0] row_reg;  //寄存扫描行值

always @(posedge clk or negedge reset)

if(!reset) begin clk_500khz<=0;
count<=0; end

else

begin

if(count>=50) begin
clk_500khz<=~clk_500khz;count<=0;end

else count<=count+1;

end

always @(posedge clk_500khz or negedge reset)

if(!reset) begin
col<=4'b0000;state<=0;end

else

begin

case (state)

0:

 begin

col[3:0]<=4'b0000;

key_flag<=1'b0;

if(row[3:0]!=4'b1111) begin
state<=1;col[3:0]<=4'b1110;end
//有键按下,扫描第一行

else state<=0;

end

1: 

begin

if(row[3:0]!=4'b1111) begin
state<=5;end  
//判断是否是第一行

else  begin
state<=2;col[3:0]<=4'b1101;end 
//扫描第二行

end

2:

begin   

if(row[3:0]!=4'b1111) begin
state<=5;end   
//判断是否是第二行

else  begin
state<=3;col[3:0]<=4'b1011;end 
//扫描第三行

end

3:

begin   

if(row[3:0]!=4'b1111) begin
state<=5;end  
//判断是否是第三一行

else  begin
state<=4;col[3:0]<=4'b0111;end 
//扫描第四行

end

4:

begin   

if(row[3:0]!=4'b1111) begin
state<=5;end  //判断是否是第一行

else  state<=0;

end

5:

begin 

if(row[3:0]!=4'b1111)

begin

col_reg<=col;  //保存扫描列值

row_reg<=row;  //保存扫描行值

state<=5;

key_flag<=1'b1;  //有键按下

end            

else

begin state<=0;end

end   

endcase

end          

always @(clk_500khz or col_reg or row_reg)

begin

if(key_flag==1'b1)

begin

case ({col_reg,row_reg})

8'b1110_1110:key_value<=0;

8'b1110_1101:key_value<=1;

8'b1110_1011:key_value<=2;

8'b1110_0111:key_value<=3;

8'b1101_1110:key_value<=4;

8'b1101_1101:key_value<=5;

8'b1101_1011:key_value<=6;

8'b1101_0111:key_value<=7;

8'b1011_1110:key_value<=8;

8'b1011_1101:key_value<=9;

8'b1011_1011:key_value<=10;

8'b1011_0111:key_value<=11;

8'b0111_1110:key_value<=12;

8'b0111_1101:key_value<=13;

8'b0111_1011:key_value<=14;

8'b0111_0111:key_value<=15;    

endcase

end  

end      

endmodule

 

另一个程序,和上面的思想一样:

 

module key44

(

      
code     
,

      
col      
,

      
valid    
,

      
row    
  ,

      
sys_clk   ,

      
rst 

);

 

//-------------------------------------------------------------------------------------------------

// Port declaration

output  [3:0] 
col    
;

output        
valid   ;

output  [3:0] 
code    ;

 

input  
[3:0] 
row    
;

input
         sys_clk,rst
;

 

//-------------------------------------------------------------------------------------------------

//

reg    
[3:0]  col,code;

reg    
[5:0]  state,next_state;

 

parameter  S_0 = 6'b000001,

          
S_1 = 6'b000010,

          
S_2 = 6'b000100,

          
S_3 = 6'b001000,

          
S_4 = 6'b010000,

          
S_5 = 6'b100000;

reg       
S_row ;

reg [3:0] count,row_reg,col_reg;

reg      
clk2,clk4;

 

 

reg [4:0] Mega_cnt;

wire     
clk;

 

always @( posedge sys_clk, negedge rst )

begin

      
if(!rst)      
Mega_cnt<=0;

      
else 
      
Mega_cnt<=Mega_cnt+1;

end

 

assign clk = Mega_cnt[4];

 

// Frequency Division Two

always @( posedge clk )

clk2 <= ~clk2;

 

// A quarter of the clk

always @( posedge clk2 )

clk4 <= ~clk4;

 

always @( posedge clk4, negedge rst )

if(!rst)

      
begin

             
count <= 0;

             
S_row <= 0;

      
end

else

      
begin

      
      
if(!(row[0]&row[1]&row[2]&row[3]))

             
      
begin

                    
      
if(count < 'd4)  count
<= count +
1;     
      
// Filter

                    
      
else        
      
S_row <= 1;

             
      
end

             
else if((state == S_0) || (state == S_5))

             
      
begin

                    
      
count <= 0;

                    
      
S_row <= 0;

             
      
end

      
end

 

assign valid = ((state == S_1)||(state == S_2)||(state ==
S_3)||(state == S_4))
&& 
(!(row[3]&row[2]&row[1]&row[0]));

 

// Save the value of row and col

always @( negedge clk )

if( valid )

      
begin

      
      
row_reg <= row ;

      
      
col_reg <= col ;

      
end

 

// Decode the Key

always @( row_reg, col_reg, clk )

      
case( {row_reg,col_reg} )

      
      
8'B1110_1110: code = 4'hd;

      
      
8'B1110_1101: code = 4'h9;

      
      
8'B1110_1011: code = 4'h5;

      
      
8'B1110_0111: code = 4'h1;

             

      
      
8'B1101_1110: code = 4'he;

      
      
8'B1101_1101: code = 4'ha;

      
      
8'B1101_1011: code = 4'h6;

      
      
8'B1101_0111: code = 4'h2;

             

      
      
8'B1011_1110: code = 4'hf;

      
      
8'B1011_1101: code = 4'hb;

      
      
8'B1011_1011: code = 4'h7;

      
      
8'B1011_0111: code = 4'h3;

             

      
      
8'B0111_1110: code = 4'h0;

      
      
8'B0111_1101: code = 4'hc;

      
      
8'B0111_1011: code = 4'h8;

      
      
8'B0111_0111: code = 4'h4;

      
4000
       
default             
: code = 4'h0;

      
endcase

 

always @( posedge clk4, negedge rst )

      
if( !rst )

             
state <= S_0 ;

      
else

             
state <= next_state ;

 

always @( state, row, S_row )

begin

      
col = 0;

      
// Decoding...

      
S_1 :  begin

             
      
col = 4'b1110;

             
      
if(row!='hf)      
next_state = S_5;

             
      
else        
      
next_state = S_2;

             
end

      
S_2 :  begin

             
      
col = 4'b1101;

             
      
if(row!='hf)      
next_state = S_5;

             
      
else        
      
next_state = S_3;

             
end

      
S_3 :  begin

             
      
col = 4'b1011;

             
      
if(row!='hf)      
next_state = S_5;

             
      
else        
      
next_state = S_4;

             
end 

      
S_4 :  begin

             
      
col = 4'b0111;

             
      
if(row!='hf)      
next_state = S_5;

             
      
else        
      
next_state = S_0;

             
end 

      
//----------------------------------------------

      
S_5 :  begin

             
      
col = 4'b0000;

             
      
if(row == 4'b1111)
      
next_state = S_0;

             
      
else
      
             
      
next_state = S_5;

             
end

      
default: next_state = S_0;

      
endcase

end

endmodule 

 

下面是我自己写的一个程序:

module Key_led(clk,row,col,key_temp);

input clk,row;

output key_temp,col;

reg[3:0]
key_temp;                                    
//key temporary value

reg[3:0] col;

wire[3:0] row;

reg key_down , clk_100;

reg[1:0] key_curstate ,key_nexstate;

integer cont;

always @(posedge clk)

begin

if(cont==500000) cont=1;

else cont=cont+1;

if(cont==1) clk_100=1;

else clk_100=0;

end                                   

initial begin

key_curstate=2'b00;

end

always @(posedge clk_100)

begin

if(row!=4'b1111) key_down=1;

else key_down=0;

end

always @(posedge clk_100)

begin

col=4'b0000;

case(key_curstate)

00:begin

if(key_down==0) key_nexstate=00;

else key_nexstate=10;

end

10:begin

if(key_down==0) key_nexstate=01;

else key_nexstate=11;

end

11:begin

if(key_down==0) key_nexstate=01;

else key_nexstate=11;

end

01:begin

if(key_down==0) key_nexstate=00;

else key_nexstate=10;

end

endcase

if(key_curstate==2'b11)begin

col=4'b0111;

  if(row==4'b0111) key_temp=4'h0;

  else if(row==4'b1011) key_temp=4'h4;

  else if(row==4'b1101) key_temp=4'h8;

  else if(row==4'b1110) key_temp=4'hc;

  else begin

   
col=4'b1011;

   
if(row==4'b0111) key_temp=4'h1;

    else
if(row==4'b1011) key_temp=4'h5;

    else
if(row==4'b1101) key_temp=4'h9;

    else
if(row==4'b1110) key_temp=4'hd;

    else
begin

     
col=4'b1101;

     
if(row==4'b0111) key_temp=4'h2;

     
else if(row==4'b1011) key_temp=4'h6;

     
else if(row==4'b1101) key_temp=4'ha;

     
else if(row==4'b1110) key_temp=4'he;

     
else begin

        
col=4'b1110;

        
if(row==4'b0111) key_temp=4'h3;

        
else if(row==4'b1011) key_temp=4'h7;

        
else if(row==4'b1101) key_temp=4'hb;

        
else if(row==4'b1110) key_temp=4'hf;

      
end

    
end

   end

  end

end

 

always @(posedge clk_100)

key_curstate=key_nexstate;

endmodule

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: