Hy Leute, ich hab bisher nur einige PIC´s Programmiert (nicht wirklich tief, nur ein bisschen "gespielt" und darf nun in meienr Firma einen Tiny24 programm eines ehemaligen Mitarbeiter umstricken. Dementsprechend habe ich hier und da auch meine Probleme mit den Programmierunterschieden. Ich habe nun das Problem, das ich eine Variable mit 16Bit habe (uint16_t) die ich im EEPROM abspeichern muss. Wenn ich das nun richtig gesehen habe, hat das EEPROM eine Wortbreite von nur 8Bit (ist ja auch logisch bei einem 8biter). Ich will nun die oberen 8Bit der Variablen z.B. in die EEPROM Adresse 0x01 schreiben und die unteren 8Bit in die EEPROM Adresse 0x02. Ich habe mir auch schon aus dem Datenblatt des Tiny24 die EEPROM schreibe/lese Routine rausgezogen und implementiert, ich habe nun aber das Problem, das ich nicht weis wie ich es im AVR-Studio umsetze das ich wie erwähnt auf die oberen bzw. unteren Bits zugreifen kann. Kann mir jemand nen Tip geben wie ich das umsetzen kann. P.S.: Beim PIC bin ich leider auch noch nicht in die Verlegenheit gekommen, dies umzusetzen, von daher weis ich leider nicht wie ich ansetzen soll.
EDIT: Sorry, habe vergessen zu erwähnen, dass ich in C Programmiere. :-)
ob tino oder sonstwas .. ein 16 bit in 2 8bit zerlegen is überall gleich
1 | eepromwert_1 = (unsigned char) sechszenbitwert ; |
2 | eepromwert_2 = (unsigned char) (sechszenbitwert>>8) ; |
oder auch
1 | union
|
2 | {
|
3 | unsigned int sechszenbitwert |
4 | struct
|
5 | {
|
6 | unsigned int eepromwert1; |
7 | unsigned int eepromwert2; |
8 | };
|
9 | }eep_16; |
Hi Jens, es gibt in der avr-libc schon Funktionen, die das für dich erledigen! Binde im AVR Studio den header #include <avr\eeprom.h> ein. Dann verwende die Funktion "eeprom_write_byte (uint8_t *addr,uint8_t value)" oder "eeprom_write_word (uint16_t *addr,uint16_t value)". Zu beachten ist aber: Es dürfen beim EEPROM schreiben keine Interrupts auftreten! Also evtl. global Interrupt Flag löschen!
Hey, danke für die schnelle Antworten, ich werde es gleich mal versuchen. Kann ich über diese Art auch wieder die 16Bit Daten aus dem EEPROM lesen? Das mit den Interrupts weis ich und stellt auch kein Problem dar. Das Schreiben auf ads EEPROM ist nur eine Art Kalibrierfunktion, die nur unter bestimmten Umständen aufgerufen wird, dann sind die Interrupts sowiso aus. Und das lesen passiert bei einem Neustart, bevor die Interrupts aktiviert werden.
Beim Lesen müssen die Interrupts nicht gesperrt sein. Lesen kannst du mit
1 | uint16_t eeprom_read_word (const uint16_t *addr) |
Btw. das mit dem Interrupt macht man so:
1 | unsigned char Sreg_Temp; |
2 | |
3 | Sreg_Temp=SREG; |
4 | cli(); //Sperrt global ALLE Interrupts |
5 | eeprom_write_word(0, 70000); Schreibt an die Adresse 0 die 70000 |
6 | SREG=Sreg_Temp; //SREG wieder restauriert, eventulle Interrupts wieder aktiv |
> Beim Lesen müssen die Interrupts nicht gesperrt sein.
Äh, glaub ich zumindest, müsste aber selber nochmal nachlesen...
naja nich unbedingt ... hatte selbst schon den effekt wenn beim lesen die ISR zuschlägt .. das dort mal was schief gehen kann wenn man große datenmengen liest witzig wirds dann wenn man liest die ISR kommt und dort soll nochmal was gelesen werden das führt dann zu sehr kuriosen fehlern die schwer zu finden sind
Das Sperren der Interrupts an der kritischen Stelle erledigt C schon von selbst. Es ist nicht nötig, das von Hand zu machen.
Hy, danke nochmal @ all für die schnelle und Fachmänische Hilfe. Ich hab den schreib/lese Zugriff nun über die eeprom_write_word und eeprom_read_word realisiert. Zudem habe ich jeweils vor dem lesen bzw. schreiben die I´s gesperrt und dann natürlich wieder frei gegeben.
> Das Sperren der Interrupts an der kritischen Stelle erledigt C schon von > selbst. Es ist nicht nötig, das von Hand zu machen. Das ist so nicht richtig! Warum sollte C sich um die Interrupts kümmern? Die Sprache "C" kennt ja keine Interrupts und ist prozessorunabhängig.
Aus der eeprom.h: \note As these functions modify IO registers, they are known to be non-reentrant. If any of these functions are used from both, standard and interrupt context, the applications must ensure proper protection (e.g. by disabling interrupts before accessing them).
> Warum sollte C sich um die Interrupts kümmern?
Dann schau mal nach <avr/eeprom.h>. Du wirst einen cli finden.
(Natürlich ist die C-Laufzeitbibliothek und nicht der C-Standard
gemeint. Ich denke, das versteht sich aus dem Zusammenhang von selbst
-- es ging ja um eeprom_write_word() -- und bedarf keiner Erwähnung.)
Tobi schrieb: > As these functions modify IO registers, they are known to be > non-reentrant. Das ist nochmal eine andere Baustelle. Unabhängig davon müssen Interrupts auch bei Nicht-reentrant-Zugriff gesperrt werden, und eben darum kümmert sich das C Runtime selber. Dass es darüber hinaus noch Umstände geben kann, in denen Zugriffe gegenseitig verriegelt sein müssen (und wo das Sperren von Interrupts die Lösung sein kann, aber nicht muss), versteht sich von selber; davon war aber nicht die Rede.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.