PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATmega32 mit externem Quarz, PWM falsch



Mauro
12.04.2010, 16:24
Hallo zusammen!

Ich habe einen ATmega32 und kann mit dem internen 8MHz-Quarz ein relativ gutes PWM Signal erzeugen (1-2ms, Wiederholung alle 20 ms, typisch für Modellbau).

Aber die Genauigkeit weicht einige Prozent vom Sollwert ab, das "sagen" einerseits die Servos und andererseits mein Oszi.

Deshalb habe ich mir gedacht ich schließe einen externen Quarz an. Ich habe einen 14,7456 MHz-Quarz gewählt, da der für die serielle Schnittstelle optimal ist.

Ich arbeite wieder mit einem Prescaler 8, Mode 14 Fast PWM, nicht invertiert. ergibt also ca. 36864 Takte je 20ms.

Im AVR Studio habe ich als Takt gewählt: Ext. Crystal/Resonator HF, Startuo 16K CK +64ms

Ich bekomme nun eine Ausgabe Frequenz von 1Hz, statt der rund 50Hz.
Der Fehler ist also Faktor 50, was irgendwie systematisch zu sein scheint.

Hat von Euch vielleicht jemand eine Idee?

Liebe Grüße und Danke!

yaro
12.04.2010, 20:27
1Hz ist schon echt viel!
Hast du den Quarz mit 20pF Kondensatoren gegen GND richtig beschaltet?
Hast du im Makefile die neue Taktfrequenz eingestellt?
Prescaler sicher richtig gewählt?

Was passiert, wenn du den Maximalwert im Timer halbierst? Halbiert sich dann auch die PWM-Frequenz? (kann ja sein, dass der Fehler woanders liegt)

Gruß, Yaro

Mauro
13.04.2010, 10:56
Ich habe gerade im Datenblatt nochmal nachgeschaut, dort steht bei externem Quarz über 1 MHz sollte man den Quarz mit 12-22 pF verschalten. Das hatte ich auch gemacht, beide Füße mit GND verbunden. nun habe ich diese durch 15pF ersetzt und das Problem ist das gleiche geblieben.

Prescaler habe ich auf dem Papier nachgerechnet und zum Vergleich nochmal den internen Quarz zum Vergleich hergenommen. das scheint zu passen.

Quarz 14745600 Hz
Prescaler 8
ergibt prescaled Frequency 1843200 Hz
bei gewollter Periode von 20ms (50Hz)
ergibt sich 36864 Takte je 20ms (ICR1) oder 50 Hz Ausgabefrequenz
bei mir leider nur 1,irgendwas Hz... :-(

Die Taktfrequenz habe ich im AVR Studio ausgewählt, das setzt mir die Fuses und ersetzt damit ja mein Makefile.

Halbiere ich den maximalen Wert des Timers (ICR1), verdoppelt sich die Frequenz (sollte sie ja auch).

Grüße,
emmPunkt

Mauro
14.04.2010, 11:13
Ich habe jetzt bei der Suche nach einer anderen Sache etwas entdeckt. Im Thread "Atmega32 führt Program nicht aus [gelöst]" schreibt Kollege _R2D2, dass das AVR Studio beim Atmega die falschen Fuses schreibt, ist das wahr bzw. ein bekanntes Problem, oder Gegenfrage: Nutzt jemand den Atmega32 erfolgreich mit externem Quarz und schreibt seine Fuses mit AVR Studio?

Ich arbeite jetzt mit dem internen Quarz und mache ja nach Raumtemperatur ein anderes Offset. Das ist aber ganz klar nur eine Notlösung.

wkrug
14.04.2010, 11:52
Nutzt jemand den Atmega32 erfolgreich mit externem Quarz und schreibt seine Fuses mit AVR Studio?
Ja, mach ich und hatte eigentlich noch keine Probleme damit.
Ich nutze sehr oft externe 8MHz Quarze am ATMEGA 16 und 32.
Auch mit einem 16MHz Quarz hat bei mir bis jetzt immer alles geklappt.

Ich nutze dabei die Einstellung:
Ext. Crystal/Resonator High Freq.; Start-up time: 16K CK + 64 ms

Ich hab die AVR Studio Version 4.17 Built 666 und den AVR ISP MKII als Programmer.
Du hast aber schon die Fuses richtig gesetzt bevor Du das .elf File abgespeichert hast ?

Mauro
14.04.2010, 12:30
So, da haste mich erwischt :-)
Die Einstellung wie Du sie beschrieben hast, nutze ich auch.
Allerdings: Fuses habe ich nicht gesetzt, nur die Einstellung gewählt (bin so ein typischer User der denkt, dass es dann funktioniert).
*.elf habe ich in meinem Leben noch nicht gehört oder gesehen.
Nutze AVR Studio 4.18 b692 mit AVR ISP MK II.

Scheinbar könnte das Problem hier liegen.

wkrug
14.04.2010, 23:41
Am .elf File kann es dann eigentlich nicht liegen.
Du musst natürlich die Einstellungen im Fuses Fenster machen und dann "Program" in diesem Fenster anklicken.

Das .elf File ist eine Art Steuerdartei.
Man macht alle benötigten Einstellungen ( Fuses Pfande usw. ) und macht dann ein neuse .elf File.

Will man dann mehrere Controller nacheinander Programmieren, braucht man nur dieses gespeicherte .elf File starten und alle Einstellungen und Programmierungen am Controller werden erledigt.

