甚至Arduino milli()或micro()函数都使用中断例程......
为清楚起见,以下代码取自:
Arduino的0022-src.tar.gz Arduino的0022 硬件 Arduino的芯 Arduino的 wiring.c
//预分频器设置为每隔64个时钟周期滴定一次,并且
//每256个tick会调用一个溢出处理程序。
#define MICROSECONDS_PER_TIMER0_OVERFLOW(clockCyclesToMicroseconds(64 * 256))
//每个timer0溢出的整数毫秒数
#define MILLIS_INC(MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
//每个timer0溢出的小数毫秒数。我们向右转
//由三个将这些数字拟合成一个字节。 (对于我们关心的时钟速度
//大约 - 8和16 MHz - 这不会失去精度。)
#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;
SIGNAL(TIMER0_OVF_vect)
{
//将这些复制到局部变量,以便它们可以存储在寄存器中
//(每次访问时必须从内存中读取volatile变量)
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 millis()
{
无符号长m;
uint8_t oldSREG = SREG;
//当我们读取timer0_millis或者我们可能得到一个时,禁用中断
//不一致的值(例如在写入timer0_millis的过程中)
CLI();
m = timer0_millis;
SREG = oldSREG;
返回m;
}
unsigned long micros(){
无符号长m;
uint8_t oldSREG = SREG,t;
CLI();
m = timer0_overflow_count;
#if defined(TCNT0)
t = TCNT0;
#elif定义(TCNT0L)
t = TCNT0L;
#其他
#error TIMER 0未定义
#万一
#ifdef TIFR0
if((TIFR0& _BV(TOV0))&&(t