Forum: Compiler & IDEs PWM OCRnB Problem


von Chrstian T. (christian_trohn)


Lesenswert?

Guten Abend,
ich stehe jetzt schon seit etlichen Stunden vor einem Problem, das ich 
mir nicht erklären kann.
Zum Grundsätzlichen (weiss nich obs eine Rolle spielt weil ich 
mitlerweile keinen möglichen Fehler mehr ausschliesse) erstmal meine 
Initialisierung:

void pwm_init(void)
{
DDRD |= (1<<PD4);     //OC1B Pin
TCCR1A=(1<<WGM11)|(1<<WGM10)|(1<<COM1B1);//PWM, Phase correct, Clear 
comp
TCCR1B = (1<<CS11);  //Presc. 64
}

Ich nutze einen Atmega644-20PU mit 10Mhz Ext Clock. Der Timer1 ist ein 
16bit Timer. An meinem Ausgang OC1B hängt eine Led gegen Ground.
Der PWM arbeitet, schreibe ich von Hand Werte in OCR1B eigentlich 
richtig.
Jetzt zu meinem Aufbau der mir die Probleme macht.

Ich habe einen variablen unsigned char wert von 0-200. Mit diesem möchte 
ich das OCR1B Register steuern.
Hierbei habe ich mir follgende Funktion erstellt:

void pwm_out(unsigned char pot_value)
{

  char temp[50];                 //Diagnose
  unsigned short pot_value_16;   //16 bit pot_val
  pot_value_16=(unsigned short)pot_value;  //uebergabe an 16bit var
  pot_value_16=pot_value_16*81;  //rechnung range 0-16200 dezimal

  itoa(pot_value_16,temp,10);    //Diagnose
  lcd_clear();                   //Diagnose
  lcd_string(temp);              //Diagnose
  OCR1B=pot_value_16;  //Wert an Register uebergeben
}

Lcd funktionen können hier bei dem Problem unberücksichtigt bleiben, die 
hab ich eigentlich nur zur Fehlerdiagnose eingebaut. Aber da ich die 
Funktion jetzt nicht manipulieren will hier im Originialaufbau.
Der Gedanke hinter diesem Konzept ist ganz simpel.
Ich habe maximal den Wert pot_value von 200. Das ganze *81 sollte 
höhstens 16200 ergeben. In Hex wäre das 3F 48. Also bei weitem noch im 
Rahmen der möglichen 16 bit. Jetzt hab ich, wenn ich an meinem Poti 
drehe bei zB: 9234 dezimal die LED komplett aus. bei 10206 dezimal die 
LED komplett an. Sozusagen nur einen Bereich von 972 um die LED von 
dunkel auf hell zu steuern. Das wiederholt sich ständig wenn ich das 
Poti drehe. Schon klar das es wegen den 81 vielleicht etwas mehr oder 
weniger Schritte sind und ich das nich genau feststellen kann. Aber 
Grundsätzlich sollte doch bei solchen Werten kein Überlauf statt finden 
oder?
Bei der Berechnung der Werte sollte ich eigentlich keinen Fehler haben. 
Hab ja auch die Ausgabe auf meinem LCD die mir das richtige Ergebnis 
anzeigt. Denk ich vielleicht an irgend etwas nicht oder hab ich ein 
Grundsätzlichen Fehler in meinem Programm? Hab vorher noch nie mit PWM 
usw gearbeitet also bin um jede Hilfe froh!
Danke schonmal im Vorraus.

Christian

von Klaus W. (mfgkw)


Lesenswert?

Du hast doch WGM1x auf 0b0011 stehen?
Da steht im Datenblatt etwas von "PWM, Phase correct, 10-bit".

Du musst vielleicht noch WGM13 (in TCCR1B) setzen?

(nur auf die Schnelle, habe es nicht genau angesehen)

von Chrstian T. (christian_trohn)


Lesenswert?

Ja PWM Phase correct 10 bit sinds laut Datenblatt.
Aber zu WGM13 / WGM12 steht im Datenblatt nur was zu Wave Generator 
Form.
Trotzdem hab ich das eben noch durch gespielt. Kein sinnvolles Ergebnis.
Mit gestztem WGM13 im TCCR1B hab ich bei Poti stellung 0 die LED voll 
Leuchtend (hab leider kein Oszilloskop, deswegen reines 
Helligkeitsempfinden) und sobald ein Wert in die Rechnung einfliesst ist 
sie aus.

