AVR C Почему не прерывать это?

Недавно я пытался сделать прерывание на моем atmega328p, используя atmelstudio, чтобы светодиод, подключенный к цифровому контакту 13/PB5/PCINT5, мигал в четыре раза медленнее, чем обычно, когда кнопка подключена к выходу 5 В и цифровому контакту 2/PD0/PCINT18 нажата.

Но всякий раз, когда я запускаю код и нажимаю кнопку, он никогда (насколько я могу судить) не сбудется с кодом прерывания.

#include <avr/io.h>
#include <avr/interrupt.h>

volatile int t = 1;
int main(void)
{
    init();
    Serial.begin(9600);
    DDRB = (1 << 5);
    DDRD &= ~(1 << DDD2);     // Clear the PD2 pin
    // PD2 (PCINT0 pin) is now an input

    PORTD |= (1 << PORTD2);    // turn On the Pull-up
    // PD2 is now an input with pull-up enabled



    EICRA |= (1 << ISC00);    // set INT0 to trigger on ANY logic change
    EIMSK |= (1 << INT0);     // Turns on INT0

    sei();                    // turn on interrupts
    Serial.println("loop started");

    while(1)
    {
        PORTB ^= (1 << 5);
        delay(500*t);
    }
}



ISR (INT0_vect)
{
    Serial.println("interrupt");
    if(t=1){
        t=4;
    }
    else{
        t=1;
    }
}

Я просмотрел таблицу данных несколько раз и в конце концов наткнулся на этот код в Интернете (да, я знаю, что я настоящий кусок работы) и добавил к нему свои собственные части. но это даже это не работает, кто-нибудь знает почему?

1 ответ

В вашем коде есть несколько возможных проблем:

  1. Наиболее важным является назначение в if условие, которое уже упоминалось в комментариях.
  2. очевидно, еще один - это также упомянутый материал serial.print в ISR.
    ISR должны быть максимально короткими и простыми.

  3. Еще один аппаратный. Если вы нажимаете кнопку, они отскакивают и обычно дают несколько прерываний. так что поищите какой-нибудь прыгающий код или загляните в библиотеку arduino, если там что-то есть. вам, возможно, придется изменить код, потому что обычно сама аппаратная логика обрабатывается прерываниями, но фактическое тестирование состояний кнопок должно принадлежать основному коду.

  4. продвинутые вещи - если вы в настоящее время читаете учебные пособия и учите себя - игнорируйте это, но, возможно, имейте в виду, для реальных проектов
    Другой проблемой является дизайн программы: ваш процессор теперь не может делать ничего, кроме переключения светодиодов, потому что его основной поток программы ждет.
    Обычно вы хотели бы использовать аппаратный таймер для такого рода задач. Либо используйте его в качестве временной базы, чтобы сигналы передавали интервалы на главную через переменную флагов. или напрямую используйте функцию ШИМ для прямого подключения светодиода через один из выводов сравнения выхода (OC[012][AB]).

Другие вопросы по тегам