PWM Signal wird nich 0V

tenor

Mitglied
30. Sep. 2012
169
0
16
44
Sprachen
  1. BascomAVR
Hallo!
für meine LED RGB Steuerung benötige ich 3 PWM Signale an meinem Atmega48.
Diese Signale gehen über einen 150Ohm Widerstand an das Gate eines N Channel logic Mosfet.
Source gegen Masse und bei Drain sitzt die LED, bzw. das LED Band gegen 12V.
Das funktioniert soweit auch.

Jetzt bin ich gerade am "Farben mischen" und habe festgestellt, das 2 PWM Signale nicht auf 0V gehen, obwohl das Register mit
0 geladen wurde!
Der Aufbau der 3 Signale ist identisch.
Hier der Code:
Code:
$regfile = "m48def.dat"
$crystal = 8000000

Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portd.1 , Rs = Portd.0
Config Lcd = 16 * 2                                         'configure lcd screen


Config Portc = Output                                       'LCD Display
'Config Portd = Output
Config Pind.5 = Output
Config Pind.6 = Output
Config Pinb.1 = Input
Config Pinb.2 = Output
Config Pind.3 = Output
Config Pinb.3 = Output
Config Pind.7 = Input
Config Pinb.6 = Input
Config Pinb.7 = Input
Config Pind.4 = Input
Config Pind.2 = Input

Dim Green As Byte , Red As Byte , Blue As Byte

Initlcd                                                     'init display again
Cursor On

Tccr0a = &B10100011
Tccr0b = &B00000010
Tccr1a = &B10100011
Tccr1b = &B00000010
Tccr2a = &B10100011
Tccr2b = &B00000010

Blue = 0
Green = 0
Red = 0

Cls

Main:
Cls

Do

Ocr0a = Red
Ocr1b = Blue
Ocr2b = Green
'Ocr2a = Pwm(5)
'Ocr0b = Pwm(2)
'Ocr1a = Pwm(3)

Debounce Pind.7 , 0 , Gren , Sub
Debounce Pind.4 , 0 , Grenminus , Sub
Debounce Pinb.6 , 0 , Rot , Sub
Debounce Pind.2 , 0 , Rotminus , Sub
Debounce Pinb.7 , 0 , Blau , Sub
Debounce Pinb.1 , 0 , Blauminus , Sub
                                                            ' calling sub convert

Loop
Blauminus:
If Blue = 0 Then Return
Blue = Blue - 1
Locate 1 , 10
Lcd Blue
Return

Rotminus:
If Red = 0 Then Return
Red = Red - 1
Locate 1 , 5
Lcd Red
Return

Grenminus:
If Green = 0 Then Return
Green = Green - 1
Locate 1 , 1
Lcd Green
Return

Blau:
Blue = Blue + 1
Locate 1 , 10
Lcd Blue
If Blue > 255 Then
   Blue = 0
   Cls
End If
Return

Rot:
Red = Red + 1
Locate 1 , 5
Lcd Red
If Red > 255 Then
   Red = 0
   Cls
End If

Return

Gren:
Green = Green + 1
Locate 1 , 1
Lcd Green
If Green > 255 Then
   Green = 0
   Cls
End If
Return

Hat jemand dazu einen Tip?
Das dritte Signal funktioniert wie es soll, beim drücken des Schalters wird das Signal eingeschaltet und dann jeweils inkrementiert.
Das Inkrementiere funktioniert bei den anderen auch bestens, nur starten diese nicht ganz bei 0, sondern ca. 0,2V.
 
Hallo tenor,

