Светодиодный куб AtMega16

Код предназначен для светодиодного куба, и я хочу добавить новую функцию. Когда кто-то нажимает кнопку, подключенную к PORTB0, текущий световой эффект должен измениться.

Я пробую что-то, но это не работает.

Программа для ATmega16, а код написан в Atmer Studio 6

код


person Community    schedule 16.08.2012    source источник


Ответы (1)


Как выглядит схема, подключенная к B0?

Предполагая, что одна сторона переключателя идет к B0, а другая к земле, ваши значения направления и подтягивания хороши, но ваш оператор if должен искать бит 0 PINB, чтобы перейти от 1 к 0 при нажатии кнопки. При включенном подтягивании бит будет равен 1, когда кнопка не нажата, и 0, когда она нажата.

В вашем коде вы рассматриваете ввод как «край», но на самом деле это «уровень». Я имею в виду, что нажатие кнопки изменяет входной сигнал на длительный период времени с точки зрения процессора. Вы хотите изменить эффект перехода

Здесь есть еще одна проблема, связанная с устранением дребезга переключателей. Когда переключатель нажат, он не переключается напрямую с выключения на включение. Во время перехода слышен шум, который для вашего кода будет выглядеть как множество нажатий кнопок.

Устранение дребезга может быть выполнено аппаратно или программно. В программном обеспечении я бы сделал что-то подобное в вашем внутреннем цикле в delay_ms:

static unsigned int debounce; 
static const unsigned int presscount = 500;
if ((PINB&1)==0) { // switch is pressed
    if (debounce < presscount ) {
        ++debounce;
    }
} 
else {
    if (debounce > 0) {
        --debounce;
    }
}
if (debounce == presscount ) {
    // switch has been pressed long enough 
    debounce = 0; // reset
    i = (i+1)%4;
    return;
}

Это увеличит эффект не более одного раза каждые 500 циклов. Если вы продолжите удерживать кнопку, эффекты продолжат меняться. Возможно, вы захотите изменить код так, чтобы он не увеличивал эффект снова до тех пор, пока переключатель не будет выключен на некоторое время, чтобы каждое нажатие выполняло только одно увеличение, независимо от того, как долго оно удерживается. Для приведенного выше кода вы можете поиграть с константой 'presscount', чтобы увидеть, что она делает.

Надеюсь, это поможет.

person kday    schedule 17.08.2012
comment
Это помогло мне написать это внутри delay_ms unsigned short int b_was=1; if ((PINB&1)==0 && b_was==1) b_was=0; else if ( PINB&1==1 && b_was==0) { b_was=1; i = (i+1)%4; launch_effect(i); } Мне интересно, можно ли это как-то сделать, не теряя смысла функции delay_ms? - person ; 17.08.2012
comment
В идеале функция delay_ms не должна ничего делать, кроме задержки. Вы можете вызвать delay_ms(1) в основном цикле и чередовать его с проверкой пин-кода. Это было бы чище. Ваша идея b_was находится на правильном пути, но вам все равно нужно учитывать устранение дребезга, если только это уже не сделано аппаратно. - person kday; 17.08.2012