von Chrstian T. (christian_trohn)


Lesenswert?

Du hattest vollkommen Recht!
Ohne das WGM13 bit war es garkein PWM Phase correct. Danke das du mich 
nochmal darauf Aufmerksam gemacht hast! Natürlich gab es einen Überlauf 
bei meiner Funktion ohne WGM13, TOP war nämlich in dem Phase Correct PWM 
Mode, den ich ohne dieses bit gewählt hatte 0x01FF und den hab ich sehr 
wohl zum Überlaufen gebracht. Das Problem mit dem Überlauf ist also 
erledigt. Aber das Problem mit der Poti-stellung 0 und der voll 
leuchtenden LED besteht jetzt immernoch, wie in meinem vorherigen Post 
beschrieben. Also so richtig PWM mässig sieht das ganze bei mir noch 
nicht aus :(

Edit: Sry Vertippt. Überlauf war bei der vorherigen Einstellung auf 
0x03FF.

von Stefan E. (sternst)


Lesenswert?

Wenn du jetzt zusätzlich WGM13 gesetzt hast, dann hast du Mode 11. Der 
ist auch für dich untauglich, weil bei dem OCR1A als TOP verwendet wird. 
Wenn du unbedingt 16 Bit PWM haben willst (warum eigentlich, wo du doch 
nur einen 8 Bit Ausgangswert hast?), dann musst du entweder Mode 8, 10, 
oder 14 nehmen, und ICR1 auf 0xffff setzen.

von Stefan E. (sternst)


Lesenswert?

Nachtrag: Ich sehe gerade, dass du OC1B benutzt. Dann kannst du 
natürlich auch Mode 11 nehmen, musst dann aber OCR1A entsprechend 
setzen.

von Chrstian T. (christian_trohn)


Lesenswert?

Den 16 bit modus hab ich gewählt, weil ich mit der Rechnung dann ohne 
Floats näher an den Endwert herran komme. Wenn ich 8 oder 9 Bit PWM 
nutze, würde ich ohne berechnung mit Float und meinen 200 Steps nicht so 
nah an den Endwert kommen wie bei 16 bit. Verhältnismässig fehlen mir 
zum Endwert mit höherer Auflösung und angepasstem Faktor nurnoch 
weniger.  Ich hab jetzt 10 bit genommen und es scheint sehr gut zu 
Funktionieren. Damit komme ich mit Ganzzahlen auf 97,6% vom Endwert. Mit 
16 bit wären es 99,7%. Aber auf diese kleine Ungenauigkeit kommt es bei 
meiner Anwendung nicht an, da haste Recht.
Den Modus 11 hab ich eigentlich aus Unwissenheit gewählt gehabt weil ich 
aus dem Datenblatt die Infos falsch Interpretiert hatte.

Ich Danke euch beiden vielmals für eure Hilfe einem kleinen Anfänger auf 
die Sprünge zu Helfen :)

von Stefan E. (sternst)


Lesenswert?

Chrstian Trohn schrieb:
> Den 16 bit modus hab ich gewählt, weil ich mit der Rechnung dann ohne
> Floats näher an den Endwert herran komme. Wenn ich 8 oder 9 Bit PWM
> nutze, würde ich ohne berechnung mit Float und meinen 200 Steps nicht so
> nah an den Endwert kommen wie bei 16 bit.

Warum denn gleich Float.
Ich persönlich würde z.B. 8 Bit nehmen und dann:
1
OCR1B = pot_value + pot_value/4;

von Chrstian T. (christian_trohn)


Lesenswert?

Ja stimmt, das geht auch :)
Aber jetzt hab ich schon den ganzen Tag seit meinem Post mit 10 bit 
gerechnet und weiter Programmiert weils ja Funktioniert hat :(
Aber ich denk das macht wenig Unterschiede, jetzt wo ich schon an nem 16 
bit Ausgang hänge.

Vielen Dank nochmal für die Hilfe!!!

von ddink (Gast)


Angehängte Dateien:

Lesenswert?

War der Fehler gewesen. Danke!

Ich habe für den Timer in dem Modus eine Exceltabelle gemacht, die einem 
alle benötigten Werte berechnet. Wenn jmd interesse dran hat, hier ist 
sie. Wenn jmd einen findet, sagt bescheid.

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.