8177| 2
|
[讨论] 关于定时器0溢出中断的疑问 |
本帖最后由 Youyou 于 2014-3-27 13:20 编辑 #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) #define FRACT_MAX (1000 >> 3) volatile unsigned long timer0_overflow_count = 0; volatile unsigned long timer0_millis = 0; static unsigned char timer0_fract = 0; ISR(TIMER0_OVF_vect) { // copy these to local variables so they can be stored in registers // (volatile variables must be read from memory on every access) unsigned long m = timer0_millis; unsigned char f = timer0_fract; m += MILLIS_INC; f += FRACT_INC; if (f >= FRACT_MAX) { f -= FRACT_MAX; m += 1; } timer0_fract = f; timer0_millis = m; timer0_overflow_count++; } unsigned long micros() { unsigned long m; uint8_t oldSREG = SREG, t; cli(); m = timer0_overflow_count; #if defined(TCNT0) t = TCNT0; #elif defined(TCNT0L) t = TCNT0L; #else #error TIMER 0 not defined #endif #ifdef TIFR0 if ((TIFR0 & _BV(TOV0)) && (t < 255)) m++; #else if ((TIFR & _BV(TOV0)) && (t < 255)) m++; #endif SREG = oldSREG; return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); } 在Arduino底层库中有这样一些代码,看到micros()函数,我就想到了一个问题:单片机开了定时器0的溢出中断,定义了中断函数,以上代码就是的。如果在快要计数溢出时,比如250,由于需要读取micros,会执行cli()函数,把总中断关闭。过了一会读取完毕后,可能这时定时器已经溢出后重新开始了,比如计数到20。那么退出micros()会执行sei()函数,把中断打开,此时刚才的中断函数仍会执行吗?还是会忽略上一次未执行的中断直接等待下一次的中断?求高手指点江山啊 |
There are basically two types of interrupts. The first type is triggered by an event that sets the Interrupt Flag. For these interrupts, the Program Counter is vectored to the actual Interrupt Vec- tor in order to execute the interrupt handling routine, and hardware clears the corresponding Interrupt Flag. Interrupt Flags can also be cleared by writing a logic one to the flag bit position(s) to be cleared. If an interrupt condition occurs while the corresponding interrupt enable bit is cleared, the Interrupt Flag will be set and remembered until the interrupt is enabled, or the flag is cleared by software. Similarly, if one or more interrupt conditions occur while the Global Interrupt Enable bit is cleared, the corresponding Interrupt Flag(s) will be set and remembered until the Global Interrupt Enable bit is set, and will then be executed by order of priority. 引自Mega2560 datasheet 19页 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed