简体   繁体   English

Arduino Uno Timer1 似乎自行启动

[英]Arduino Uno Timer1 seemingly starts itself

The While(busy);时(忙); loop is instantly skipped.循环立即被跳过。 But the only place where busy can be set to 0 is in the Timer1 ISR.但唯一可以将 busy 设置为 0 的地方是在 Timer1 ISR 中。 But Timer 1 is stopped and only ever starts when in the Pin Change ISR.但是定时器 1 停止并且仅在处于引脚变化 ISR 时才启动。

From the UART output I can tell that Timer 1 ISR happens, while Pin Change ISR never does.从 UART 输出我可以看出 Timer 1 ISR 发生了,而 Pin Change ISR 永远不会发生。 which should not be possible, right?这是不可能的,对吧?

What am I missing?我错过了什么?

In my main function:在我的主要功能中:

...
    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();
...

Timer 1 ISR:定时器 1 中断服务程序:

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

Pin Change ISR:引脚更改 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 output is: Uart输出为:

13

edit编辑

I tried moving the TIMSK1 |= (1 << TOIE1);我尝试移动TIMSK1 |= (1 << TOIE1); to the Pin Change ISR.到引脚更改 ISR。 Now it goes in there at least once like I want it but as soon as I enable the Interrupt it triggers the ISR again and ends.现在它至少像我想要的那样进入那里一次,但是一旦我启用中断,它就会再次触发 ISR 并结束。

As the Arduino core starts all timers by default (because of PWM), there is possibility that interrupt flags are already set and they fires as soon as you enable the corresponding interrupts.由于 Arduino 内核默认启动所有定时器(由于 PWM),有可能中断标志已经设置,并且一旦您启用相应的中断,它们就会触发。 So you have to clear them before reenabling interrupts.因此,您必须在重新启用中断之前清除它们。 But there is a tiny little obstacle: interrupt flags are cleared by writing logic one into corresponding bit.但是有一个小小的障碍:通过将逻辑 1 写入相应位来清除中断标志。 Therefore you have to use something like this TIFR1 = _BV(ICF1) | _BV(OCF1B) | _BV(OCF1A) | _BV(TOV1);因此你必须使用这样的东西TIFR1 = _BV(ICF1) | _BV(OCF1B) | _BV(OCF1A) | _BV(TOV1); TIFR1 = _BV(ICF1) | _BV(OCF1B) | _BV(OCF1A) | _BV(TOV1); (however as you don't use any other Timer1 interrupt, you can clear TOV1 flag only). (但是由于您不使用任何其他 Timer1 中断,您只能清除 TOV1 标志)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM