Location>code7788 >text

stm32 F103C8T6 4x4 Matrix Keyboard Use

Popularity:834 ℃/2024-08-05 16:33:54

First of all, I would like to thank JKU for the stm32 introductory course which is very beneficial. Recommend interested friends to take a look.

First, let's see what kind of matrix keyboard I use (a very common one)

Wiring as shown (other models according to their own needs to connect the GPIO port)

The code is based onstm the great and the goodThe code is modified from the code, the talk is very detailed, thank you very much.

Straight to the code:

header file

#ifndef __KEY4x4_H
#define __KEY4x4_H

void KEY_4x4_Init(void); 
void KEY_Scan(void);
u16 Key_Read(void);

#endif

Main document

#include ""
#include ""

u8 anxia = 0;
u8 key = 1;
u16 line[4] = {0x00fe , 0x00fd , 0x00fb ,0x00f7};
u16 off = 0x00ff; // All pins set to 1
u16 keys[16] = {
    49, 50, 51, 65,
    52, 53, 54, 66,
    55, 56, 57, 67,
    42, 48, 35, 68,
};

void KEY_4x4_Init(void){
    
    GPIO_InitTypeDef GPIO_InitStructre;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); // Enable GPIOA clock

// Group I
    GPIO_InitStructre.GPIO_Pin  = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
    GPIO_InitStructre.GPIO_Mode = GPIO_Mode_Out_PP; // push-pull output
    GPIO_InitStructre.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA , &GPIO_InitStructre);
    GPIO_SetBits(GPIOA , GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
    // Second set of data
    GPIO_InitStructre.GPIO_Pin  = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructre.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA , &GPIO_InitStructre);
    GPIO_SetBits(GPIOA , GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
    
}

void Do_Click(uint16_t gpio_pin_x , u8 num){
    anxia = 1;
    key = num;
    while(!GPIO_ReadInputDataBit(GPIOA , gpio_pin_x));
}

void KEY_Click_Listener(u8 num){
    if((GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)==0)){
        Delay_ms(10);
        if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)){
            Do_Click(GPIO_Pin_4 , num+0);
        }else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)){
            Do_Click(GPIO_Pin_5 , num+1);
        }else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)){
            Do_Click(GPIO_Pin_6 , num+2);
        }else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)){
            Do_Click(GPIO_Pin_7 , num+3);
        }else {
            anxia = 0;
            GPIO_Write(GPIOA , off);
        }
    }
}

void KEY_Scan(){
    // First row, 1111, 1110.
    GPIO_Write(GPIOA , line[0]);
    KEY_Click_Listener(1);
    // second line
    GPIO_Write(GPIOA , line[1]);
    KEY_Click_Listener(5);
    // third line
    GPIO_Write(GPIOA , line[2]);
    KEY_Click_Listener(9);
    // fourth line
    GPIO_Write(GPIOA , line[3]);
    KEY_Click_Listener(13);
}

u16 Key_Read(){
    return keys[key-1];
}

Main Code Description:

 

Initialization Configuration (KEY_4x4_Init).

  • Enables clocking of the GPIOA module.
  • Configure the first four pins of GPIOA (GPIO_Pin_0 through GPIO_Pin_3) for push-pull output mode for keyboard line scanning.
  • Set the last four pins of GPIOA (GPIO_Pin_4 through GPIO_Pin_7) to pull-up input mode for detecting the status of the keyboard column lines.
// Group I
    GPIO_InitStructre.GPIO_Pin  = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
    GPIO_InitStructre.GPIO_Mode = GPIO_Mode_Out_PP; // push-pull output
    GPIO_InitStructre.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA , &GPIO_InitStructre);
    GPIO_SetBits(GPIOA , GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
    // Second set of data
    GPIO_InitStructre.GPIO_Pin  = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructre.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA , &GPIO_InitStructre);
    GPIO_SetBits(GPIOA , GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

 

Keystroke Detection (KEY_Click_Listener).

 

  • Detects the state of the column line and, if a key is pressed, calls theDo_ClickThe function logs the key information and waits for the key to be released.
  • Using the delay functionDelay_msto eliminate jitter.
void KEY_Click_Listener(u8 num){
    if((GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)==0)
||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)==0)||(GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)==0)){ Delay_ms(10); if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_4)){ Do_Click(GPIO_Pin_4 , num+0); }else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_5)){ Do_Click(GPIO_Pin_5 , num+1); }else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_6)){ Do_Click(GPIO_Pin_6 , num+2); }else if(0 == GPIO_ReadInputDataBit(GPIOA , GPIO_Pin_7)){ Do_Click(GPIO_Pin_7 , num+3); }else { anxia = 0; GPIO_Write(GPIOA , off); } } }
void Do_Click(uint16_t gpio_pin_x , u8 num){
    anxia = 1;
    key = num;
    while(!GPIO_ReadInputDataBit(GPIOA , gpio_pin_x));
}

 

 

Scanning process (KEY_Scan).

 

  • Cyclically scans each line and detects if a key is pressed by changing the state of the line.
  • invocationsKEY_Click_Listenerfunction to handle keystroke detection for each line.

 

Read key value (Key_Read).

 

  • Returns the value corresponding to the currently pressed key.

Additional Notes:

u16 line[4] = {0x00fe , 0x00fd , 0x00fb ,0x00f7};
u16 off = 0x00ff; // All pins set to 1
u16 keys[16] = {
    49, 50, 51, 65,
    52, 53, 54, 66,
    55, 56, 57, 67,
    42, 48, 35, 68,
};

line defines four hexadecimal values to be converted to binary.
0000 0000 1111 1110  0x00fe

0000 0000 1111 1101 0x00fd

0000 0000 1111 1011 0x00fb

0000 0000 1111 0111 0x00f7

The lower four bits are rows and the upper four bits are columns.

Setting 0 is to set a low level for the corresponding line

This way we can see in the scan code that scanning is done by first setting the incoming line line[x] low

All columns are high When the scan reaches a column that is low it means that the column was clicked.

Cycle from the first column to the fourth column to set a low level until a column is detected to be low as well.

Assuming 1 is clicked, the 1 column is also low.

It's the first row, the first column, low.

This makes sure that 1 is clicked. Just assign 1 to the corresponding parameter

Then according to the defined keys (askII code list corresponding value)

The main code is the above, the other code as long as the copy of the source code of the courseware of OLED Jiangke University can be

Usage

#include ""                  // Device header
#include ""
#include ""
#include ""

int main(void)
{
    
    /*Module initialization*/
    OLED_Init();        //OLED Initialization
    KEY_4x4_Init();
    
    /*OLED display*/
    OLED_ShowString(1, 1, "in put:");                //1 row and 1 column display character A
    u8 num = 0;
    while (1)
    {
        KEY_Scan();
        num = Key_Read();
        OLED_ShowChar(1 ,8 ,num);
    }
}