首页 > 解决方案 > Arduino Uno Timer1 似乎自行启动

问题描述

期间(忙);循环立即被跳过。但是唯一可以将忙设置为 0 的地方是 Timer1 ISR。但是定时器 1 停止并且仅在引脚更改 ISR 中启动。

从 UART 输出我可以看出 Timer 1 ISR 发生了,而 Pin Change 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;
}

引脚更改 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

编辑

我尝试将其TIMSK1 |= (1 << TOIE1);移至 Pin Change ISR。现在它至少像我想要的那样进入那里一次,但是一旦我启用中断,它就会再次触发 ISR 并结束。

标签: ctimerarduinoarduino-unoisr

解决方案


由于 Arduino 内核默认启动所有定时器(由于 PWM),因此可能已经设置了中断标志,并且一旦您启用相应的中断,它们就会触发。因此,您必须在重新启用中断之前清除它们。但是有一个小障碍:通过将逻辑 1 写入相应的位来清除中断标志。因此你必须使用这样的东西TIFR1 = _BV(ICF1) | _BV(OCF1B) | _BV(OCF1A) | _BV(TOV1);(但是由于你不使用任何其他 Timer1 中断,你只能清除 TOV1 标志)。


推荐阅读