EEPROM avr

Gast #404264
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;
}
Gast #404266
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;
}
Gast #404267
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.
Gast #404270
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]
}
Gast #404272
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...
Gast #404274
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.
Gast #404276
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?
Gast #404281
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;
}
Gast #404282
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 ...
Gast #404283
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?
Gast #404284
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]
Gast #404285
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren