Forum: Mikrocontroller und Digitale Elektronik EEPROM schreiben lesen


von gast (Gast)


Lesenswert?

Servus Leute,

Erst mal zu meinem Vorhaben: Und zwar möchte ich ein PWM-Sinus erzeugen. 
Bzw. immer nur die positive Halbwelle abwechseln auf 2 PWM-Ausgängen des 
ATTiny13.
Jetzt hab mich mich ein wenig eingelesen und gelernt, dass es am 
sinnvollsten ist ein paar Werte in den EEPROM zu schreiben und anhand 
derer den Sinus zu generieren. Die Methode gefällt mir auch, nur mangelt 
es mir an Programmierkunst, da ich leider noch nicht allzulange dabei 
bin und mit EEPROM noch nie etwas gearbeitet habe. Desweiteren bin ich 
recht froh C zu verstehen und auch ein wenig schreiben zu können, 
allerdings beherrsche ich Assembler sicher nicht!
D.h. ich möchte mein kleines Projekt in C schreiben, auch wenn viele 
sagen, dass der Tiny13 mit Assembler und sonst nix programmiert gehört.

Und nun zu meiner Frage:

Wie schreibe ich in den EEPROM rein und wie kann ich die Werte auch 
wieder auslesen?

von Uhu U. (uhu)


Lesenswert?

EEPROM: Sieh dir mal die Beschreibung des Tiny13 an - unter Memories 
stehen Codebeispiele in ASM und C, wie man das macht.

C und Tiny13: da wirst du u.U. sehr schnell in Speicherplatznot kommen - 
512 Codeworde sind schnell voll geschrieben. Man kann zwar durch 
geschickte Codieren in C einiges rausholen, aber dazu muß man sich den 
ASM-Output des Compilers ansehen - was aber auch eine gute Methode ist, 
den Assembler zu lernen...

von gast (Gast)


Lesenswert?

ah ja das im datenblatt habe ich soeben auch gefunden gehabt, nur hilft 
mich dar gerade nicht zuu viel. Gibts da nicht auch irgendiwe so ein 
Tutorial wie das AVR-GCC-Tutorial? Da würde meinem Verständnist stark 
helfen!

Zu Assembler: Grundsätzlich will ich das schon noch lernen, aber jetzt 
erstal uss ich C richtig lernen und beherrschen. Und da der Tiny13 nicht 
mehr als dieses geteilet Sinussignal erzeugen soll, hab ich kein problem 
mit mangeldem Speicher denke ich.

von spess53 (Gast)


Lesenswert?

Hi

Du solltest dir aber bewusst sein, dass der EEPROM-Zugriff nicht gerade 
der schnellste ist.

MfG Spess

von Tim T. (tim_taylor) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hi, ich hatte sowas mal für einen Tiny25 gebastelt, allerdings die Werte 
nicht im EEPROM (Quelltext anbei).

Würde ich nur heute anders machen, bastel dir einfach einen Schwingkreis 
(LC) mit der gewünschten Resonanzfrequenz, den du mit einer einfachen 
PWM der gewünschten Frequenz pulst.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Grade mal versucht auf einem Tiny13 zu kompilieren:

1. TIMSK heisst dort TIMSK0
2. Sind es zu viele Werte für den Speicher.
   (Nur die Hälfte der Sinuswerte nehmen und spiegeln!)


Idee zum EEPROM:
1
 OCR0A = eeprom_read_byte(counter);

Setzt vorraus das die Sinuswerte ab 0x00h im EEPROM liegen, allerdings 
ist dieser NICHT schnell genug um die Daten in der ISR zu liefern!

von Uhu U. (uhu)


Lesenswert?

gast wrote:
> ah ja das im datenblatt habe ich soeben auch gefunden gehabt, nur hilft
> mich dar gerade nicht zuu viel. Gibts da nicht auch irgendiwe so ein
> Tutorial wie das AVR-GCC-Tutorial? Da würde meinem Verständnist stark
> helfen!

Zu dem Thema EEPROM schreiben/lesen gibt es - zumindest aus 
Softwaresicht - nicht mehr zu sagen, als im Datenblatt steht, aber du 
kannst ja hier mal gucken: 
http://www.mikrocontroller.net/articles/Speicher#EEPROM

> Zu Assembler: Grundsätzlich will ich das schon noch lernen, aber jetzt
> erstal uss ich C richtig lernen und beherrschen. Und da der Tiny13 nicht
> mehr als dieses geteilet Sinussignal erzeugen soll, hab ich kein problem
> mit mangeldem Speicher denke ich.

