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 the
Do_Click
The function logs the key information and waits for the key to be released. - Using the delay function
Delay_ms
to 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.
- invocations
KEY_Click_Listener
function 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); } }