embedded-systems-labs/prekol-display/keyboard.c
2025-12-25 11:09:27 +03:00

89 lines
2.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "keyboard.h"
char lastKey;
uint32_t lastScanTime;
void initKeyboard(void) {
// Строки (R1-R4) как выходы с открытым стоком
// PB7, PB6, PB3, PA10
GPIOB->MODER = (GPIOB->MODER & ~(3U << (7 * 2))) | (1U << (7 * 2));
GPIOB->MODER = (GPIOB->MODER & ~(3U << (6 * 2))) | (1U << (6 * 2));
GPIOB->MODER = (GPIOB->MODER & ~(3U << (3 * 2))) | (1U << (3 * 2));
GPIOA->MODER = (GPIOA->MODER & ~(3U << (10 * 2))) | (1U << (10 * 2));
GPIOB->OTYPER |= (1U << 7) | (1U << 6) | (1U << 3);
GPIOA->OTYPER |= (1U << 10);
// Столбцы (C1-C3) как входы с подтяжкой к питанию
// PB10, PB4, PB5
GPIOB->MODER &= ~(3U << (10 * 2) | 3U << (4 * 2) | 3U << (5 * 2));
GPIOB->PUPDR = (GPIOB->PUPDR & ~(3U << (10 * 2))) | (1U << (10 * 2));
GPIOB->PUPDR = (GPIOB->PUPDR & ~(3U << (4 * 2))) | (1U << (4 * 2));
GPIOB->PUPDR = (GPIOB->PUPDR & ~(3U << (5 * 2))) | (1U << (5 * 2));
lastKey = '\0';
lastScanTime = 0;
}
char readKey(void) {
const uint8_t rows[] = {7, 6, 10, 3}; // R1..R4
const uint8_t cols[] = {10, 4, 5}; // C1..C3
// Только первый ряд задействован: B / D / H
const char keymap[4][3] = {
{'B', 'D', 'H'},
{'?', '?', '?'},
{'?', '?', '?'},
{'?', '?', '?'}
};
for (uint8_t i = 0; i < 4; i++) {
// Активируем текущую строку (тянем в 0)
if (rows[i] != 10) {
GPIOB->BSRR = (1U << (rows[i] + 16)); // reset
} else {
GPIOA->BSRR = (1U << (rows[i] + 16));
}
// небольшая задержка
for (volatile int d = 0; d < 100; d++);
// Проверяем столбцы
for (uint8_t j = 0; j < 3; j++) {
if ((GPIOB->IDR & (1U << cols[j])) == 0) {
// Деактивируем строку
if (rows[i] != 10) {
GPIOB->BSRR = (1U << rows[i]);
} else {
GPIOA->BSRR = (1U << rows[i]);
}
return keymap[i][j];
}
}
// Деактивируем строку (отпускаем)
if (rows[i] != 10) {
GPIOB->BSRR = (1U << rows[i]);
} else {
GPIOA->BSRR = (1U << rows[i]);
}
}
return '\0';
}
void scanKeyboard(void) {
// Опрос раз в 100 мс
if (tickCount - lastScanTime > 100) {
lastScanTime = tickCount;
char currentKey = readKey();
if (currentKey != '\0' && currentKey != lastKey) {
printf("Pressed: %c\n", currentKey);
lastKey = currentKey;
} else if (currentKey == '\0') {
lastKey = '\0';
}
}
}