Du wirst dich wundern, wie schnell der Tiny13 voll ist...

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Uhu Uhuhu wrote:
> Du wirst dich wundern, wie schnell der Tiny13 voll ist...

Ohne jetzt einen Glaubenskrieg (ASM vs. C) anzuzetteln, aber das Problem 
ist diesmal wirklich das DATA Segment und da wirst du nix mit ASM dran 
optimieren können, 64 Byte bleiben 64 Byte und da bekomme zumindest ich 
nur 64 Byte rein^^


PS: Nach Anpassung mit Spiegelung in C:

Program:     234 bytes (22.9% Full)
(.text + .data + .bootloader)

Data:         41 bytes (64.1% Full)
(.data + .bss + .noinit)

von Uhu U. (uhu)


Lesenswert?

Tim T. wrote:
> Uhu Uhuhu wrote:
>> Du wirst dich wundern, wie schnell der Tiny13 voll ist...
>
> Ohne jetzt einen Glaubenskrieg (ASM vs. C) anzuzetteln,

Nimms nicht tragisch, war nicht böse gemeint...

von gast (Gast)


Lesenswert?

Hey super Danke euch.

Den Code von Tim T. finde ich Spitze! Danke!
Zur Arraylänge kann ich sagen, dass die sich vierteln lässt, da ich ja 
mit sin(0) -> sin(90) -> sin(0) schon wieder ne halbwelle habe.
Die Idee mit dem EEProm hatte ich nur um eben den Flash zu entlasten, 
aber wenn das passt, dann ists mir so auch lieber.

Zu meinem Verständis hätte ich aber doch noch ein paar kleine Fragen:
(auch wenn ich den EEPROM in diesem Projekt dann also doch nicht nutzen 
werde will ich doch etwas über ihn lernen...)

-Ihr sag der EEPROM sei zu langsam. Ist denn der Flash schneller, oder 
wird das Array automatisch in den SRAM abgelegt?
- Wie schnell ist denn der EEPROM überhaupt?

-Und allgemein zum EEPROM. Den muss ich ja nicht bei jedem programmstart 
neu schreiben bzw. würde das ja auch keine entlastung für den 
Flash-Speicher sein. Also wie bekäme ich das Array in den EEPROM? Muss 
ich da erst ne Software drauflasen, mit der ich über RS232 o.ä. in den 
EEPROM reinschreibe und dann neu Flashen mit der Software die das dann 
nutzt oder wie ginge sowas in meinem Fall?

von Uhu U. (uhu)


Lesenswert?

EEPROM: Lesen geht recht flott, aber das Schreiben braucht lange - wie 
beim Flash auch.

Die AVRs sind Harvard-Maschinen - die können keinen Code aus RAM oder 
EEPROM ausführen. http://de.wikipedia.org/wiki/Harvard-Architektur

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

gast wrote:
>Zur Arraylänge kann ich sagen, dass die sich vierteln lässt, da ich ja
>mit sin(0) -> sin(90) -> sin(0) schon wieder ne halbwelle habe.
Klar, das kann man mit ner Viertelperiode machen, wird nur wieder etwas 
aufwändiger.

>Die Idee mit dem EEProm hatte ich nur um eben den Flash zu entlasten,
>aber wenn das passt, dann ists mir so auch lieber.
Da das Programm sonst nur 2 Byte im Data Segment belegt, bleiben dir 62 
Byte. Im EEPROM hingegen hast du volle 64 Byte, lohnt also ansich nicht.

>Ihr sag der EEPROM sei zu langsam. Ist denn der Flash schneller, oder
>wird das Array automatisch in den SRAM abgelegt?
Ja der Flash ist schneller und nein, es wird vorher nicht ins SRAM 
kopiert.

>Wie schnell ist denn der EEPROM überhaupt?
Der Zugriff dauert afaik 4 Takte, aufs Flash 2 Takte. Demnach halb so 
schnell. Sollte aber solange du mit CPU-Takt/8 die PWM benutzt gehen, 
sonst könnte es bei großen OCR0A Werten (z.B. 254) Probleme geben da vom 
Compare(254) bis zum Update (255) der OCR0A noch keinen neuen Wert hat.
Ergo ist meine Aussage oben, das der EEPROM nicht schnell genug für die 
Verwendung in der ISR ist, zumindest beim reinen Lesezugriff, als 
relativ zu betrachten^^