Mauro
15.04.2010, 10:20
Nun ich klicke den Program Button, siehe auch das angehängte Bild.
Nun ist mir gerade aufgefallen, dass im Build-Fenster aber DF_CPU 8MHz versteckt ist. Das dürfte dann doch nicht mehr der Fall sein, oder?

Build-Meldung:
avr-gcc -mmcu=atmega32 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT MG_S.o -MF dep/MG_S.o.d -c ../MG_S.c

Fuses-Fenster: s. Anhang

Was ist denn da nun los? Da liegt doch der Fehler...

Mauro
15.04.2010, 11:56
Ok: ich kann nun meine Frequenz in der Build-Zeile sehen!
Grund: Unter Project...Configuration...General stand noch immer 8MHZ, da steht nun meine neue Frequenz, aber statt 50Hz PWM Signal messe ich noch immer rund 1Hz.

Mein Latein ist zu Ende :-(

wkrug
15.04.2010, 17:59
Mein Latein ist zu Ende
Mir fallen noch ein paar Sachen ein.

1. Du solltest die JTAGEN Fuse deaktivieren.
Kann zwar mit deinem Problem eigentlich nichts zu tun haben, belegt aber einzelen Pins des Ports C.

2. Hast Du in Deiner Software irgendwo den Watchdog aktiviert und es komt nicht rechtzeitig der "WDR"

Die beiden Sachen fallen mir dan noch ein.

Mauro
16.04.2010, 12:03
Hallo wkrug!

ad 1.: Mit oder ohne JTAGEN, keine Beeinflussung
ad 2.: Den Watchdog habe ich nur mal als Symbol gesehen, aber nie verwendet. WDR finde ich auch nirgends.

Ich hatte ausversehen ein PWM mit 27,40 Hz und dachte, hey warum ist das plötzlich so? Über Nacht hatte ich nichts geändert:

Ich habe eine Fehlermatrix aufgestellt:
General-
einstellung Fuses ICR1 Gemessenes PWM
8MHz Int. 8Mhz 20000 50Hz (logische Sache)
8MHz Int. 8Mhz 36864 27,4Hz (logische Sache)
14,xxMHz Int. 8Mhz 20000 27,4Hz (Generaleinstellung hat offenbar keinen Einfluss)
14,xxMHz Ext. HF Cry. 36864 1,xxHz (altes Problem)
14,xxMHz Ext. HF Cry. 20000 ~2Hz (altes Problem)

Was auch immer der Watchdog ist und macht und ob ich ihn überhaupt verwende, sind die Fuses auf Ext. geht gar nichts mehr so wie es soll...

Mhhh...

wkrug
16.04.2010, 19:15
OK,

was hast Du für einen ATMEGA 32
Nen ATMEGA 32 - 16 oder einen ATMEGA 32 L 8 ?
Was sagt AVR Studio in der Simulation ?
Passt da die PWM Frequenz ?

Hast Du schon mal einen anderen ATMEGA 32 - 16 Controller ausprobiert ?

Wie schaut das Oszillogramm deiner PWM aus ?

oberallgeier
16.04.2010, 19:43
Hi, emm.,


... Quarz 14745600 Hz
Prescaler 8
ergibt prescaled Frequency 1843200 Hz
bei gewollter Periode von 20ms (50Hz)
ergibt sich 36864 Takte je 20ms (ICR1) oder 50 Hz Ausgabefrequenz
bei mir leider nur 1,irgendwas Hz... ...Könntest Du bitte mal den Code posten, mit dem Du den Timer initialisierst?

Mauro
17.04.2010, 11:26
//PWM
//Ext. Quarz 14,7456MHz

//Prescler festlegen: 8
TCCR1B |= (1<<CS11) ;

//Timer im Fast PWM Mode 14, auf die beiden TCCR1 Register verteilt
TCCR1A |= (1<<WGM11) ;
TCCR1B |= (1<<WGM13) | (1<<WGM12) ;

//Compare output mode, Fast PWM, non-inverting mode
TCCR1A |= (1<<COM1A1) | (1<<COM1B1) ;

//Timer 36864 Takte sind 20ms und entsprechen dann 50Hz
ICR1 = 36864;

//Registereinträge für die gewünschtenn Werte
OCR1A = iPWM1A;
OCR1B = iPWM1B;

//Pins als Ausgang konfigurieren, sonst liegt kein Signal am Pin an
DDRD |= (1<<PD4) | (1<<PD5) ;

oberallgeier
17.04.2010, 19:30
Jetzt hoffe ich nur, dass Du nicht schon Interrupts erlaubst, bevor der Timer 1 vollständig initialisiert ist. Sonst KÖNNTE der einen Interrupt auslösen, bevor ICR1 = 36864 komplett weggeschrieben ist. Jedenfalls erinnere ich mich bei meinen Problemen dunkel an unsinnige Funktionen des Timers, wenn ich in so ein Timerregister erst am Ende der Initialisierung reingeschrieben hatte; vermutlich hatte ich da schon mal vorher "sei();" gesetzt . . . .


[/size]MEL im doc 8155A–AV R–06/08]... Special procedures must be followed when accessing the 16-bit registers. ...Ich weiß aber wirklich nicht, ob das eine Abhilfe sein kann.

Mauro
19.04.2010, 10:11
So, ich habe nun alle sei() aus dem Code raus, da ich sie aktuell eh nicht brauche. Aber das bringt gar nichts.

Scheint bei mir ein Montagsprodukt zu sein. Ohne externen Quarz kann ich leider nicht weiterarbeiten, werde mir ein Zweitsystem zusammenlöten. Neue Chance neues Glück?