ein paar Dinge zum Epson RTC72421

rtc

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