Matrix button row and column scanning method and reverse scanning method: principle and code implementation

Matrix buttons: row-column scanning method and reverse scanning method
Normally, when the button is pressed, a low-level signal will be generated, and the button generally uses a low level to indicate the pressed state.

When the key is not pressed, it is usually in a high level state, because when the key is connected to the circuit, the internal pull-up resistor or external pull-up resistor will pull the state of the key not pressed to a high level. When the button is pressed, the inside of the button is turned on, so that the pin connected to the circuit is in a low state, thereby indicating that the button is pressed.

This low level indicates a pressed design is common because in digital circuits, a low level is usually considered a logic "0" and a high level is considered a logic "1". By using a low level to indicate a press, logic judgment and control can be performed more easily. Of course, according to the requirements of specific applications, a high level can be used in the design to indicate pressing, and it only needs to be processed according to the corresponding logic.


1. Matrix button row and column scanning method:


principle:

The matrix button row and column scanning method is a simple and intuitive button scanning method. In the matrix key row and column scanning method, the keys of the keyboard are cross-connected through rows and columns to form a matrix. Each key is located at the intersection of a row and a column. By means of polling and scanning, the state of each button is detected one by one. When a button is pressed, which button is pressed can be determined by judging the corresponding row and column.

Generally speaking:
row scanning, the row line is low level, and the column line is high level. (As far as the STC89C5 type of machine is concerned, column scanning is generally used, thinking that the row line port may be occupied by other pins (multiplexing) ))
Column scan, row line is high level, column line is low level.

advantage:

The matrix key row and column scanning method is simple and easy to understand, and the implementation cost is low, and it is suitable for a small-scale keyboard matrix.


shortcoming:

As the size of the keyboard increases, the scanning efficiency decreases because each key needs to be scanned one by one.

Matrix button row and column scanning method (assuming GPIO control pins are used):

#include <stdio.h>
#include <stdbool.h>

// Define the number of rows and columns
#define NUM_ROWS 4
#define NUM_COLS 4

// define the row and column pins
int rows[NUM_ROWS] = {R0, R1, R2, R3}; // the specific pins in the array
int cols[NUM_COLS] = {C0, C1, C2, C3}; // in the array for a specific pin

