新聞中心

        EEPW首頁 > 嵌入式系統 > 牛人業話 > 【從零開始走進FPGA】 基于PLD的矩陣鍵盤狀態機控制

        【從零開始走進FPGA】 基于PLD的矩陣鍵盤狀態機控制

        —— 零基礎學FPGA(十八)基于PLD的矩陣鍵盤狀態機控制
        作者: 時間:2015-03-07 來源:網絡 收藏

          講過了獨立按鍵檢測,理所當然應該講講中矩陣鍵盤的應用了。這個思維和電路在中有所不同,在此,在此做詳細解釋,Bingo用自己設計的成熟的代碼作為案例,希望對你有用。

        本文引用地址:http://www.104case.com/article/270621.htm

          一、矩陣鍵盤電路圖

          在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

        fpga相關文章:fpga是什么




        關鍵詞: FPGA PLD

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 琼结县| 富民县| 沙田区| 葵青区| 田东县| 安泽县| 吉木萨尔县| 永福县| 景宁| 澳门| 新干县| 囊谦县| 邳州市| 安达市| 石首市| 长葛市| 湘乡市| 大悟县| 定远县| 通榆县| 深水埗区| 堆龙德庆县| 依兰县| 赞皇县| 聂拉木县| 嘉祥县| 迁安市| 乐平市| 富平县| 渑池县| 花莲市| 漳州市| 和田市| 修武县| 嘉义市| 手机| 婺源县| 揭西县| 台江县| 德江县| 铜梁县|