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?
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...
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.
Hi Du solltest dir aber bewusst sein, dass der EEPROM-Zugriff nicht gerade der schnellste ist. MfG Spess
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.
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!
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...
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)
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...
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?
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
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.
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?
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.
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.
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?!
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.
> 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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.