// Initialize pin state
void setup() {     for (int i = 0; i < NUM_ROWS; i++) {         pinMode(rows[i], OUTPUT); //Row configuration is output mode,         digitalWrite(rows[i], LOW); //The row initialization level is low level     }     for (int i = 0; i < NUM_COLS; i++) {         pinMode(cols[i], INPUT_PULLUP); //Columns are configured as input mode, pull-up     } }







// Scan keyboard status
void scanKeypad() {     for (int col = 0; col < NUM_COLS; col++) {         // Set the current column pin to low level         digitalWrite(cols[col], LOW);         for (int row = 0; row < NUM_ROWS; row++) {             // Detect row pin status, if it is low, it means that the button is pressed             if (digitalRead(rows[row]) == LOW) {                 // process here Button press logic                 // ...             }         }         // Set the current column pin to high level, ready to scan the next column         digitalWrite(cols[col], HIGH);     } }













int main() {
    setup();
    while (true) {
        scanKeypad();
    }
    return 0;


2. Inverse scan method


principle:

The reverse scan method is another common key scan method. In the reverse scan method, the row and column pins are connected separately, the row pins are set as output, and the column pins are set as input. Then, set the row pins to high level one by one, and detect the state of the column pins to determine the state of the key.

advantage:

The scanning efficiency of the reverse scanning method is relatively high, and it is suitable for a large-scale keyboard matrix, because it only needs to scan row pins one by one.


shortcoming:

Compared with the matrix button row and column scanning method, the inversion scanning method is slightly more complicated in hardware connection.


Inverted scanning method (assuming GPIO control pins are used):


#include <stdio.h>
#include <stdbool.h>

// Define the number of rows and columns
#define NUM_ROWS 4
#define NUM_COLS 4

// Define row and column pins
int rows[NUM_ROWS] = {R0, R1, R2, R3};
int cols[NUM_COLS] = {C0, C1, C2, C3};

// 初始化引脚状态
void setup() {
    for (int i = 0; i < NUM_COLS; i++) {
        pinMode(cols[i], OUTPUT);
        digitalWrite(cols[i], HIGH);
    }
    for (int i = 0; i < NUM_ROWS; i++) {
        pinMode(rows[i], INPUT_PULLUP);
    }
}

// Scan keyboard status
void scanKeypad() {     for (int row = 0; row < NUM_ROWS; row++) {         // Set current row pin to low level         digitalWrite(rows[row], LOW);         for (int col = 0; col < NUM_COLS; col++) {             // detect the state of the column pin, if it is low, it means that the button is pressed             if (digitalRead(cols[col]) == LOW) {                 // process here Button press logic                 // ...             }         }         // Set the current row pin to high level, ready to scan the next row         digitalWrite(rows[row], HIGH);     } }













int main() {
    setup();
    while (true) {
        scanKeypad();
    }
    return 0;
}

 Example:

The schematic diagram of a 51-matrix button is as follows:

 #define KEY_MATRIX_PORT P1

//Row and column selection method:

unsigned char key_matrix_ranks_scan(void)
{
    unsigned char key_value=0;

    KEY_MATRIX_PORT=0xf7;//Assign 0 to the first column
    if(KEY_MATRIX_PORT!=0xf7)//Determine whether the first column button is pressed
    {         delay_10us(1000);//Debounce         switch(KEY_MATRIX_PORT)//Save the first column button Key value after pressing             {             case 0x77: key_value=1;break;             case 0xb7: key_value=5;break;             case 0xd7: key_value=9;break;             case 0xe7: key_value=13;break;         }     }     while(KEY_MATRIX_PORT!= 0xf7);//Wait for the button to be released         KEY_MATRIX_PORT=0xfb;//Assign 0 to the second column, and the rest are all 1     if(KEY_MATRIX_PORT!=0xfb)//Judge whether the button in the second column is pressed     {         delay_10us(1000);/ /Debounce         switch(KEY_MATRIX_PORT)//Save the key value after the second column button is pressed             {










    






            case 0x7b: key_value=2;break;
            case 0xbb: key_value=6;break;
            case 0xdb: key_value=10;break;
            case 0xeb: key_value=14;break;
        }
    }
    while(KEY_MATRIX_PORT!=0xfb);//wait for key Release     KEY_MATRIX_PORT         = 0xfd     ; //Assign         0 to     the third column
    
    , and the rest are all 1 //Save the key value after pressing the button in the third column             {             case 0x7d: key_value=3;break;             case 0xbd: key_value=7;break;             case 0xdd: key_value=11;break;             case 0xed: key_value=15;break;         }     }











    while(KEY_MATRIX_PORT!=0xfd);//Wait for the button to be released    
    
    KEY_MATRIX_PORT=0xfe;//Assign 0 to the fourth column, and the rest are all 1
    if(KEY_MATRIX_PORT!=0xfe)//Judge whether the button in the fourth column is pressed
    {         delay_10us (1000);//Debounce         switch(KEY_MATRIX_PORT)//Save the key value after pressing the button in the fourth column             {             case 0x7e: key_value=4;break;             case 0xbe: key_value=8;break;             case 0xde: key_value=12 ;break;             case 0xee: key_value=16;break;         }     }     while(KEY_MATRIX_PORT!=0xfe);//Wait for the key to be released     return key_value;         }










    

//line inversion method:

unsigned char key_matrix_flip_scan(void)
{
    static unsigned char key_value=0;

    KEY_MATRIX_PORT=0x0f;//Assign 0 to all rows, all columns are 1
    if(KEY_MATRIX_PORT!=0x0f)//Determine whether the button is pressed
    {         delay_10us(1000);//Debounce         if(KEY_MATRIX_PORT!=0x0f)         {             // Test column             KEY_MATRIX_PORT=0x0f;             switch(KEY_MATRIX_PORT)//save behavior 0, the column value after the button is pressed                 {                 case 0x07: key_value=1;break;                 case 0x0b: key_value=2;break;                 case 0x0d: key_value=3;break ;                 case 0x0e: key_value=4;break;             }             //Test line             KEY_MATRIX_PORT=0xf0;             switch(KEY_MATRIX_PORT)//Save the column as 0, the key value after pressing the key    















            {
                case 0x70: key_value=key_value;break;
                case 0xb0: key_value=key_value+4;break;
                case 0xd0: key_value=key_value+8;break;
                case 0xe0: key_value=key_value+12;break;
            }
            while(KEY_MATRIX_PORT!=0xf0);//等待按键松开    
        }
    }
    else
        key_value=0;        
    return key_value;        
}

 


 

Guess you like

Origin blog.csdn.net/weixin_53000184/article/details/132053159