KEYPAD-SMALL-CAL C представляет собой матричную клавиатуру, что означает, что вы должны настроить некоторые контакты как входные, а некоторые как выходные. Это приличная библиотека, которую я лично использовал для своего проекта с использованием матричной клавиатуры - https://github.com/nimaltd/KeyPad
Вы сможете без особых проблем интегрировать ее в свой код. Короче говоря, у вас есть столбцы и строки. В приведенном примере строки являются входными контактами, а столбцы - выходными контактами. Есть цикл for, который проверяет нажатие кнопки. По умолчанию строки являются высокими, после нажатия кнопки библиотека проверяет комбинацию между строкой и столбцом, которая определяет, какая кнопка была нажата. Для вывода конфигурации проще всего было бы использовать программное обеспечение, такое как "STM32CubeMX", которое генерирует код c с конфигурацией вашего микроконтроллера, вы можете легко настроить там строки и столбцы матричной клавиатуры и решить, какие выводы следует использовать для ЖК-дисплея.
Edit: вот модифицированная версия библиотеки github, которую я лично использовал в проекте
исходная клавиатура. c
#include "keyboard.h"
//#define _KEYPAD_DELAY(x) HAL_Delay(x)
const GPIO_TypeDef* _KEYPAD_COLUMN_GPIO_PORT[] =
{
COL_1_GPIO_Port,
COL_2_GPIO_Port,
COL_3_GPIO_Port,
COL_4_GPIO_Port,
COL_5_GPIO_Port,
COL_6_GPIO_Port,
COL_7_GPIO_Port,
COL_8_GPIO_Port
};
const uint16_t _KEYPAD_COLUMN_GPIO_PIN[] =
{
COL_1_Pin,
COL_2_Pin,
COL_3_Pin,
COL_4_Pin,
COL_5_Pin,
COL_6_Pin,
COL_7_Pin,
COL_8_Pin
};
const GPIO_TypeDef* _KEYPAD_ROW_GPIO_PORT[] =
{
ROW_1_GPIO_Port,
ROW_2_GPIO_Port,
ROW_3_GPIO_Port,
ROW_4_GPIO_Port
};
const uint16_t _KEYPAD_ROW_GPIO_PIN[] =
{
ROW_1_Pin,
ROW_2_Pin,
ROW_3_Pin,
ROW_4_Pin
};
KeyPad_t KeyPad;
//#############################################################################################
void KeyPad_Init(void)
{
KeyPad.ColumnSize = sizeof(_KEYPAD_COLUMN_GPIO_PIN)/2;
KeyPad.RowSize = sizeof(_KEYPAD_ROW_GPIO_PIN)/2;
}
//#############################################################################################
uint16_t KeyPad_Scan(void)
{
uint16_t key = 0;
uint8_t hold_key = 0;
int int_btn_cnt = 0;
int int_button_state_change = 0;
GPIO_PinState int_button_current_state = GPIO_PIN_SET;
GPIO_PinState int_button_last_state = GPIO_PIN_SET;
for(uint8_t c=0 ; c<KeyPad.ColumnSize ; c++)
{
for(uint8_t i=0 ; i<KeyPad.ColumnSize ; i++)
HAL_GPIO_WritePin((GPIO_TypeDef*)_KEYPAD_COLUMN_GPIO_PORT[i],_KEYPAD_COLUMN_GPIO_PIN[i],GPIO_PIN_SET);
HAL_GPIO_WritePin((GPIO_TypeDef*)_KEYPAD_COLUMN_GPIO_PORT[c],_KEYPAD_COLUMN_GPIO_PIN[c],GPIO_PIN_RESET);
for(uint8_t r=0 ; r<KeyPad.RowSize ; r++){
while(HAL_GPIO_ReadPin((GPIO_TypeDef*)_KEYPAD_ROW_GPIO_PORT[r],_KEYPAD_ROW_GPIO_PIN[r])==GPIO_PIN_RESET){
int_btn_cnt++;
if(int_btn_cnt == _KEYPAD_DEBOUNCE_TIME_MS){
key |= 1<<c;
key |= 1<<(r+8);
return key;
}
}
int_btn_cnt = 0;
}
}
return key;
}
//#############################################################################################
uint16_t KeyPad_WaitForKey(uint32_t Timeout_ms)
{
volatile uint16_t keyRead;
while(Timeout_ms==0)
{
keyRead = KeyPad_Scan();
if(keyRead!=0)
{
KeyPad.LastKey = keyRead;
return keyRead;
}
}
uint32_t StartTime = HAL_GetTick();
while(HAL_GetTick()-StartTime < Timeout_ms)
{
keyRead = KeyPad_Scan();
if(keyRead!=0){
KeyPad.LastKey = keyRead;
return keyRead;
}
}
return 0;
}
//#############################################################################################
char KeyPad_WaitForKeyGetChar(uint32_t Timeout_ms)
{
char result = 0;
switch(KeyPad_WaitForKey(Timeout_ms))
{
case 0x802: // ^
result = '^';
break;
case 0x804: // 7
result = '7';
break;
case 0x808: // 7
result = '8';
break;
case 0x810: // 9
result = '9';
break;
case 0x820: // 04
result = 0xFF;
break;
case 0x840: // D+
result = 0xFE;
break;
case 0x880: // M
result = 'M';
break;
case 0x401: // -%
result = '-';
break;
case 0x402: // +%
result = '+';
break;
case 0x404: // 4
result = '4';
break;
case 0x408: // 6
result = '5';
break;
case 0x410: // 6
result = '6';
break;
case 0x420: // 03
result = 0xFD;
break;
case 0x440: // PRUREP
result = 0xFC;
break;
case 0x480: // STL
result = 0xFB;
break;
case 0x201: // ALT
result = 0xFA;
break;
case 0x202: // CLK
result = 0xF9;
break;
case 0x204: // 1
result = '1';
break;
case 0x208: // 3
result = '2';
break;
case 0x210: // 3
result = '3';
break;
case 0x220: // 02
result = 0xF8;
break;
case 0x240: // PY1 RA
result = 0xF7;
break;
case 0x101: // C
result = 'C';
break;
case 0x102: // VD
result = 0xF6;
break;
case 0x104: // 0
result = '0';
break;
case 0x108: // .
result = '.';
break;
case 0x110: // QTY
result = 0xF5;
break;
case 0x120: // 01
result = 0xF4;
break;
case 0x140: // PY2PO
result = 0xF3;
break;
case 0x180: // TL
result = 0xF2;
break;
}
return result;
}
и клавиатура файла заголовка. h
#ifndef __KEYBOARD_H__
#define __KEYBOARD_H__
#include <stdint.h>
#include <stdbool.h>
typedef struct
{
uint8_t ColumnSize;
uint8_t RowSize;
uint16_t LastKey;
}KeyPad_t;
void KeyPad_Init(void);
uint16_t KeyPad_WaitForKey(uint32_t Timeout_ms);
char KeyPad_WaitForKeyGetChar(uint32_t Timeout_ms);
#define _KEYPAD_DEBOUNCE_TIME_MS 5
#endif /* __KEYBOARD_H__ */
Вам следует настраивать константные массивы только с портами и выводами, которые вы планируете использовать, и использовать библиотеку следующим образом:
клавиатура инициализации в начале вашей программы:
KeyPad_Init();
и используйте его так:
uint8_t key = KeyPad_WaitForKeyGetChar(1); // wait 1 ms
key - это значение нажатой клавиши, если вы используете KeyPad_WaitForKeyGetChar (0), код останется здесь и будет ждать нажатия клавиши.
Надеюсь, это поможет!