Reálné hodiny s PIC18f97J60 (bez použití RTC) jdou nepřesně

Ahoj, delam s pic 18F97J60 a potreboval bych udelat realne hodiny. K procesoru (T1OSI a T1OSO) mam pripojen krystal 32.768 kHz. Na displeji zobrazuji cas. Po naprogramovani se mi nedari odladit nejak rozumne presnost tech hodin (chyba 1 minuta denne). Asi delam neco spatne.

Zhruba jak mam program

nastaveni
OSCCON = 0x01;
T1CON = 0b00110101;
INTCON = 0xC0;
PIR1bits.TMR1IF = 0;
PIEbits.TMR1IE=1; //povoleni preruseni od casovace
INTCONbits.GIE=1;

void InterruptHandlerLow (){
if (PIR1bits.TMR1IF) //nastane preteceni
{
PIR1bits.TMR1IF=0x00;
k++;
TMR1H=2; //presne doladeni
TMR1L=213; //
}

	if (k==12)               //jednou za 12 je zhruba 1 sekunda
	{   
	   k=0;
       		   datum_cas();        //fce pro vypocet a zobrazeni casu
                    } 

jde mi proste o to, ze se mi nedari nastavit ta presnost, i kdyz by to s timto krystalem nemel byt problem. Mam asi spatne nastavene ty registry.
Ma s tim nekdo prosim zkusenost.
Diky

:arrow_right: administrator: přejmenováno z "realny cas s pic 18f97j60"

Proč nepoužiješ raději nějaký extérní RTC u kterého bude určitě větší přesnost.

protoze tu desku mam uz osazenou :slight_smile:, nemam jinou moznost

Bude tedy asi potřeba u krystalu použít ladící kondenzátor a pohrát si.

tak než doladovat krystal 32,768kHz tak tam raději přidej oscilátor budeš to mít o 100,- držší ale nemusíš řešit stabilitu ty normální hodinové xtaly při dotažení kondem docela běhaj s teplotou ! a nebo rovnou použi interní osc. ta stabilita kmitočtu bude obdobná!

Mě se něco podobného stalo, když jsem zkoušel programovat v uBasicu.

sub procedure Interrupt
counter = counter + 1
TMR0 = 6
INTCON = $20
end sub

main:
CMCON = 7
OPTION_REG = %00000011
TMR0 = 6
tj. předdělička 1:16 což při krystalu 4MHz a nastaveném TMR0 = 6(256-6 = 250) by mělo nastat přerušení za 4ms(1us x16 x 250).

if counter = 250 then
sec = sec + 1
(4ms x 250 = 1s)
Problém byl že to za 24h mělo chybu několik minut, tak jsem se pořádně podíval na to, jak ten uBasic převede program na assembler:

(interrupt)
záloha registrů W,STATUS,PCLATH
movwf save_W
swapf STATUS,W
clrf STATUS
movwf save_STATUS
movf PCLATH,W
movwf save_PCLATH
clrf PCLATH

incf counter,F

movlw .6
movwf TMR0

movlw .32
movwf INTCON

pak následuje obnovení registrů a návrat z přerušení.

Když jsem tuto část kodu zkusil v MPLABu, tak jsem zjistil, že změna registru counter nastane ne za 4ms, ale až za 4,016ms(tj + 16cyklů).
4,016 x 250 = 1,004s tj. 0,004 x 3600(1h) = 14,4s!! což za 24h je chyba cca 6minut.
Takže jsem upravil TMR0 = 7(249) 1x 16 x 249 = 3984us + 16 = 4000us.
Po této úpravě se chyba zmenšila na cca 3s za 24h což odpovídá přesnosti použitého krystalu.

V přerušení od timeru nenastavuj jeho hodnotu napevno, ale to číslo tam přičítej, reakce na přerušení totiž obvykle trvá určitou (proměnnou) dobu (řekl bych že i u piců to tak je) a tím pevným nastravením tam vnášíš nepřesnost právě díky tomu zpoždění. Kdežto když hodnotu přičteš, tak se čítač změní vždy stejně a je jedno, jak dlouho reakce trvala.

Hm, nějak jsem nepochopil co kam přičist. Mohl bys mi napsat jak to má vypadat? Díky

MístoTMR1H=2; //presne doladeni TMR1L=213; // zkusTMR1H += 2; //presne doladeni TMR1L += 213; //

Ovšem lepší by bylo nechat točit timer celej a ten dopočet dělat jen 1x (třeba když přičítáš vteřinu).
Když ti např vyjde počet přetečení 5.3, tak ho nechat otočit 5 x dokola a nakonec ho přednastavit na (1-0.3)*TOP.

Tak už se mi to povedlo, chyba byla trochu někde jinde. Proto mě zaráželo, že ten výpočet počtů přetečení se tolik liší.
Teď to chodí s přesnotí 1,5 s denně, což je vzhledem k použitému krystalovému oscilátoru slušné.

Petře, proč si myslíš, že přesnost externího RTC obvodu bude vyšší (při použití steného typu krystalu)?

Vlasťa

To nevím, já jsem o použití stejného typu krystalu nic nepsal.

Já jsem to spíš pochopil tak, že přesnost softwarového řešení RTC bude menší (pokud samozřejmě není naprogramováno 100% správně)…jinak mnoho procesorů má již hardwarové RTC integrované v sobě, bohužel mezi 8-bit jich je zatím hodně málo a těžko říct jestli se to v blízké době výrazně změní…i proto je výhodnější zaměřit se na PIC24F, ten přináší nejenom vyšší výkon ale i mnohem větší počet periferií za stejnou cenu…