>Und allgemein zum EEPROM. Den muss ich ja nicht bei jedem programmstart
>neu schreiben bzw. würde das ja auch keine entlastung für den
>Flash-Speicher sein. Also wie bekäme ich das Array in den EEPROM? Muss
>ich da erst ne Software drauflasen, mit der ich über RS232 o.ä. in den
>EEPROM reinschreibe und dann neu Flashen mit der Software die das dann
>nutzt oder wie ginge sowas in meinem Fall?
Nein, es wäre in der Tat nicht so sinnig den bei jedem Programmstart neu 
zu schreiben. Für das Beschreiben des EEPROMS kannst du im AVR Studio 
unter View -> Memory -> EEPROM die Bytes von Hand setzen und dann beim 
Beschreiben "Use Current Simulator EEPROM" auswählen. Oder du erstellst 
ein EEPROM.hex File das du reinschreibst. Oder du bastelst ein Programm 
was mal eben das Sinustabellen Array ins EEPROM schreibt und löschst den 
EEPROM dann nicht mehr, bzw. liest den EEPROM aus und schreibst ihn in 
ein Hexfile.

Ansonsten zum lernen:

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#EEPROM
und
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Speicher#EEPROM_2

Uhu Uhuhu wrote:
>Die AVRs sind Harvard-Maschinen - die können keinen Code aus RAM oder
>EEPROM ausführen. http://de.wikipedia.org/wiki/Harvard-Architektur
Stimmt, ist aber für die Fragestellung nicht ganz passend, natürlich 
kann man DATEN aus jeder Datenquelle verarbeiten, nur das PROGRAMM muss 
im Flash stehen. Wo das Array mit den Werten steht ist egal.

von gast (Gast)


Lesenswert?

Im Datenblatt vom ATTiny bin ich glaube ich auch ein stück schlauer 
geworden. Die daten werden wohl erst aus den EEPROM in ein Register im 
SRAM gespeichert und könnn von dort aus verarbeitet werden. Jetzt 
dämerts auch was man mir vor eingen Jahren mal über Mikrocontroller 
erzählt hatte. (Damals konnte ich mit glück einen Transistor als 
Schalter Verwenden)

Aber nochmal zurück zum Code von Tim T. Kann das sein, dass das keine 
saubere Sinuswelle ergibt? wenn ich das so richtig sehe, dann wird dort 
der Falsche interrupt verwendet. Nämlich der "Timer/Counter Compare 
Match A"-Interrupt. Dies dürfte meiner Meinung nach zu einer Kurve wie 
dem in folgendem Beitrag führen:
Beitrag "Re: PWM-Sinus"
Wenn man stattdessen den "Timer/Counter Overflow"-Interrupt verwendet, 
werden die gleichmäßig breit ausgerechneten Abschnitte der Sinuskurve 
auch gleichmäßig breit wiedergegeben.
Oder liege ich da falsch?

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

gast wrote:
> Viel Text.

Der Quelltext benutzt die Fast PWM Variante, in der Einstellung das der 
Ausgang bei 0x00 auf 1 und beim Match auf 0 gesetzt wird, der Zähler 
zählt allerdings IMMER bis 0xFF, absolut unabhänig welcher Interrupt 
ausgelöst wird. Der Wert von ORC0A die On-Tastzeit an. Die PWM Periode 
geht immer von 0x00 bis 0xFF und läuft mit einer Frequenz von 
F_CPU/(Vorteiler*256), bei 8MHz und einem Vorteiler von 8 etwa 
3906,25Hz. Und da ich hintereinander die 78 Werte ausgebe, jeder braucht 
eine PWM-Periode, teilt sich dabei diese Frequenz nochmals durch 78 und 
ich komme auf etwa 50,08 Hz.

Der Timer Compare Match A wird ausgelöst wenn Zähler = OCR0A.
Der Timer Overflow wird ausgelöst wenn Zähler = 0xFF.
Auswirkungen auf das Zählerverhalten haben diese Interrupts nicht.

Wenn man wie du es vorschlägst den Overflow Interrupt benutzt, kommt 
dieser immer nach der gleichen Zeit beim überlauf von 0xFF nach 0x00, 
nur ist das ansich schon zu spät um ORC0A noch vor dem nächsten 
Durchlauf zu ändern (die komplette ISR muss vorher durchlaufen werden), 
da der Wert von OCR0A intern schon bei BOTTOM (0x00) übernommen wird.
Bei meiner Variante wird der nächste 0RC0A Wert schon beim Compare 
geschrieben, man hat somit mehr Zeit (höchster Wert der Sinustabelle war 
glaubich 254). Somit hat man (256-254)*Vorteiler -> 16 Takte Zeit bis 
der Wert aus dem ORC0A intern übernommen wird.

von gast (Gast)


Lesenswert?

Achso ja... Ok hast mich überredet. Ich hab aus irgendeinem Grund 
gedanklich bei jedem Komparematch den Counter gelöscht, was aber 
irgendwie keinen Sinn gibt. Naja Fehler passieren.
Aber danke für deine ausführliche Antwort.

