mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Tiny24 und 16Bit Zahl in EEProm speichern


Autor: Jens G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jens G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
EDIT:

Sorry, habe vergessen zu erwähnen, dass ich in C Programmiere. :-)

Autor: blubb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ob tino oder sonstwas .. ein 16 bit in 2 8bit zerlegen is überall gleich

eepromwert_1 = (unsigned char) sechszenbitwert ;
eepromwert_2 = (unsigned char) (sechszenbitwert>>8) ;


oder auch
union 
{
  unsigned int sechszenbitwert
  struct
   {
     unsigned int eepromwert1;
     unsigned int eepromwert2;
   };
}eep_16;

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Jens G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Lesen müssen die Interrupts nicht gesperrt sein.

Lesen kannst du mit
uint16_t eeprom_read_word (const uint16_t *addr)

Btw. das mit dem Interrupt macht man so:
unsigned char Sreg_Temp;

Sreg_Temp=SREG;
cli(); //Sperrt global ALLE Interrupts
eeprom_write_word(0, 70000); Schreibt an die Adresse 0 die 70000
SREG=Sreg_Temp; //SREG wieder restauriert, eventulle Interrupts wieder aktiv


Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Beim Lesen müssen die Interrupts nicht gesperrt sein.

Äh, glaub ich zumindest, müsste aber selber nochmal nachlesen...

Autor: blubb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann auch beim lesen leiber die I's sperren!

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Sperren der Interrupts an der kritischen Stelle erledigt C schon von 
selbst.  Es ist nicht nötig, das von Hand zu machen.

Autor: Jens G. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.