mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM Problem: Pin nur 1 Clk Cycle High


Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab ein Problem mit dem Atmega88 und der PWM. Ich hatte die PWM 
bereits am Laufen, habe dann aber wohl irgendwie einen Fehler 
eingebaut... leider kann ich diesen einfach nicht finden.
void initPWM()
{
  // Fast PWM 10bit (WGM10,WGM11,WGM12,!WGM13), clear on compare match (COM1A1,!COM1A0)
  TCCR1A = (1<<WGM10) | (1<<WGM11) | (1<<COM1A1);
  // prescale of 1 @ 10bit -> PWM = 7.8kHz (CS10,!CS11,!CS12)
  // setting CS10 to one starts -> leave it 0 for init
  TCCR1B = (1<<WGM12);
  // Timer to 0
  TCNT1L = 0;
  TCNT1H = 0;
  // compare register to 0
  OCR1AL = 0;
  OCR1AH = 0;
  // PB1 is OC1A -> set output
  DDRB |= (1<<PB1);
}

void setPWM(uint16_t hightime)
{
  //10bit pwm, make sure upper 6bits are 0
  OCR1AL = (uint8_t)hightime;
  OCR1AH = (uint8_t)((hightime>>8)&0x0003);
}

void startPWM()
{
  TCCR1B |= (1<<CS10);
}


int main()
{
  initPWM();
  setPWM(0x100);
  startPWM();
  while(1);
}

Mit dem Code möchte ich die PWM eigentlich initialisieren und starten. 
Der OC1A Pin ist allerdings unabhängig von dem Wert den ich mit setPWM() 
setze genau 1 Clock Cycle HIGH, dann den Rest der Periode LOW.

Viele Grüße
Stefan

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab jetzt noch eine Weile rumgespielt und den Code aus dem eigenen 
Testprojekt genommen (Testprojekt hat nur oben genannten Code 
beinhaltet).
Im Zusammenhang mit anderem Code funktioniert die PWM mit oben 
vorgenommenen Einstellungen nun.
Was ist da passiert? Hat der Compiler die While-Schleife wegoptimiert... 
wäre ja logisch... aber springt er dann komplett auf "aus"? Also ist es 
normal, dass er dann auch keine PWM mehr ausührt?

Viele Grüße
Stefan

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>  OCR1AL = (uint8_t)hightime;
>  OCR1AH = (uint8_t)((hightime>>8)&0x0003);

Die Reihenfolge ist falsch. Erst das H- und dann das L-Register 
schreiben.

MfG Spess

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo spess,

herzlichen Dank für Deine Antwort. Ich habe die Reihenfolge nun 
geändert. Im Testprojekt hat sich dadurch leider nichts geändert. 
Immernoch nur 1 clock cycle High.

Viele Grüße
Stefan

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan schrieb:
> Ich habe die Reihenfolge nun
> geändert.

Auch in initPWM()?

Andreas

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andreas,

ja sowohl im setPWM, als auch im initPWM. Zur Vorsicht habe ich nun auch 
noch TCNT1H/L gedreht. Hat leider auch nichts bewirkt.

Viele Grüße
Stefan

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Hat leider auch nichts bewirkt.

Kannst du mal den Assemblercode des Programms anhängen.

MfG Spess

P.S. Neu compiliert hast du aber?

Autor: Stefan (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

neu compiliert hatte ich :)
hier das Assembly... leider sieht es nicht sehr aufgeräumt auf. Ich habe 
noch nie etwas mit Assembler gemacht und es einfach aus dem Disassembly 
Fenster beim debuggen kopiert, ich hoffe das ist in Ordnung (wusste 
sonst keine Möglichkeit).

Viele Grüße
Stefan

