清霜一梦

4*4键盘扫描程序

0
阅读(1208)

键盘扫描程序,用来扫描4*4键盘

module keybd_scan  (
                                    clock ,
                                    reset ,
                                    ver_sig,   // vertical  signal 
                                    hor_sig  , // horizontal signal 
                                    data_out 
                                    );
    input clock ,reset ;
    input                [3:0]    ver_sig ;
    output     reg         [3:0]    hor_sig ;
    output   reg     [4:0]    data_out ; 
    
    reg   [3:0] cosc_state ; 
    reg             key_on ; 
    //-------------------------------------------------------
    always @ (posedge clock  )
    if(!reset )  
        begin 
            cosc_state  <= 4'd0 ; 
            key_on  <= 1'd0 ;  end 
    else 
        begin 
                if (!(&ver_sig)) 
                        begin 
                                cosc_state <=  4'b0000 ;
                                key_on       <=  1'd1 ;     
                        end 
                else   if (key_on )
                        case (cosc_state )
                                4'b0000  :  begin  key_on <= 1'd1 ;     cosc_state <= 4'b0001  ;  end 
                                4'b0001  :  begin  key_on <= 1'd1 ;     cosc_state <= 4'b0010   ; end 
                                4'b0010  :  begin  key_on <= 1'd1 ;     cosc_state <= 4'b0100   ; end 
                                4'b0100  :  begin  key_on <= 1'd1 ;     cosc_state <= 4'b1000   ; end 
                                default  :   begin   key_on <= 1'd0 ; cosc_state <= 3'd0 ; end 
                        endcase   
                        
                else 
                        begin 
                                //key_on       <= 1'd0 ; 
                                cosc_state <= 3'd0 ; 
                        end 
        end 

        reg    scan_state ; 
// generate  codesan  
always @(posedge clock )
    if(!reset )
        begin 
            hor_sig       <= 4'd0 ; 
            scan_state  <= 1'd0 ; 
        end 
    else if(key_on)
            case (scan_state)
                    1'b0  :   begin   hor_sig  <=  4'b1110 ;  scan_state  <=  1'b1; end 
                    1'b1  :   begin   hor_sig  <= {hor_sig[0],  hor_sig[3:1]}   ;   scan_state <= 1'b1;  end 
            endcase 
    else  
        begin 
                scan_state  <=  1'b0 ; 
                hor_sig       <=   4'b0000;
        end 
    
        
        reg [4:0]  data_out_reg ; 
//--------------------------------------------------------------------------------------------------------------------------------------        
always @ (posedge clock)          
if(!reset )  data_out_reg  <= 5'd0 ;                                                  //------------------------------------------------
else         case ({hor_sig,  ver_sig})                                       //             |   0        1        2         3       |        
            8'b0111_1110: data_out_reg <= 5'h00;                                    //       |   4         5          6          7       |
            8'b1011_1110: data_out_reg <= 5'h04;                                    //       |   8         9           a          b      | 
            8'b1101_1110: data_out_reg <= 5'h08;                                   //        |   c         d           e          f       |
            8'b1110_1110: data_out_reg <= 5'h0c;                           //        |-------------------------------------------------
                                                                              //                 +         -           *          /   
            8'b0111_1101: data_out_reg <= 5'h01;
            8'b1011_1101: data_out_reg <= 5'h05;  
            8'b1101_1101: data_out_reg <= 5'h09;
            8'b1110_1101: data_out_reg <= 5'h0d; 
        
            8'b0111_1011: data_out_reg <= 5'h02;
            8'b1011_1011: data_out_reg <= 5'h06; 
            8'b1101_1011: data_out_reg <= 5'h0a;
            8'b1110_1011: data_out_reg <= 5'h0e; 
    
            8'b0111_0111: data_out_reg <= 5'h03;
            8'b1011_0111: data_out_reg <= 5'h07;  
            8'b1101_0111: data_out_reg <= 5'h0b;
            8'b1110_0111: data_out_reg <= 5'h0f;
            default              data_out_reg <= 5'h1f;
        endcase 

always @ (posedge clock)
 if(!reset )  data_out  <= 5'd0 ; 
 else   begin 
    if ((data_out_reg >=5'h0)  && (data_out_reg <= 5'h0f)) 
            data_out     <=   data_out_reg;
    else if (!key_on)   data_out  <= 5'h1f;   end 
    //else if (1)   data_out  <= 5'h07;

endmodule

ver_sig 是输入扫描信号,hor_sig 是键盘输出的信号。