ein paar Dinge zum Epson RTC72421
Es handelt sich dabei um eine in einen IC vergossene Quartzuhr. Das IC unterstützt
Uhrzeit, Datum und Tag der Woche.
Das Ein- und Auslesen der Daten erfolgt über einen 4Bit breiten Datenbus Stellen(digit)weise,
die einzelnen Digits werden mit 4Bit adressiert. ALE wird auf Vdd gelegt, so der MC kein ALE hat
(ALE brauch man bei AVRs nich, also auf 5V). WR/RD zeigen ihm (wenn low) ob gelesen/geschrieben werden soll und
die beiden chipselects das er drann ist (und wann er was tun soll).
ASM Code für nen ATMega8515 (also ohne CALL, dafür mit ICALL)
Der Code ist aus dem File der Funkuhr rausgerissen, die Ports sind daher etwas
komisch verteilt, können aber für andere Anwendungen problemlos ausgetauscht werden
(so man den Code anpaßt natürlich). Ist nicht alles notwendig so (z.B. die jeweils letzten Blöcke) , aber
da bei der Funkuhr 2 MCs auf die Uhr zugreifen mach ichs halt so.
Sorry wegen dem Mix aus deutsch und english in den Kommentaren, bin zu faul um
daran jetzt noch was zu ändern...
Die Intialisierung ist etwas länger, darum ist sie am ende der Seite zu finden, so ganz unten halt.
Die Portbelegung zu den Beispielen:
; RTC72421
; PA0-PA3 D0-D3 data pins
; PB0-PB3 A0-A3 address pins
; PB4 CS0
; PD0 RD
; PD1 CS1
; PD2 WR
1 Digit lesen (4bit):
rRTCbit:
; 4bit Wert aus dem RTC72421 lesen
; rgi haelt 4bit Adresse
; rgtmp wird 4bit digit halten
; rgtmp2 is fuer temporaere Daten
; lower half portb (address) auf ausgang
LDI rgtmp2, 0xff
OUT DDRB, rgtmp2
; write address
IN rgtmp2, portb ; read portb
CBR rgtmp2, 0x0f ; clear lower 4 bits
OR rgtmp2, rgi ; mask address into read bits
OUT portb, rgtmp2 ; write address to port
; wait, give everything a little time to settle
NOP
NOP
; get the bits
; clear rd
CBI portd, 0
; delay
NOP
; read the bits
IN rgtmp, pina ; read bits
CBR rgtmp, 0xf0 ; clear upper half of read data
; pull rd back up
SBI portd, 0
; lower half port b zurück auf eingang, zuerst die pullups raus
; ist sicher so, kommt auf den beiden Ports nichts in den Weg
; port b
IN rgtmp2, portb ; read portb
CBR rgtmp2, 0x0f ; clear lower 4 bits
OUT portb, rgtmp2 ; write result to portb
LDI rgtmp2, 0xf0
OUT DDRB, rgtmp2
RET
1 Digit schreiben (4bit):
wRTCbit:
; 4bit Wert in den RTC72421 schreiben
; rgi haelt 4bit Adresse
; rgtmp haelt den 4bit Wert zum Schreiben
; rgtmp2 is fuer temporaere Daten
; lower half porta (data) und portb (address) auf ausgang
LDI rgtmp2, 0xff
OUT DDRA, rgtmp2
LDI rgtmp2, 0xff
OUT DDRB, rgtmp2
; write address
IN rgtmp2, portb ; read portb
CBR rgtmp2, 0x0f ; clear lower 4 bits
OR rgtmp2, rgi ; mask address into read bits
OUT portb, rgtmp2 ; write address to port
; wait, give ports time to get used to being output
NOP
NOP
; write data
IN rgtmp2, porta ; read porta
CBR rgtmp2, 0x0f ; clear lower 4 bits
OR rgtmp2, rgtmp ; mask data into read bits
OUT porta, rgtmp2 ; write data to port
; make it swallow the bits
; clear wr
CBI portd, 2
; delay
NOP
NOP
; pull wr back up
SBI portd, 2
; lower half port a und b zurück auf eingang, zuerst die pullups raus
; ist sicher so, kommt auf den beiden Ports nichts in den Weg
; port a
IN rgtmp2, porta ; read porta
CBR rgtmp2, 0x0f ; clear lower 4 bits
OUT porta, rgtmp2 ; write result to porta
LDI rgtmp, 0xf0
OUT DDRA, rgtmp
; port b
IN rgtmp2, portb ; read portb
CBR rgtmp2, 0x0f ; clear lower 4 bits
OUT portb, rgtmp2 ; write result to portb
LDI rgtmp, 0xf0
OUT DDRB, rgtmp
RET
Beispiel: Minuten stellen
Da auch die Sekunden gestellt (auf den Anfang der Minute gesetzt) werden sollen, wird die Uhr zuerst angehalten.
Dann wird der Zähler unterhalb der Sekunden auf 0 gesetzt, um den Anfang der Minute
möglichst genau (die Verzögerung gering halten) zu treffen.
; adjust the minute of the RTC72421
AdjustRTCMinute:
; adjust seconds at beginning of 0 second
; f register, reset to 1
LDI rgi, 0x0f ; address
LDI rgtmp, 0x05 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; f register, stop reseting
LDI rgi, 0x0f ; address
LDI rgtmp, 0x04 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; write x1 seconds
LDI rgi, 0x00 ; address
LDI rgtmp, 0x00 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; write 0x seconds
LDI rgi, 0x01 ; address
LDI rgtmp, 0x00 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; write minute lsd from RAM
LDI ZH,HIGH(mDCFMinL) ; address of mDCFMinL
LDI ZL,LOW(mDCFMinL)
LD rgtmp, Z
LDI rgi, 0x02 ; address of minute lsd in RTC
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; write minute msd from RAM
LDI ZH,HIGH(mDCFMinH) ; address of mDCFMinH
LDI ZL,LOW(mDCFMinH)
LD rgtmp, Z
LDI rgi, 0x03 ; address of minute msd in RTC
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
RET
den RTC intialisieren:
InitRTC:
; initialise the RTC72421
; clear cs0
CBI portb, 4
; set cs1
SBI portd, 1
; set wr
SBI portd, 2
; set rd
SBI portd, 0
; f register, stop counter
LDI rgi, 0x0f ; address
LDI rgtmp, 0x07 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; e register
LDI rgi, 0x0e ; address
LDI rgtmp, 0x07 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; d register
LDI rgi, 0x0d ; address
LDI rgtmp, 0x04 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write x1 seconds
LDI rgi, 0x00 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write 1x seconds
LDI rgi, 0x01 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write x1 minutes
LDI rgi, 0x02 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write 1x minutes
LDI rgi, 0x03 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write x1 hours
LDI rgi, 0x04 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write 2x hours
LDI rgi, 0x05 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write x1 days
LDI rgi, 0x06 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write 1x days
LDI rgi, 0x07 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write x1 month
LDI rgi, 0x08 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write 1x month
LDI rgi, 0x09 ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write x1 year
LDI rgi, 0x0a ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write 1x year
LDI rgi, 0x0b ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; INIT: write day 1 of the week, Monday
LDI rgi, 0x0c ; address
LDI rgtmp, 0x01 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
; f register, start counter
LDI rgi, 0x0f ; address
LDI rgtmp, 0x04 ; value
LDI ZH,HIGH(wRTCbit)
LDI ZL,LOW(wRTCbit)
ICALL
RET