Witam. Próbuję zaimplementować prymitywny zegar czasu rzeczywistego na mikrokontrolerze AT89S52 taktowanym rezonatorem kwarcowym 12 MHz. Do tego celu wykorzystałem licznik T2 i przerwanie od niego pochodzące. Wartość początkową i do przeładowania po przepełnieniu ustawiłem na 3CAFh. Czyli przerwanie będzie występować co 50 ms (65 535 – 15 535 = 50 000, 50 000 * 1 us = 50 ms). Dodatkowo w procedurze obsługi przerwania zmniejszam za każdym razem rejestr roboczy R0 (zaczynając od 10) i gdy R0 = 0 neguje bit CY. W programie głównym zapalam diodę na porcie P1.0 gdy CY = 0 i gaszę gdy CY = 1. Wynikałoby z tego, że dioda będzie mrugać z częstotliwością 1 Hz. Wszystko ładnie, pięknie ale po kilkunastu minutach pracy dioda jakby „wyprzedzała” czas jaki wskazuje mój komputer.
Oto listing programu:
Gdzie i jaki popełniłem błąd w obliczeniach? Liczę na Waszą pomoc.
Oto listing programu:
ORG 0
OKRES EQU 10
LJMP START_PROGRAMU
ORG 002BH
LJMP PRZERWANIE
START_PROGRAMU:
MOV 0CDH, #03CH ;WPISANIE WARTOSCI POCZATKOWEJ DO LICZNIKA T2 (STARSZY BAJT)
MOV 0CCH, #0AFH ;WPISANIE WARTOSCI POCZATKOWEJ DO LICZNIKA T2 (MLODSZY BAJT)
MOV 0CBH, #03CH ;WPISANIE WARTOSCI DO PRZELADOWANIA PO PRZEPELNIENIU LICZNIKA T2 (STRASZY BAJT)
MOV 0CAH, #0AFH ;WPISANIE WARTOSCI DO PRZELADOWANIA PO PRZEPELNIENIU LICZNIKA T2 (MLODSZY BAJT)
SETB 0AFH ;WLACZENIE SYSTEMU PRZERWAN (EA = 1)
SETB 0ADH ;WLACZENIE PRZERWANIA OD LICZNIKA T2 (ET2 = 1)
MOV R0, #OKRES
SETB 0CAH ;START LICZNIKA T2 (TR2 = 1)
START:
JC $
CLR P1.0
JNC $
SETB P1.0
LJMP START
PRZERWANIE:
CLR 0CFH ;WYZEROWANIE FLAGI PRZEPELNIANIA LICZNIKA T2
DJNZ R0, POWROT ;DEKREMENTACJA I SPRAWDZENIE CZY R0 = 0, JEZELI NIE TO SKOK POD 'POWROT'
MOV R0, #OKRES ;WPISANIE DO R0 WARTOSCI 'OKRES'
CPL C ;ZANEGOWANIE BITU CY
POWROT:
RETI
END
Gdzie i jaki popełniłem błąd w obliczeniach? Liczę na Waszą pomoc.