mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik EEPROM avr


Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche eine adresse im eeprom zu beschreiben und sie wieder
auszulesen.Doch irgendwo hackt das Programm. Sind die Funktionen für
das lesen und schreiben im eeprom eines atmega 16 richtig.Danke


char eeprom_daten_auslesen()
{
int adress;
adress=400;
while(EECR & (1<<EEWE))
{
}
EEAR=adress;
EECR=EECR | (1<<EERE);
return EEDR;
}

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf Seite 19 des Datenblattes ist der Ablauf (inklusive Codebeispiel)
gegeben.

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, das liegt vormir,aber ich wollte das ein wenig umändern.
aber er gibt mir nur die zahl 255 aus statt meiner gewählten 45.
hier der ganze code:

#include <avr/io.h>
#include <avr/delay.h>
#define FOSC 3686400                   //Quarz mit 3,686400 MHz

char eeprom_daten[1];
                              ;

void eeprom_daten_speichern()
{
int adress;
adress=400;
char adc_data[1];
adc_data[0]=45;
while(EECR & (1<<EEWE))
{
}
EEAR=adress;
EEDR=adc_data[0];
EECR=EECR | (1<<EEMWE);
EECR=EECR | (1<<EEWE);
}



void eeprom_daten_auslesen()
{
int adress;
adress=400;
while(EECR & (1<<EEWE))
{
}
EEAR=adress;
EECR=EECR | (1<<EERE);
eeprom_daten[0]=EEDR;
}




void uart_ausgabe()
{
while(!(UCSRA & (1<<UDRE)))
{
}
UDR=eeprom_daten[0];
}

int main(void)
{
int i;
UCSRB=UCSRB | (1<<TXEN);
UCSRC=UCSRC | (3<<UCSZ0);
UBRRH=0;
UBRRL=95;
while(1)
{
eeprom_daten_speichern();
eeprom_daten_auslesen();
uart_ausgabe();
_delay_ms(100);
}
return 0;
}

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich mach' das mit WinAVR so:

#include <avr/eeprom.h>

eeprom_busy_wait(); 
eeprom_read_block(&Temp_Variable,(uint16_t*)0,sizeof(int));
 if (!(Variable == Temp_Variable))
  {
  eeprom_busy_wait();
  eeprom_write_block(&Variable,(uint16_t*)0,sizeof(int));
  }

wobei 'Variable' die zu Schreibende /lesende Variable ist und
'Temp_Variable' eine temporäre um zu überprüfen ob der EEPROM-Inhalt
differiert. Falls der Inhalt gleich ist braucht nicht neu geschrieben
zu werden. In diesem Fall wird ab Startadresse '0' geschrieben
(gelesen). Mit sizeof wird die anzahl Bytes abgefragt, die geschrieben
werden soll (abhängig von der Variablen).

Ist aber in den Examples im WinAVR gut beschrieben.

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Direkt einen Fehler in meinen Code kann niemand finden?

Vielen Dank trotzdem...

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"ja, das liegt vor mir, aber ich wollte das ein wenig umändern."

Es wäre sicher einfacher, wenn du die Änderungen im Code kommentiert
oder wenigstens markiert hättest ;-)

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
soviel ist nicht verändert worden:

void eeprom_daten_auslesen()
{
int adress;
adress=400;
while(EECR & (1<<EEWE))
{
}
EEAR=adress;
EECR=EECR | (1<<EERE);
eeprom_daten[0]=EEDR;   !!!ich lese hier den Wert im EEDR Register
in ein Feld Namens eeprom.data[0]
}

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
BTW:
_delay_ms(100) geht mit 3,6864 MHz nicht. Maximale Verzögerung ist
262,14ms / F_CPU[MHz]

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
leider liegt es daran auch nicht...habe es geändert..
er schafft es irgendwie nicht den wert zu speichern.. bzw. wieder
einzulesen...

wenn ich mir einen wert vorgebe, und ihn direkt ausgebe funktioniert es
...

nur wenn ich einen wert speichern und anschliessend lesen möchte , gibt
er mir einen falschen wert aus...

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst du nicht per AVRStudio ins EEPROM gucken? Dann wüsstest du
wenigsten, dass dein Wert auch geschrieben wurde.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du schon den WINAVR verwendest, wieso benutzt Du dann nicht, wie
von Sonic angegeben, die entsprechenden Funktionen aus der AVR-libc?
Die sind doch genau dafür da, dass Du Dir um die ganze Warterei und
Registerschreiberei keine Gedanken machen musst!

Deklariere Deine Variable im EEPROM mit

unsigned char EEMEM variable;

oder

unsigned char EEMEM array[LAENGE];

und greife mit