schau mal in das Datenblatt des Mikrocontrollers im Kapitel DC-Characteristics, genauer in der Tabelle die Zeile VOL. Ideal wären natürlich 0V für LOW, tatsächlich wird dies aber nicht erreicht. Die minimale Spannung ist auch abhängig vom Strom. Beim Schalten eines MOSFETs wird die Gate-Kapazität umgeladen, was den IO-Pin belastet. Warum allerdings der MOSFET bei 0,2V VGS anfängt ausreichend zu leiten, bzw. ein Kanal sich anders verhält als andere, kann ich im Moment nicht sagen.
Dass du bei zwei Kanälen ein Minimum von 0,2V hast, könnte auch an der Software liegen, mit Bascom kenne ich mich aber nicht so aus und kann dir hier nicht besonders helfen.

Dirk :ciao:
 
Danke!
Ich tippe sehr stark auf Software ;)
Wenn ich das Kabel vom Mosfet zum AVR trenne, dann geht die Lampe auch komplett aus, d.h.
der Mosfet sperrt.
Wenn ich die Kabel unter einander tausche, dann wandert der "Fehler".
OC1B ist hier der der sich gut verhält ;)
 
Hallo,

ich hab erstmal zwei laaange Komentare (#######) reingemacht damit man besser sieht wo die Hauptschleife ist. Beim ersten Drübersehen bin ich da nämlich ziemlich durcheinandergekommen :rolleyes:

Der Aufbau der 3 Signale ist identisch.
Hier der Code:
Code:
$regfile = "m48def.dat"
$crystal = 8000000

Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portd.1 , Rs = Portd.0
Config Lcd = 16 * 2                                         'configure lcd screen


Config Portc = Output                                       'LCD Display
'Config Portd = Output
Config Pind.5 = Output
Config Pind.6 = Output
Config Pinb.1 = Input
Config Pinb.2 = Output
Config Pind.3 = Output
Config Pinb.3 = Output
Config Pind.7 = Input
Config Pinb.6 = Input
Config Pinb.7 = Input
Config Pind.4 = Input
Config Pind.2 = Input

Dim Green As Byte , Red As Byte , Blue As Byte

Initlcd                                                     'init display again
Cursor On

Tccr0a = &B10100011
Tccr0b = &B00000010
Tccr1a = &B10100011
Tccr1b = &B00000010
Tccr2a = &B10100011
Tccr2b = &B00000010

Blue = 0
Green = 0
Red = 0

Cls

Main:
Cls

Do  ' [B]############ HAUPTSCHLEIFE ANFANG ##################[/B]

Ocr0a = Red
Ocr1b = Blue
Ocr2b = Green
'Ocr2a = Pwm(5)
'Ocr0b = Pwm(2)
'Ocr1a = Pwm(3)

Debounce Pind.7 , 0 , Gren , Sub
Debounce Pind.4 , 0 , Grenminus , Sub
Debounce Pinb.6 , 0 , Rot , Sub
Debounce Pind.2 , 0 , Rotminus , Sub
Debounce Pinb.7 , 0 , Blau , Sub
Debounce Pinb.1 , 0 , Blauminus , Sub
                                                            ' calling sub convert

Loop                 ' [B]############ HAUPTSCHLEIFE ENDE ##################[/B]




Blauminus:
If Blue = 0 Then Return
Blue = Blue - 1
Locate 1 , 10
Lcd Blue
Return



Rotminus:
If Red = 0 Then Return
Red = Red - 1
Locate 1 , 5
Lcd Red
Return



Grenminus:
If Green = 0 Then Return
Green = Green - 1
Locate 1 , 1
Lcd Green
Return



Blau:
Blue = Blue + 1
Locate 1 , 10
Lcd Blue
If Blue > 255 Then
   Blue = 0
   Cls
End If
Return



Rot:
Red = Red + 1
Locate 1 , 5
Lcd Red
If Red > 255 Then
   Red = 0
   Cls
End If
Return



Gren:
Green = Green + 1
Locate 1 , 1
Lcd Green
If Green > 255 Then
   Green = 0
   Cls
End If
Return

Hat jemand dazu einen Tip?

Hmmm ... irgendwie klappt das mit dem konzentrieren heute wohl nicht mehr :rolleyes: :vollkommenauf: :sleep:

Gruß
Dino
 
Hmmm ... irgendwie klappt das mit dem konzentrieren heute wohl nicht mehr :rolleyes: :vollkommenauf: :sleep:

:D Das Problem habe ich auch ... ich schaue morgen nochmal, falls sich zwischenzeitlich keine Lösung finden läßt.

Dirk :ciao:
 
Ja, dem Schließ ich mich an, ab aufs Sofa, morgen geht's weiter ;)
 
Vorweg: per PWM kannst Du so nicht auf "dauerhaft Gnd" kommen, da der Pin beim Überlauf gesetzt wird, aber erst einen Timertakt nach dem Compare-Match wieder gelöscht. Also wenn das entsprechende OC-Register 0 ist, wird der Pin bei TCNTx=1 gelöscht...
Aber nun zu:
...Der Aufbau der 3 Signale ist identisch...
Nein!
Du hast lediglich ähnlichen Registern dieselben Werte zugewiesen.
Timer 0 und 2 sind 8bit-Timer, Timer1 ist ein 16bit-Timer. Abgesehen davon sind die Timer auch unterschiedlich mächtig, dementsprechend gibts auch unterschiedliche Konfigurationsmöglichkeiten...
Du hast folgendes eingestellt:
Timer0:
WGM=3 -> Fast-PWM (single slope) bis 0xFF (8Bit)
OC-ModeA/B=2 -> non Inverting (clear on match, set on bottom)
CS=2 -> Prescaler=8, also effektive PWM-Frequenz von 1MHz

Timer2:
sollte dasselbe sein, die asynchrone Clock ist default aus

Timer1:
WGM=3 -> phasenkorrektes 10bit-PWM (dual slope bis 0x03FF)
OC-ModeA/B=2 -> OC-Pins sind Gnd <==> TCNT>OCR
CS=2 -> Prescaler=8, effektiv 1MHz

Ob das jetzt was mit Deinem Problem zu tun hat, hab ich noch nicht begrübelt...

Grüße
LotadaC
 
Besten Dank für den Hinweis!
Ich war eigentlich der Meinung das das so passt mit den Timern..
Die Helligkeit der einzelnen PWMs sind auch identisch, wenn ich alle 3 auf 255 setze, dann habe ich ein weißes Licht auf voller Helligkeit...
Nur der Offset passt nicht 100%, den wollte ich voher noch richtig stellen.

Der funktionierende OC1B ist demnach zugehörig zum 16 bit Timer und beide 8 bit PWMs passen nicht..
Scheint somit das du auf jeden Fall das Problem entdeckt hast.

0,2V ist aber schon ne Menge!
Das ist ja mehr als nur ein bit beim Überlauf gesetzt...

Hast du evtl. einen Verbesserungsvorschlag?
Wie bekomme ich 6 gleiche PWM Signale hier zum laufen?
 
Hab grad keine Zeit - kannst ja selbst mal im Datenblatt bei den 3 Timern die Tabellen bei "Register Descriptions" und so vergleichen. Du kannst auch Timer1 im FastPWM bis 8Bit fahren.
Genauso sollten die anderen beiden auch phasenkorrekten PWM können - einfach mal selbst das Datenblatt durchsehen...;)
 
