Вт сен 05, 2017 07:01:30
// Прерывание от TMR1
if (TMR1IE && TMR1IF) {
TMR1H |= 0x80u;
TMR1IF = 0;
if (flag.timeset) unixtime++;
}
Вт сен 05, 2017 07:37:59
Вт сен 05, 2017 07:58:38
// Прерывание от TMR1
if (TMR1IE && TMR1IF) {
if (TMR1H & 0x7F) {
flag.lostsec = 1;
}
TMR1H |= 0x80u;
TMR1IF = 0;
if (flag.timeset) unixtime++;
}
if (POWER_LOST) { // если лог.1, то питания нет
// ложимся спать
clock_mode = sleep_mode;
TMR2IE = 0; // выключаем динамическую индикацию
RTCCIE = 0;
INT1IE = 1; // разрешаем прерывание по появлению питания
DIVIDER = 0;
COMMA = 0;
START_CONV = 0;
LATA = 0x48; // выключаем аноды
LATB = 0x00; // выключаем катоды
// OSCCON = 0x00; // тактовая 2МГц.
// спим
do {
SLEEP();
NOP();
} while (POWER_LOST);
// выход из спячки:
OSCCON = _OSCCON_IRCF0_MASK | _OSCCON_IRCF1_MASK | _OSCCON_IRCF2_MASK; // 8MHz
clock_mode = show_time;
TMR2IE = 1;
RTCCIE = 1;
INT1IE = 0;
INT1IF = 0;
}
Вт сен 05, 2017 07:59:11
Вт сен 05, 2017 08:09:46
// тут сбрасываем секунды у RTCC
RTCCFGbits.RTCPTR1 = 0;
RTCCFGbits.RTCPTR0 = 0;
RTCVALL = 0;
RTCCFGbits.RTCWREN = 0;
flag.holduntilreleased = 0;
flag.update = 1;
// делаем захват значений
GIE = 0;
timetorunh = unixtime;
timetorunl = TMR1H & 0x7Fu;
unixtime = 0;
TMR1L = 0;
TMR1H = 0x80;
flag.timeset = 1;
GIE = 1;
if (timetorunh & 0xffff0000) { // измеренный интервал должен быть почти сутки как минимум 65536сек (18ч))
if (timetorunh & 0xFF000000u) {
correction = timetorunh % 60;
if (correction > 30) {
correction = 60 - correction;
correctionsign = plus;
} else correctionsign = minus;
} else {
timetorunh = (timetorunh << 7) | timetorunl;
correction = timetorunh % (60 << 7);
if (correction > (30 << 7)) {
correction = (60 << 7) - correction;
correctionsign = plus;
} else correctionsign = minus;
}
timetorun_saved = timetorunh;
result = correction * 2 * 491520ul / timetorunh;
if (result & 1) result++;
result >>= 1;
result_saved = result;
Вт сен 05, 2017 08:25:40
Вт сен 05, 2017 08:40:40
bit 7-0 CAL<7:0>: RTC Drift Calibration bits
01111111 = Maximum positive adjustment; adds 508 RTC clock pulses every minute
...
00000001 = Minimum positive adjustment; adds four RTC clock pulses every minute
00000000 = No adjustment
11111111 = Minimum negative adjustment; subtracts four RTC clock pulses every minute
...
10000000 = Maximum negative adjustment; subtracts 512 RTC clock pulses every minute
Вт сен 05, 2017 09:08:41
Может уже установлено какое-нибудь значение корректировки RTC ?uldemir писал(а):Вопрос как поймать за руку разбег двух часов идущих от одного и того же генератора.
Вт сен 05, 2017 13:34:39
Analysis:
I added some debug code to the ISR and used a logic analyser to try to find out what was going on. The results proved quite interesting.
I noticed that when TMR1H was preset to 0xc0 the TMR1L register would randomly MISS a count even though the 32 KHz oscillator was still running.
I am using a 16F7x7 device and the datasheet gives various warnings about reading and writing the timer1 registers when enabled and the characteristic behaviour when first enabled. There was no mention of missing counts while being used as the basis for a RTC.
More debug code revealed that if TMR1H is preset when the 32 kHz source oscillator output is high TMR1L counts correctly and accuracy is consistent. If TMR1H is preset when the oscillator output is low TMR1L misses a count and the RTC looses time.
Ср сен 06, 2017 17:14:51
void ASMISR_HI(void) @ 0x0008 {
#asm
// Pure assembly ISR here
BSF TMR1H, 7
BCF PIR1, 0
MOVLW 1
ADDWF _unixtime, F
BTFSC 0xFD8, 0
ADDWF _unixtime+1, F
BTFSC 0xFD8, 0
ADDWF _unixtime+2, F
BTFSC 0xFD8, 0
ADDWF _unixtime+3, F
RETFIE F ; return from interrupt
#endasm
}
Пт сен 08, 2017 13:21:51
BTFSC TMR1IE
BTFSS TMR1IF
#include "xc.inc"
GLOBAL _unixtime
; This is the high priority interrupt handler. It is placed at address 8.
PSECT intcode,class=CODE,reloc=2
GOTO HI_ISR_ROUT
PSECT isr_routine,class=CODE,reloc=2
HI_ISR_ROUT:
BTFSC TMR1IE, 0
BTFSS TMR1IF, 0
BRA INTEXIT
BSF TMR1H, 7, 0
BCF TMR1IF, 0
MOVLW 1
MOVLB high(_unixtime)
ADDWF _unixtime+0, F
MOVLW 0
ADDWFC _unixtime+1, F
ADDWFC _unixtime+2, F
ADDWFC _unixtime+3, F
INTEXIT:
RETFIE F
Пт сен 08, 2017 13:41:40
Пт сен 08, 2017 16:27:55
#define BANKMASK(addr) ((addr) and 0FFh)
#define TMR1IE BANKMASK(PIE1), 0