Forum: Mikrocontroller und Digitale Elektronik EEPROM avr


von Greenhorn (Gast)


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;
}

von inoffizieller WM-Rahul (Gast)


Lesenswert?

Auf Seite 19 des Datenblattes ist der Ablauf (inklusive Codebeispiel)
gegeben.

von Greenhorn (Gast)


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;
}

von Sonic (Gast)


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.

von Greenhorn (Gast)


Lesenswert?

Direkt einen Fehler in meinen Code kann niemand finden?

Vielen Dank trotzdem...

von Stefan (Gast)


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 ;-)

von Greenhorn (Gast)


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]
}

von johnny.m (Gast)


Lesenswert?

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

von Greenhorn (Gast)


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...

von inoffizieller WM-Rahul (Gast)


Lesenswert?

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

von johnny.m (Gast)


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.

von Sonic (Gast)


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.

von Stefan (ein anderer) (Gast)


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?

von Sonic (Gast)


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!

von Greenhorn (Gast)


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

von Stefan (ein anderer) (Gast)


Lesenswert?

http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
Seite 21+22

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Bytes_lesen.2Fschreiben
=> Sourcecode von avr-libc Funktionen eeprom_read_byte und
eeprom_write_byte ansehen

von inoffizieller WM-Rahul (Gast)


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.

von Greenhorn (Gast)


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;
}

von Greenhorn (Gast)


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 ...

von Stefan (ein anderer) (Gast)


Lesenswert?

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

1
unsigned char EEPROM_read(unsigned int adress)
2
{
3
   while(EECR & (1<<EEWE))
4
   {
5
   }
6
   EEAR=adress;
7
   EECR |= (1<<EERE);
8
   return EEDR;
9
}


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

von inoffizieller WM-Rahul (Gast)


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]

von Stefan (Gast)


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.

von Greenhorn (Gast)


Lesenswert?

hallo,

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

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
Noch kein Account? Hier anmelden.