hm, ich werde leider nicht schlau draus.
hat noch jemand einen Tip?
 
Was willst Du denn nun konkret einstellen, was geht nicht?

Ich vermute: Timer1 soll auch als single slope fastPWM bis 8bit (0xFF) laufen, mit Prescaler=8.
beide OutputCompareUnits sollen dabei non-inverting PWM sein...
Hast Du die Register entsprechend gesetzt? Welches Resultat?
 
Ich möchte 6 gleiche PWM Kanäle, die sich von 0 bis 255 einstellen lassen. (0-12V)
Bisher passt der offset halt nicht.
Beim OCR0a scheint es geholfen zu haben in den invertierenden Modus zu gehen, aber bei 255 sollte er halt wie die anderen auf 100% sein.

wie gesagt ich tue mich sehr schwer diesen registern..
 
Mach es uns doch mal bitte einfacher, und schreibe, was stimmt, und was nicht...
In Beitrag #1 hattest Du ein Programm gepostet.
In #7 hab ich auseinandergenommen, was Deine gesetzten Register eigentlich bewirken.
In #8 hast Du geantwortet, daß OC1B korrekt arbeitet, die beiden 8bit-Timer nicht.

Was ist mit OC1A? der sollte doch identisch zu OC1B laufen
Irgendwie paßt das aber nicht zu Deiner Angabe mit den 255 - top sollte ja 1024 sein, da kommst Du mit einem 8bit-Timer in Hardware nie hin, klar...
Hast Du Dir im Datenblatt mal die unterschiedlichen erzielbaren Waveform Generation Modes angesehen?

