Forum: Mikrocontroller und Digitale Elektronik ATTiny261A mit Phase/Freq. korrekt PWM will nicht


von Uwe (Gast)


Angehängte Dateien:

Lesenswert?

Moin!

Nach 7 Stunden Knobeln bin ich jetzt bereit mir Rat zu holen...

Baustein: Attiny261A-PU
Problem: Frequenz und Phasenkorrektes PWM am Ausgang von "OC1A 
INVERTIERT" (IC Pin 1, PORTB 0) will nicht.

Zur Übersicht:
- µC läuft
- Takt vom RC mit 8Mhz ist da
- PIN PORTB, 0 als Ausgang initalisiert (und auch mal testweise mit 
SBI/CBI auf Funktiion geprüpft)
- TIMER/COUNTER0 läuft und liefert an einem anderen Ausgang einen 
50Hz-Takt

Ich habe mich strikt ans Datenblatt gehalten. Das Register OCR1C soll ja 
der "TOP"-Wert (Zählerbreite) und OCR1A der MATCH-Wert. Aber so oder so, 
es rührt sich am Suagang nichts.

Kann wer mal über den ASM-Code gucken und mir sagen, an welcher Stelle 
ich mich in die Nesseln gesetzt habe? :)

Danke!

Uwe

von Karl H. (kbuchegg)


Lesenswert?

Weißt du

Solche Dinge
1
          ldi    r16, 0b00010000      ; Bit 4 - OCIE0A: Timer/Counter0 Output Compare Match A Interrupt Enable
2
          out    TIMSK, r16
3
4
          ; OCR0A - Timer/Counter0 Output Compare Register A
5
          ldi    r16, 0x7A      ; Wert für CTC-Match
6
          out    OCR0A, r16
sind so unglaublich mühsam zu kontrollieren!

Warum schreibst du
1
          ldi    r16, 0b00010000      ; Bit 4 - OCIE0A: Timer/Counter0 Output Compare Match A Interrupt Enable
2
          out    TIMSK, r16

wenn ein
1
          ldi    r16, (1<<OCIE0A)
2
          out    TIMSK, r16
genau dasselbe macht und um 3 Größenordnungen besser lesbar wäre? 
Schliesslich muss dann zumindest niemand kontrollieren, ob das Bit 4 im 
TIMSK wirklich OCIE0A ist oder nicht.
Mit dem Timer-Modus ist es dasselbe Spiel. OK, welche Bits für einen CTC 
Modus in welchem Register zu setzen sind, müsste man im Datenblatt 
nachsehen (da gibt es eine Tabelle dazu). Aber zumindest das 
Auseinanderpfriemeln der Bits in der Hex-Zahl würde man sich ersparen.

In diesem Sinne: wundere dich nicht, wenn sich die Leute hier nicht 
gerade darum reißen, deinen Code zu kontrollieren.

Edit:
Das selbe gilt natürlich sinngemäss auch für den Timer 1 und seine 
Einstellungen.

: Bearbeitet durch User
von Achim K. (aks)


Lesenswert?

1
          ;TCCR1A  Timer/Counter1 Control Register A
2
          ldi    r16, 0b01000010    ; CTC, OCR1A Enable
3
          out     TCCR1A, r16
4
5
           ;TCCR1C  Timer/Counter1 Control Register C
6
          ldi    r16, 0b00000000
7
          out     TCCR1C, r16

Gemäß Doku sind einige Bits in TCCR1C die selben wie in TCCR1A
1
Bits 7:6 – COM1A1S, COM1A0S: Comparator A Output Mode, Shadow Bits 1 and 0
2
These are shadow bits of COM1A1 and COM1A0 in TCCR1A. Writing to bits COM1A1S and
3
COM1A0S will also change bits COM1A1 and COM1A0 in TCCR1A. Similary, changes written
4
to bits COM1A1 and COM1A0 in TCCR1A will show here.
5
See “TCCR1A – Timer/Counter1 Control Register A” on page 111 for information on bit usage.

Es könnte sein, dass Du mit 0 auf TCCR1C die Bits in TCCR1A löscht.
Ausprobiert habe ich das aber nicht.

von Karl H. (kbuchegg)


Lesenswert?

Eines noch
1
; OCR1A - Timer/Counter1 Output Compare Register A
2
      ldi    r16, 0b00001111    ; Setze Vergleichswert für CTC
3
      out    OCR1A, r16
Ich hab ja nichts gegen Kommentare. Sofern sie sinnvoll sind.
Die hier sind nicht sinnvoll. Dass da etwas ins OCR1A bugsiert wird, das 
sehe ich auch so im Code. Das musst du mir nicht kommentieren. Viel 
wichtiger wäre für mich als Leser des Codes, wie du auf den Wert 
gekommen bist! Warum 15? Wie kommen die zustande? Welche Bewandniss hat 
es damit.
Generell: Kommentiere nicht das wie! Kommentiere das warum!
Wie etwas passiert, das steht im Code. Den Code brauch ich nur lesen. 
Was aber nicht im Code steht, das ist warum hier etwas, und zwar genau 
das was im Code steht, passiert.

und noch was. Wenn du 15 meinst, dann schreib auch 15. Es ist witzlos, 
Dezimalzahlen in Binärform hinzuschreiben, wenn man die im Kopf sowieso 
erst mal wieder auf Dezimal umformen müsste, damit man mit dem 
Zahlenwert was anfangen kann. Du kannst ruhig schreiben
1
; OCR1A - Timer/Counter1 Output Compare Register A
2
      ldi    r16, 15          ; 15, weil .....
3
      out    OCR1A, r16
das ist für dich beim Schreiben einfacher und auch bei deinem Leser, der 
versucht den Code zu verstehen.
Und dem Assembler ist es sowieso wurscht ob du Dezimal oder 
Binärschreibweise benutzt (oder die Bits zb mit der 1<<... Syntax unter 
Verwendung der Bitnamen aus dem Datenblatt ansprichst oder einen 
arithmetischen Ausdruck benutzt um die 15 zb aus der CPU-Frequenz und 
dem Vorteiler zu errechnen oder .... Man benutzt die Schreibweise, der 
in der vorliegenden Situation die klarste ist und in der die Absicht am 
besten rüber kommt. Das ist in manchen Fällen tatsächlich die 
Binärschreibweise. Manchmal. Meistens ist sie es aber nicht.

: Bearbeitet durch User
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.