chern55 писал(а):бла-бла... А библиотека то где ?
Просить готовую библиотеку - это подход ардуинщиков. Им алгоритм ненада, им нада библиотека. Ее втулил - и все работает. И даже думать не нада.
Вон на 21 странице вы выклаадывали вариант на базе Гайверовской либы. Там все просто - подключил, кнопку скормил - и думать не нада. Все работает само. It's a magic!
А потом нужно будет к МК подключить 12 кнопок.... Фигня вопрос - выделяем на каждую кнопку отдельный пин порта. Делаем 12 экземпляров кнопки средствами гайверовской библиотеки.
Каждый экземпляр - 12 байт флагов да 20 байт переменных
Спойлер
Код: Выделить всё
struct ButtonFlags {
bool btn_deb;
bool hold_flag;
bool isHolded_f;
bool isRelease_f;
bool isPress_f;
bool step_flag;
bool oneClick_f;
bool isOne_f;
bool inv_state;
bool type;
bool tickMode;
bool noPin;
};
private:
volatile uint8_t* _port;
uint8_t _pin;
ButtonFlags flags;
bool type = 0;
uint16_t _debounce = 60;
uint16_t _timeout = 500;
uint16_t _click_timeout = 300;
uint16_t _step_timeout = 200;
uint8_t btn_counter = 0, last_counter = 0, last_hold_counter = 0;
uint32_t btn_timer = 0;
bool btn_state = 0;
bool btn_flag = 0;
bool butRead(volatile uint8_t* port, uint8_t pin);
Итого 32 байта * 12 кнопок = 384 байта ОЗУ...
А потом приезжает из Китая клавиатура - а там матрицы 3 х 4.... Воблин. А как же ее подключить к
библиотеке???
Это, наверное, нужно искать другую библу, для матричных клавиатур...
Поэтому правильно не библиотеку искать/просить/писать, а алгоритм.
Вплоть до того, что карандашиком на бумажечке.
Разрисовать, какговорил
КРАМ, временную диаграмму, натянув ее на свои кнопки либо матрицу кнопок.
И когда будет готов алгоритм - он прекрасно ляжет на любой язык программирования и любой МК.
Возможно, этот алгоритм разложится на простые "кубики", которые могут применяться и в других случаях...
Но для определения пути опроса кнопок, повторю еще раз, нужна постановка задачи. Универсальных алгоритмов с идеальной реализацией на все случаи жизни не существует.
А, есть еще вариант. Спросить код у ИИ.
Для примера я попросила код опроса 6 кнопок на порту В с подавлением дребезга. Копилот мне выдал вот такое:
Спойлер
Код: Выделить всё
#include <avr/io.h>
#include <avr/interrupt.h>
#define BUTTON_PORT PORTB
#define BUTTON_PIN PINB
#define BUTTON_DDR DDRB
#define DEBOUNCE_DELAY 100 // Задержка подавления дребезга в мс
volatile uint8_t button_state = 0; // Состояние кнопок
volatile uint8_t button_debounced = 0; // Состояние кнопок после подавления дребезга
volatile uint8_t button_changed = 0; // Флаг изменения состояния кнопок
void init_timer() {
// Настройка таймера для генерации прерываний каждые 1 мс
TCCR0 |= (1 << WGM01) | (1 << CS01) | (1 << CS00); // CTC режим, прескалер 64
OCR0 = 124; // Частота прерываний 1 кГц (при F_CPU = 8 МГц)
TIMSK |= (1 << OCIE0); // Разрешение прерываний по совпадению
}
ISR(TIMER0_COMP_vect) {
static uint8_t count[6] = {0, 0, 0, 0, 0, 0}; // Счётчики для подавления дребезга
uint8_t current_state = ~BUTTON_PIN & 0x3F; // Считывание текущего состояния кнопок (6 кнопок на нижних 6 битах)
for (uint8_t i = 0; i < 6; i++) {
if ((current_state & (1 << i)) != (button_state & (1 << i))) {
count[i]++;
if (count[i] >= DEBOUNCE_DELAY) {
button_state ^= (1 << i); // Изменение состояния кнопки
button_changed |= (1 << i); // Установка флага изменения
count[i] = 0;
}
} else {
count[i] = 0;
}
}
button_debounced = button_state;
}
void init_buttons() {
BUTTON_DDR &= ~0x3F; // Настройка первых 6 бит порта B как входы
BUTTON_PORT |= 0x3F; // Включение подтягивающих резисторов
}
int main() {
cli(); // Запрет глобальных прерываний
init_buttons();
init_timer();
sei(); // Разрешение глобальных прерываний
while (1) {
if (button_changed) {
// Обработка изменения состояния кнопок
for (uint8_t i = 0; i < 6; i++) {
if (button_changed & (1 << i)) {
if (button_debounced & (1 << i)) {
// Кнопка нажата
} else {
// Кнопка отпущена
}
}
}
button_changed = 0;
}
}
return 0;
}
Я код не проверяла, но на первый взгляд, должно быть норм