Du brauchst alle 3 Timer im 8-bit-mode (also der 16bitter muß mit top=0x00FF laufen). Ob dual oder single slope sollte eigentlich egal sein - nur eben bei allen drei Timern das gleiche einstellen (also denselben Mode - das ist nicht unbedingt dieselbe Nummer).
 
Hallo Lota,
hier meine aktuellen Timer Einstellungen:
Code:
Tccr0a = &B10100001
Tccr0b = &B00000010
Tccr1a = &B10100001
Tccr1b = &B00000001
Tccr2a = &B10100001
Tccr2b = &B00000010

Das ursprüngliche Problem das ich hatte das die PWM Signale nicht auf 0V gingen, scheint durch den invertierenden Modus behoben zu sein.
2 der Kanäle, (Oc1A und B) scheinen aber bei einem Wert von 255 nicht auf 100% zu dimmen.
Mir ist schon klar das ich aus keinem 8 Bit Timer einen 16 Bit Timer machen kann, hatte aber gehofft das das andersrum geht.

Ich habe den Modus angepasst, so dass ich phasen corrected 8 bit PWM nutze. Auf den ersten Blick scheint das jetzt zu passen.
Dauert aber etwas bis ich auf dem Testboard die Kanäle durch hab.

Besten Dank erstmal!
 
Hmm...
Ok, Timer1 sollte jetzt (auch) im phasenkorrekten 8-Bit-PWM laufen. Der Timer zählt zwischen 0 und 255 hin und her - wenn er größer als das entsprechende OCR wird, geht der korrespondierende Pin low, wird er kleiner, geht der korrespondierende Pin high. Heißt: je größer OCR, desto länger die High-Zeit.
Das ist dasselbe, wie bei den anderen beiden Timern. Der einzige Unterschied, den ich noch sehe, ist die PWM-Frequenz: Timer1 arbeitet mit Prescaler 8, Timer 0 und 2 mit Prescaler 1.
 
Hallo,

Das ursprüngliche Problem das ich hatte das die PWM Signale nicht auf 0V gingen, scheint durch den invertierenden Modus behoben zu sein.
2 der Kanäle, (Oc1A und B) scheinen aber bei einem Wert von 255 nicht auf 100% zu dimmen.
ach ... :rolleyes: ... du hast das Problem nur invertiert. Nun ist der Fehler nicht mehr im unteren Bereich sondern im oberen. Verschlimmbessert :p Du mußt schon die Wurzel des Übels finden um den Fehler zu beseitigen. Eine Invertierung invertiert lediglich das Ausgangssignal. Die Impulsform bleibt aber und damit auch dein Problem. Nur eben an anderer Stelle.

Gruß
Dino
 
hm, das stimmt!
Das fällt so ja nur im unteren Bereich auf. Könnte aber später beim mischen Probleme geben...

Hab jetzt gerade erstmal angefangen alles neu auf zu löten.
Sollte vielleicht doch mal an Platinen selber ätzen nachdenken ;)
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)