Проблема с программированием аппаратного обеспечения c - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть анимация, показанная на светодиодах. Когда кнопка нажата, анимация должна остановиться, а затем продолжить после повторного нажатия кнопки. Есть метод, который обрабатывает работу с кнопкой:

void checkButton(){

GPIO_PinState state;

state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15);
if (state == GPIO_PIN_RESET) {
    while(1){
        state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15);
        if (state == GPIO_PIN_SET){
            break;
        }
    }
    //while (state == GPIO_PIN_RESET) {
        //state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15);
    //}
}
}

GPIO_PIN_SET - позиция кнопки по умолчанию. GPIO_PIN_RESET - это состояние, когда кнопка нажата. Раздел с комментариями - это то, что я пробовал вместо while(1){...} l oop. Время от времени в главном l oop вызывается метод checkButton(). Программа работает на STM32 с модулем расширения (здесь тип модуля расширения не имеет значения). Дело в том, что этот метод останавливает анимацию на мгновение и не работает так, как мне бы хотелось. Не могли бы вы что-нибудь исправить в этой программе, чтобы она работала правильно?

1 Ответ

1 голос
/ 18 апреля 2020

Не могли бы вы что-нибудь исправить в этой программе, чтобы она работала правильно?

Мне кажется, вы пытаетесь добавить аспект «взаимодействия с человеком» в свой дизайн. Ваш текущий подход основан на единственном образце (положение кнопки), случайным образом синхронизированном а) вашим приложением и б) человеческим пальцем. Это время просто ненадежно, но исправление, возможно, не слишком сложно.


Примечание 1. «Простая» механическая кнопка будет «подпрыгивать» во время активации или отпускания (да, в любом случае). Это означает, что значение, которое программа «видит» (в течение нескольких микросекунд), непредсказуемо в течение нескольких (tbd) миллисекунд (?) Рядом с кнопкой pu sh или отпуском.

Примечание 2: Другой способ Посмотрите на эту проблему: ваше значение состояния существует в двух местах: в физической кнопке И в переменной «GPIO_PinState state;». ИМХО, значение состояния может находиться только в одном месте. Два места это всегда ошибка.

Решение, тогда (если вы верите) состоит в том, чтобы принять решение о сохранении «состояния» одного состояния и исключении другого. ИМХО, я думаю, вы хотите сохранить кнопку, которая, кажется, ваш человеческий вклад. Чтобы было понятно, вы хотите исключить переменную «Состояние GPIO_PinState»


Эта строка:

state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15);

производит выборку состояния переключателя один раз.

ОДНАКО Вы уже знаете, что этот дизайн не может полагаться на правильность прочитанного. В конце концов, ваш пользователь мог просто нажать или отпустить кнопку, и она просто подпрыгивает во время выборки.

Прежде чем мы начнем собирать выборки, вы должны знать, что отскок может продолжаться гораздо дольше чем несколько микросекунд. Я видел, как некоторые переключатели отскакивают до 10 миллисекунд или больше. Если имеется тестовое оборудование, я бы подключил его и посмотрел на характеристики вашей кнопки. Если нет, то вы можете попробовать настроить элементы управления следующего накопителя образцов.


Итак, как мы «накапливаем» достаточно образцов, чтобы быть уверенными, что мы можем знать состояние переключателя?

Рассмотрим несколько выборок, разнесенных во времени с небольшими задержками (2 элемента управления?). Я думаю, что вы можете просто накапливать их. Первый счет, который достигнет tbr - 5 (или 10 или 100?) Образцов выигрывает. Так что вращайте выборку, задержку и инкремент одного из двух счетчиков:

stateCount [2] = {0,0};  // state is either set or reset, init both to 0
//              vvv-------max samples
for (int i=0; i<100; ++i)  // worst case how long does your  switch bounce
{
    int sample = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_15);  // capture 1 sample

    stateCount[sample] += 1;  // increment based on sample

    // if 'enough' samples are the same, kick out early
    //                       v ---- how long does your switch bounce
    if (stateCount[sample] > 5) break; // 5 or 10 or 100 ms

    // to-be-determined --------vvv --- how long does switch bounce
    std::this_thread::sleep_for(1ms);  // 1, 3, 5 or 11 ms between samples
    // C++ provides, but use what is available for your system
    // and balanced with the needs of your app
}

FYI - приведенная выше схема имеет 3 настройки для обработки различной длительности отказов переключателя ... У вас есть некоторые эксперименты, которые нужно сделать. Я бы начал с максимальной выборки в 20. У меня нет рекомендаций для sleep_for ... Вы не предоставили никакой другой информации о вашей системе.

Удачи.

Это было давно, но Кажется, я помню, что кнопки pu sh на оборудовании телекоммуникационной инфраструктуры отскакивали от 5 до 15 мс.

...