Dass und wann OCR0A übernommen wird wusste ich gar nicht.

von gast (Gast)


Lesenswert?

Tim T. schreib:
>
>Program:     234 bytes (22.9% Full)
>(.text + .data + .bootloader)
>
>Data:         41 bytes (64.1% Full)
>(.data + .bss + .noinit)

Wie kommst du zu diesen Angaben? ich benutze WinAVR und war der festen 
Überzeugung das hast das schon mal angezeitg aber ich weiß einfach nicht 
wie?!

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

gast wrote:
>Achso ja... Ok hast mich überredet. Ich hab aus irgendeinem Grund
>gedanklich bei jedem Komparematch den Counter gelöscht, was aber
>irgendwie keinen Sinn gibt. Naja Fehler passieren.
>Aber danke für deine ausführliche Antwort.
Kein Akt, hatte selber als ich das Programm gebastelt hab den Denkfehler 
mit dem Timer Overflow gemacht.

>Dass und wann OCR0A übernommen wird wusste ich gar nicht.
http://www.atmel.com/dyn/resources/prod_documents/doc8126.pdf
Seite 73 in der Tabellenspalte "Update of OCRx at"

Komischerweise übernimmt der Tiny13 das OCRx laut der Tabelle im 
Datenblatt schon beim erreichen von TOP (0xFF) in Mode 3.
Der Tiny25 in Mode 3 allerdings erst bei BOTTOM (0x00):
http://www.atmel.com/dyn/resources/prod_documents/doc2586.pdf
Seite 82.
Kurzer Vergleich mit 5 Weiteren Datenblättern ergab das alle bei BOTTOM 
aktualisieren, demnach geh ich von einem Druckfehler im Datenblatt des 
Tiny13 aus...

> Wie kommst du zu diesen Angaben? ich benutze WinAVR und war der festen
> Überzeugung das hast das schon mal angezeitg aber ich weiß einfach nicht
> wie?!

AVR Studio -> View -> Toolbars -> Build Output (Haken davor machen)
Wenn da ein Haken ist, einfach auf Build im Unteren Fenster gehen, nach 
dem Build stehen die Infos dann da.

von gast (Gast)


Lesenswert?

> AVR Studio -> View -> Toolbars -> Build Output (Haken davor machen)
> Wenn da ein Haken ist, einfach auf Build im Unteren Fenster gehen, nach
> dem Build stehen die Infos dann da.

Der Haken ist gesetzt und unter build steht bei mir nur

Build started 6.1.2009 at 09:34:22
avr-gcc  -mmcu=attiny13 -Wall -gdwarf-2  -DF_CPU=4000000  -Os 
-fsigned-char -Wp,-M,-MP,-MT,test.o,-MF,dep/test.o.d  -c  ../test.c
avr-gcc -mmcu=attiny13  test.o    -o test.elf
avr-objcopy -O ihex -R .eeprom  test.elf test.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" 
--change-section-lma .eeprom=0 -O ihex test.elf test.eep
c:\Programme\AVR\WinAVR\bin\avr-objcopy.exe: --change-section-lma 
.eeprom=0x00000000 never used
Build succeeded with 0 Warnings...

Da werde ich wohl noch Google nach unbekannt durchforsten müssen...
Trotzdem aber vielen vielen Dank.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

gast wrote:
> Da werde ich wohl noch Google nach unbekannt durchforsten müssen...
> Trotzdem aber vielen vielen Dank.

Naja, ganz so schlimm ist es ja nicht: 
Beitrag "AVR Memory Usage ausgeben lassen"

Ansonsten mal in dein Makefile ob dort

## Build
all: $(TARGET) xxx.hex xxx.eep xxx.lss size

und

size: ${TARGET}
  @echo
  @avr-size -C --mcu=${MCU} ${TARGET}

drin steht.

von gast (Gast)


Lesenswert?

wahrscheinlich mach ichs falsch aber es funktioniert bei mir nicht. 
Warum auch immer.
Wenn ich das makefile Exportiere und da dann diese Zeilen einfüge (die 
1. zwei sind schon vorhanden, die unteren nicht), dann noch das Exterene 
Makefile verwenden und Compilieren. Und schon gibt er mir ne 
Fehlermeldung:
Makefile:69: *** missing separator.  Stop.
Das ist die Zeiel: @echo

Suche ich allerdings irgendwoanders das Standardmakefile (gefunden in 
...\WinAVR\sample\ ) dann passiert nix und nutze kein externes Makefile, 
dann passiert nix.

Ärgert mich jetz langsam!

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.