Arduino Uno Timer1, похоже, начинает себя - PullRequest
0 голосов
/ 18 января 2020

Время (занято); l oop мгновенно пропускается. Но единственное место, где занятость может быть установлена ​​на 0, находится в Таймере 1 ISR. Но Таймер 1 останавливается и запускается только при ISR смены контактов.

По выходу UART я могу сказать, что ISR таймера 1 происходит, а ISR смены контактов никогда не происходит. что не должно быть возможным, верно?

Чего мне не хватает?

В моей основной функции:

...
    uint32_t temp = 0;

    busy = 1;
    mode = 1;

    // Timer Interrupt Init
    TCCR1B &= ~((1<<2) | (1<<1) | (1<<0));  // Makeing sure timer is not running
    TIMSK1 |=  (1 << TOIE1);                // Timer 1 overflow interrupt enable
    TCNT1 = 0;                              // Makeing sure Timer is on 0

    // Pin Change Interrupt Init
    PCICR  |= (1<<2);   // Activating PCMSK2
    PCMSK2 |= (1<<6);   // PCMSK2 -> PCINT23.. 16 seem to correspond to physical pins D 0-7

    UartSendstring("1");
    // Scanning (see ISR)
    sei();
    TCCR1B &= ~((1<<2) | (1<<1) | (1<<0));
    while(busy);
    cli();
...

Таймер 1 ISR:

ISR(TIMER1_OVF_vect)
{
    UartSendstring("3");
    busy = 0;
}

Pin Change ISR:

ISR(PCINT2_vect)
{
    UartSendstring("2");
    //todo make first values not empty
    TCCR1B &= ~((1<<2) | (1<<1) | (1<<0));// CS12 - CS10 are set to 0 to stop the timer
    data[addr] |= TCNT1L;
    data[addr] |= (TCNT1H << 8);                // High and low byte are saved to data

    TCNT1 = 0;                      // Timer is reset
    TCCR1B |= ((1<<1) | (1<<0));    // CS12 is set to 1 to restart the timer with prescaler 64 -> tick time = 4us
                                    // Signal period duration is 1s / 38 000 = 26us
                                    // -> at least on timer tick in one signal period
    addr++;                         // Prepares to write to the next address with next edge
}

Выход Uart:

13

edit

Я попытался переместиться TIMSK1 |= (1 << TOIE1); для смены ПИН ISR. Теперь он входит туда хотя бы один раз, как я хочу, но как только я включаю прерывание, он снова запускает ISR и завершается.

1 Ответ

0 голосов
/ 18 января 2020

Поскольку ядро ​​Arduino запускает все таймеры по умолчанию (из-за ШИМ), существует вероятность того, что флаги прерываний уже установлены и они срабатывают, как только вы активируете соответствующие прерывания. Таким образом, вы должны очистить их перед повторным включением прерываний. Но есть небольшое крошечное препятствие: флаги прерывания очищаются путем записи логики c в соответствующий бит. Поэтому вы должны использовать что-то вроде этого TIFR1 = _BV(ICF1) | _BV(OCF1B) | _BV(OCF1A) | _BV(TOV1); (однако, поскольку вы не используете другое прерывание от Таймера1, вы можете очистить только флаг TOV1).

...