eeprom_daten[0] = eeprom_read_byte(variable);

oder

eeprom_daten[0] = eeprom_read_byte(array[i]);

drauf zu.

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorsicht beim EEPROM-Auslesen mit AVR-Studio 4.12 (SP3)! Bei mir geht
das Auslesen erst nachdem ich das EEPROM 1x beschrieben habe! Ansonsten
bleibt def Puffer bei 0xFF.

Autor: Stefan (ein anderer) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Sonic

Das ist logisch. 0xFF heisst das EEPROM ist an dieser Stelle
unbeschrieben, leer, gelöscht.

@ Greenhorn

Die Zeile mit !!! ist die einzige Änderung oder hast du auch was in
eeprom_daten_speichern(); geändert? Muss man zwischen Schreiben und
Lesen eine Wartezeit einhalten?

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan:
klar heißt 0xFF dass das EEPROM leer ist. das ist ja der Fehler. Das
EEPROM ist eben definitiv nicht leer, nur das AVR-Studio zeigt mir leer
an!

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

hat jemand eine Beispiel-Code zum lesen und schreibe des ineternen
Eeproms. Ich wäre ihm sehr dankbar, da ich hier nicht mehr weiter
komme.

Danke

Autor: Stefan (ein anderer) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.atmel.com/dyn/resources/prod_documents/...
Seite 21+22

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
=> Sourcecode von avr-libc Funktionen eeprom_read_byte und
eeprom_write_byte ansehen

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch es doch sonst erst mal von der anderen Seite: Schreib mit dem
AVR-Studio etwas ins EEPROM und schick dir das dann per USART.

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

die informationen aus dem datenblatt wurden schon von mir verwendet,
doch leider speichert das programm nicht bzw. kann die eeprom nicht
auslesen:

#include <avr/io.h>
#include <inttypes.h>
#ifndef F_CPU
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz  */
#endif
#include <avr/delay.h>      /* definiert _delay_ms() ab avr-libc
Version 1.2.0 */


void EEPROM_write(unsigned int adress,unsigned char data)
{
while(EECR & (1<<EEWE))
{
}
EEAR=adress;
EEDR=data;
EECR |=(1<<EEMWE);
EECR |=(1<<EEWE);
}


unsigned char EEPROM_read(unsigned int adress)
{
while(EECR & (1<<EEWE))
{
}
EEAR=adress;
EECR |= (1<<EERE);
return EEDR;
}

int main(void)
{
unsigned char data_receive;
data_receive=0;
unsigned int adress;
adress =233;
unsigned char data;
data=100;
UCSRB=UCSRB | (1<<TXEN);
UCSRC=UCSRC | (3<<UCSZ0);
UBRRH=0;
UBRRL=95;
EEPROM_write(adress,data);
EEPROM_write(adress,data);
_delay_ms(20);
while(1)
{
data_receive=EEPROM_read(adress);
while(!(UCSRA & (1<<UDRE)))
{
}
UDR=data_receive;
_delay_ms(10);
}
return 0;
}

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also die ausgabe per serieller schnittstelle passt schon .. er gibt mir
zahlen aus die ich vorher deklariert habe. doch wenn ich mit einer
variable eine zahl speichere und mit einer anderen variablen versuche
aus dem eeprom zu lesen , zeigt er mit die zahl 255 an ...

Autor: Stefan (ein anderer) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du das vom Compiler Assembler-Listing für diesen Codeamschnitt
zur Hand?

unsigned char EEPROM_read(unsigned int adress)
{
   while(EECR & (1<<EEWE))
   {
   }
   EEAR=adress;
   EECR |= (1<<EERE);
   return EEDR;
}


Kannst du die Funktionen aus der avr-libc nicht testen?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>doch wenn ich mit einer variable eine zahl speichere und mit einer
>anderen variablen versuche aus dem eeprom zu lesen , zeigt er mit >die
zahl 255 an ...

Deswegen schlage ich ja vor, dass du mal etwas ins EEPROM schreibst,
ohne dein Programm zu benutzen.
Dann könnte man feststellen, ob es am Lesen oder am Schreiben ins
EEPROM liegt.


[OT]
Auf der Tastatur gibt es diverse Tasten, die es ermöglichen auch
Großbuchstaben  zu verwenden.
[/OT]

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Assembler-Listing habe ich mir inzwischen selbst erzeugt und
angesehen. Das sieht korrekt aus.

Ich weiss jetzt auch nicht mehr weiter, ausser bekannt funktionierende
Routinen zu checken oder das Beschreiben auch mal mit externen Tools zu
versuchen.

Autor: Greenhorn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

bei mir hat es jetzt funktioniert ... warum genau oder wo der fehler
war kann ich auch nicht sagen ..

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.