<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 牛人業(yè)話 > 【從零開始走進(jìn)FPGA】 基于PLD的矩陣鍵盤狀態(tài)機(jī)控制

          【從零開始走進(jìn)FPGA】 基于PLD的矩陣鍵盤狀態(tài)機(jī)控制

          —— 零基礎(chǔ)學(xué)FPGA(十八)基于PLD的矩陣鍵盤狀態(tài)機(jī)控制
          作者: 時間:2015-03-07 來源:網(wǎng)絡(luò) 收藏

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

          本文引用地址:http://www.ex-cimer.com/article/270621.htm

            一、矩陣鍵盤電路圖

            在FPGA中的電路,與單片機(jī)雷同,如下所示:

            

          wps_clip_image-30864

           

            在上電默認(rèn)情況下,L[3:0] =4''b1,因為上拉了3.3V,而默認(rèn)情況下H.[3:0]為低電平;一旦有某一個按鍵被按下,便是是的該路電路流向該按鍵的H,是的L檢測不到電流。因此可以通過對每一行H輸出的控制,來檢索是哪一個按鍵被按下了,這也原理和單片機(jī)中一樣,只是寫法不一樣罷了。

            二、FPGA矩陣鍵盤FSM

            1. 代碼

            代碼如下所示,采用了三段式狀態(tài)機(jī)來描述矩陣鍵盤。本模塊形式與上一張按鍵消抖動雷同,方便移植。

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

            * 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. 狀態(tài)機(jī)說明

            (1)以下是該電路的state machine。

            

          wps_clip_image-15561

           

            (2)模塊可分為一下幾個狀態(tài):

            

          image

          fpga相關(guān)文章:fpga是什么




          關(guān)鍵詞: FPGA PLD

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();