Guten Morgen,
Bin schon seit Tagen dabei, eine RTC mit der internen Hardware vom xMega
zu realisieren.
Benutzen tue ich ein XPLAINED Board mit einem LCD.
Der xMega besitzt auch eine externe Batterie. Nun Soll es damit wohl
möglich sein, die Uhrzeit zwischen zu speichern. Wie genau funktioniert
das. Wie zähle ich die Zeit weiter, wenn VCC nicht mehr vorhanden ist?
Jan H. schrieb:> Nun Soll es damit wohl> möglich sein, die Uhrzeit zwischen zu speichern.
Was soll es helfen die Zeit zu speichern? Und wo? Im EEPROM?
Jan H. schrieb:> Wie zähle ich die Zeit weiter
Du zählst nicht die Zeit weiter sondern die Uhr deines XMega.
Nimm dir doch das Beispielprojekt dazu heran... da ist doch alles
realisiert. Jedenfalls bei dem Xplained ohne LCD ist es verwendet. Wenn
die extra mit Batterie ausliefern, dann wird es bei deinem Board wohl im
Beispielprojekt ebenfalls verwendet werden.
Ich steige durch das Datenblatt bsw. durch den Abschnitt RTC32 nicht
durch.
Das heißt im Endeffekt, die RTC32 muss ein Register haben, was während
VCC aus ist, weiter zählt? Ist es eins von den "Cnt" Registern?
Google mal nach AVR Appnote 1321 da ist ein Bisschen was beschrieben.
Ich habe vorige Woche mich genau durch diesen Kram gefräst..
Du brauchst die VBAT Initialisierungsgeschicht aus der Appnote:
1
* Depending on the VBAT system check appropriate actions need to
2
* be taken.
3
* In this example we re-initialize the VBAT system in all
..und ja, ich habe auch an mir gezweifelt, die Manuals sind nicht
übermäßig didaktisch geschrieben.. aber bei mir funzt das indessen
(auf anderer Hardware).
Gruß,
Holm
Danke.
Wie funktioniert das?
Ist das der Zählstand der in den Register von RTC32.CNT0 - 3 ist?
Oder muss ich in der ISR Variablen deklarieren und die werden dann
weiter gezählt?
Die RTC32 ist ein 32Bit counter der mit Batteriepower weiterlaufen kann,
bei Sekundentakt läuft der nach 168 Jahren (?) über, bis dahin mußt Du
Dir um die Zeit keine Sorgen machen.
Umrechnen der Sekunden nach Zeit mittels mktime() und gmtime() (oder
localtime etc..). Interrupts sind nicht unbedingt notwendig.
Gruß,
Holm
Hallo Holm,
Das macht einiges Verständlicher. Ich bin mir immer noch nicht ganz
sicher, wo ich die Sekunden nun auslesen kann. Ist ziemlich doof
beschrieben.
Sind es wirklich die jeweils 8 x 4 Bit breiten CNT Register?
hole Dir doch mal die Appnote und das dazugehörige Zip Archiv, die
Funktionen sind darin dokumentiert und das Ganze darfst Du ja auch
benutzen.
Suche nach AVR1321 z.B. bei Atmel auf der Webseite unter den Dokuementen
zum AtXmega.
Das was Du suchst steht in rtc32_driver.c
1
/*! \brief This function returns the current RTC count value.
2
*
3
* This function synchronizes the RTC32 module's CNT value to the system
4
* clock domain, then returns its value.
5
*
6
* \return The current RTC count value.
7
*/
8
uint32_t RTC32_GetCount( void )
9
{
10
/* Synchronize the RTC module's CNT value to the system clock domain. */
Ich habe den Zähler jetzt Initalisiert, laufen tut er aber viel zu
schnell.
Normalerweise sollte das CNT Register ja jede Sekunde um +1 erhöht
werden oder sehe ich das falsch?
Es wird aber viel zu schnell gezählt.
Hier meine Init ->
1
voidRTC32_Init(void)
2
{
3
/* Apply a reset of the VBAT */
4
VBAT.CTRL|=VBAT_ACCEN_bm;
5
6
/* Set access enable bit */
7
VBAT.CTRL=VBAT_RESET_bm;
8
9
/* Enable 32.768kHz crystal oscillator */
10
VBAT.CTRL|=VBAT_XOSCEN_bm|VBAT_XOSCSEL_bm;
11
12
/* Wait until oscillator is stable */
13
while(!(VBAT.STATUS&VBAT_XOSCRDY_bm));
14
15
/* Enable low power mode for external oscillator */
16
OSC.XOSCCTRL=OSC_X32KLPM_bm;
17
18
/* Reset RTC32 module */
19
RTC32.CTRL=0;
20
21
/* Wait until sync done */
22
while(RTC32_SyncBusy());
23
24
/* Set PER to 1024. CLK source of the RTC32 is 1024 ticks / second = 1 Hz */
Danke für deine Unterstützung.
Leider funktioniert das alles nicht so wirklich.
Habe jetzt die Init von der Atmel Note genommen...
Und von deinem letzten Post die VBAT Init. Diese führe ich direkt nach
der Init von der RTC32 aus.
Wenn alles Konfiguriert ist, lese ich das CNT Register aus. Leider steht
dort jedes mal "0".
Jan H. schrieb:> Danke für deine Unterstützung.> Leider funktioniert das alles nicht so wirklich.> Habe jetzt die Init von der Atmel Note genommen...
Was denn nun, vorher hattest Du den Zustand "viel zu schnell" was daran
lag, das Du bei der Intialisierung nicht den 1 Sekunden Takt sondern den
1Khz Takt ausgewählt hast.
1
VBAT.CTRL |= VBAT_XOSCEN_bm | VBAT_XOSCSEL_bm;
für 1Hz mußt Du aber
1
VBAT.CTRL |= VBAT_XOSCEN_bm;
benutzen.
..und nun zählt das Ding gar nicht mehr?
Du mußt Dir klar darüber werden wann Du die Uhr initialisieren willst,
das sollte tunlichst nicht bei jedem Systemstart sondern nur bei einem
Reset passieren ansonsten haut es Dir die Zeit jedes Mal durcheinander.
> Und von deinem letzten Post die VBAT Init. Diese führe ich direkt nach> der Init von der RTC32 aus.
Im Code der Application Note ist das so, das vbat_init() vor
RTC32_Initialize() ausgeführt wird wenn ein Reset vorliegt, der 32Khz
Oszillator mit Teiler muß erst einmal eingeschaltet werden.
Die Kontrolle über den Oszillator hat der vbat Modul.
Da ich keinen PowerOn Reset bei meiner Hardware hin bekomme ohne 3
Stecker abzuziehen habe ich im Code einmalig vbat_init() beim startup
gerufen und das so programmiert. Damit lief der Zähler dann los. Danach
habe ichs wieder auskommentiert und wieder neu programmiert.
Gruß,
Holm
Sobald ich die Versorgungsspannung weg nehme, Resetet er den Zähler
(CNT) und beim Starten fängt er wieder von "0" an. Ob ich es
auskommentiere oder nicht.
Kannst du mir mal deine Main zeigen?
Jan H. schrieb:> Sobald ich die Versorgungsspannung weg nehme, Resetet er den Zähler> (CNT) und beim Starten fängt er wieder von "0" an. Ob ich es> auskommentiere oder nicht.>> Kannst du mir mal deine Main zeigen?
...eigentlich nicht, ich werde dafür bezahlt das für Jemanden zu
entwickeln, aber der Ausschnitt tuts vielleicht..das ist sowieso nur
der Appnote entsprechend:
1
int main(void)
2
{
3
4
uint8_t vbat_status;
5
static uint16_t count; // Zaehler - zaehlt alle 10ms )
Offensichtlich ist bei dir der Status nicht VBAT_STATUS_OK.
Warum nimmst Du nicht mal den originalen und änderst ihn erst ab wenn er
funktioniert hat? Hast Du die Brownout Detecor enable fuse gesetzt?
Was ist mit dieser Funktion?
Holm,
besten dank! Ich muss jetzt noch mal genau nach schauen an was es
gelegen hat. Die Funktion vbat_system_check() hat aufjedenfall den
Erfolg gebracht.
Besten dank!
Na also, geht doch.
Viel weiter bin ich auch noch nicht, aber die Zeit lät sich stellen mit
mktime() und zum auslesen nehme ich gmtime()...2038 läuft allerdings
dann der 23 Bit Timer über..
Ich bin dabei eine Software zu portieren die ich mal für den
AtXmega128A3 geschrieben hatte und der hatte eine extern (PCFxxxx) Uhr
on Board die nun wegrationalisiert wurde.
Ich habe noch genug an der Baustelle zu tun..die ADUs machen auch nicht
ganz das was ich will..
Gruß,
Holm
..ist doch ausgeschaltet in vbat_init() :
....
//RTC32_SetCompareIntLevel(RTC32_COMPINTLVL_LO_gc);
RTC32_SetCompareIntLevel(RTC32_COMPINTLVL_OFF_gc);
...
Ich brauchte keinen Interrupt, wollte nur zwecks Datenspeicherung auf SD
Karte den aktuellen Timestamp abrufen können.
Den müßtest Du dort also wieder aktivieren, logischerweise reagiert die
CPU auf den Interrupt aber nur im Sleepmode oder wenn sie wach ist,
nicht wenn sie keinen Saft hat.
Gruß,
Holm
Ja ist klar, habe ich schon gesehen.
Habe Versucht den Overflow Interrupt zu nehmen, bzw. einfach wie von dir
gepostet (nicht CompareMatch) sondern eben Overflow.
Leider passiert da nichts.
Wie machst du das mit den Sekunden? Rufst du ständig das CNT Register ab
und stellst den Wert da oder rufst du ihn einmalig beim App Start ab und
lässt es dann via. Interrupt weiter zählen? Bzw. Wie würdest du das
machen?
..der Overflow Interrupt löst bei Sekundentakt doch erst alle 168 Jahre
aus (oder so..) Du mußt also noch ein Bisschen warten.
..es sei denn Du betriebst die Uhr wieder "zu schnell".
Ich brauche keine Echtzeit im Programm, es gibt da aber einen
durchlaufenden 100ms Interrupt nach dem ich mich richte.
Beim Abspeichern von Datensätzen wird simpel der aktuelle Zeitstempel
aus der RTC gelesen und dann verwendet.
Gruß,
Holm