Autor: Stefan (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

in dem File zuvor hatte ich noch etwas rumgespielt und vergessen das 
auszukommentieren. Hier noch einmal der Assembler Code des Quellcodes 
wie ich ihn oben gepostet hatte.

Viele Grüße
Stefan

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Auf den ersten Blick:

1.  Das ist nicht das obige Programm. Ach nicht das korrigierte.
2.  Hast du beim compilieren keine Warnungen oder Fehlermeldungen 
bekommen?

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>in dem File zuvor hatte ich noch etwas rumgespielt und vergessen das

Hatte ich gemerkt.

MfG Spess

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

erstmal Entschuldigung wegen des falschen Assembler Code.
Ich habe jetzt noch einmal (diesmal direkt im Assembler) debuggt:

er steigt ein bei:
+00000045:   DFDD        RCALL     PC-0x0022      Relative call subroutine
->
+00000023:   E883        LDI       R24,0x83       Load immediate
+00000024:   93800080    STS       0x0080,R24     Store direct to data space
11:         TCCR1B = (1<<WGM12);
+00000026:   E088        LDI       R24,0x08       Load immediate
+00000027:   93800081    STS       0x0081,R24     Store direct to data space
13:         TCNT1H = 0;
+00000029:   92100085    STS       0x0085,R1      Store direct to data space
14:         TCNT1L = 0;
+0000002B:   92100084    STS       0x0084,R1      Store direct to data space
17:         OCR1AH = 0;
+0000002D:   92100089    STS       0x0089,R1      Store direct to data space
18:         OCR1AL = 0;
+0000002F:   92100088    STS       0x0088,R1      Store direct to data space
21:         DDRB |= (1<<PB1);
+00000031:   9A21        SBI       0x04,1         Set bit in I/O register
22:       }
+00000032:   9508        RET                      Subroutine return
->
+00000046:   E081        LDI       R24,0x01       Load immediate
+00000047:   93800089    STS       0x0089,R24     Store direct to data space
28:         OCR1AL = (uint8_t)hightime;
+00000049:   92100088    STS       0x0088,R1      Store direct to data space
33:         TCCR1B |= (1<<CS10);
+0000004B:   91800081    LDS       R24,0x0081     Load direct from data space
+0000004D:   6081        ORI       R24,0x01       Logical OR with immediate
+0000004E:   93800081    STS       0x0081,R24     Store direct to data space
+00000050:   CFFF        RJMP      PC-0x0000      Relative jump

Was mir hierbei auffällt ist, dass er niemals diese Zeile des C 
Quellcodes ausführt:
TCCR1A = (1<<WGM10) | (1<<WGM11) | (1<<COM1A1);

dies sollte ja nach dem ersten RCALL geschehen. Dass die PWM dann nicht 
funktioniert erscheint plausibel, da in dieser Zeile ja der OC1A Pin 
freigeschalten wird.
Dass dies nicht passiert kann ich nur irgendwie nicht mit meinem C 
Quellcode in Verbindung bringen.

Viele Grüße
Stefan

Autor: Stefan Köhler (stefankoehler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab mich jetzt mal angemeldet und hoffe, dass ich meine Beiträge nun 
auch editieren kann. Mir ist nämlich schon wieder ein Fehler 
unterlaufen: die Zeile wird doch ausgeführt, der C Code steht nur nicht 
im Kommentar des Dissassembly.

Was bei der Simulation passiert:

Alle Register werden gesetzt, dann bleibt der Code für immer im letzten 
Relative Jump. Nun beginnt der Timer zu zählen.
Timer:
1) läuft nun von 0x00 bis 0x100 und setzt Output Compare Flag 1A (hätte 
erwartet, dass das Flag von Beginn an gesetzt ist, bis 0x100 erreicht 
wird und dann auf 0 gesetzt wird. Nicht umgekehrt, da COM1A1=1 COM1A0=0)
2) läuft weiter bis 0x3FF (wie erwartet)
3) zählt von 0x3FF runter auf 0 (hätte hier erwartet, dass er auf 0 
springt, da Fast PWM: WGM10=WGM11=WGM12=1 WGM13=0)
4) bei 0 setzt er TimerOverflowFlag und Output Compare Flag 1B und zählt 
zurück auf 0x3FF.
5) ab jetzt wird auf 0x3FF gezählt und zurück auf 0 usw. (Flags werden 
nicht mehr geändert)

Die Register sind wie oben genannt gesetzt (Fast PWM, Clear OCA1 on 
Compare Match, Set at BOTTOM).

Viele Grüße
Stefan

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.