Код
volatile signed long int actualTime;
void interrupt isr (void){
//...
if (TMR1IF && TMR1IE){ // TMR1 Handler
TMR1H |= 0x80; //Загрузка таймера для получения периода 1с.
actualTime++;
}
//...
}
void interrupt isr (void){
//...
if (TMR1IF && TMR1IE){ // TMR1 Handler
TMR1H |= 0x80; //Загрузка таймера для получения периода 1с.
actualTime++;
}
//...
}
Выкурил микрочиповскую еррату по этому вопросу, и выяснил, что если загружать регистры таймера в неподходящий момент, то таймер может пропустить один такт. Это понятно. Поскольку у меня в основном коде периодически запрещаются прерывания на относительно долгие промежутки времени, ясно что такие неподходящие моменты имеют место быть. Решил сделать как написано в еррате - прежде чем загружать регистры таймера, дождаться его очередного приращения. Это тоже понятно. Но хоть убей не пойму, ЗАЧЕМ дрыгать клок с внешнего на системный и обратно, зачем выключать/включать таймер:
Код
BTFSC TMR1L,0
GOTO $-1
BTFSS TMR1L,0
GOTO $-1 ;Timer has just incremented, 31 μs before next rising edge to
;complete reload
Update:
BCF T1CON,TMR1CS ;Select system clock for Timer1
BSF TMR1H,7 ;Timer1 high byte 0x80
BCF T1CON,TMR1ON ;Timer1 off
BSF T1CON,TMR1C ;Select external crystal
BSF T1CON,TMR1ON ;Timer1 on
GOTO $-1
BTFSS TMR1L,0
GOTO $-1 ;Timer has just incremented, 31 μs before next rising edge to
;complete reload
Update:
BCF T1CON,TMR1CS ;Select system clock for Timer1
BSF TMR1H,7 ;Timer1 high byte 0x80
BCF T1CON,TMR1ON ;Timer1 off
BSF T1CON,TMR1C ;Select external crystal
BSF T1CON,TMR1ON ;Timer1 on
Разве недостаточно просто делать запись в TMR1 сразу же после инкремента последнего:
Код
void interrupt isr (void){
//...
if (TMR1IF && TMR1IE){ // TMR1 Handler
while (TMR1L == TMR1L){ // Ожидание инкремента TMR1
;
}
TMR1H |= 0x80; //Загрузка таймера для получения периода 1с.
actualTime++;
}
//...
}
//...
if (TMR1IF && TMR1IE){ // TMR1 Handler
while (TMR1L == TMR1L){ // Ожидание инкремента TMR1
;
}
TMR1H |= 0x80; //Загрузка таймера для получения периода 1с.
actualTime++;
}
//...
}
В дизассемблере это выглядит так:
Код
93: while (TMR1L == TMR1L){
223 1283 BCF STATUS, 0x5
224 080E MOVF TMR1L, W
225 060E XORWF TMR1L, W
226 1903 BTFSC STATUS, 0x2
227 2A23 GOTO 0x223
94: ;
95: }
96: TMR1H |= 0x80;
228 178F BSF TMR1H, 0x7
223 1283 BCF STATUS, 0x5
224 080E MOVF TMR1L, W
225 060E XORWF TMR1L, W
226 1903 BTFSC STATUS, 0x2
227 2A23 GOTO 0x223
94: ;
95: }
96: TMR1H |= 0x80;
228 178F BSF TMR1H, 0x7
Или я морочу голову себе и людям и надо сделать точно так как в примере из ерраты?