PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Software PWM



YaNnIk
21.08.2009, 18:39
Hi Leute..

Ich begebe mich gerade ans Software PWM..

Zuerst mal meinen Code :


$regfile = "m16def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 9600

Config Portc = Output
Config Timer1 = Pwm , Prescale = 8

Dim Y As Byte


Y = 0


Do

If Timer1 < Y
Then Portc.0 = 1
Else Portc.0 = 0

Incr Y

If Y = 255
Then Y = 0

Loop

End

Sobald ich diesen Code Compilieren will spuckt mir Bascom Folgende Fehler aus!

"Error : 1 Line : 19 Unknow Statement [IMER1 < Y] , in File ...." (Nein, "IMER1" ist kein Schreibfehler!)
"Error : 31 Line : 20 Invalid datatype [[0011] 0[THEN PORTC]] , in File ..."
"Error : 124 Line : 20 Loop expected , in File ..."


Aber leider versteh ich keinen einzigen Fehler..... ](*,)

Falls ihr mir hier nicht helfen könnt, könnt ihr mir einen funktionieren Code schreiben/erklären??!!?? Wäre euch sehr dankbar!


Mfg Yannik

for_ro
21.08.2009, 19:04
Die korrekte Syntax hierfür
If Timer1 < Y
Then Portc.0 = 1
Else Portc.0 = 0

wäre

If Timer1 < Y Then
Portc.0 = 1
Else
Portc.0 = 0
End If

Gruß

Rolf

Che Guevara
22.08.2009, 15:50
Hallo Yannik,

probier mal folgenden code:



'Software Pwm an Porta.0
'Frequenz = 200Hz

$regfile = "m32def.dat"
$crystal = 16000000


Config Timer1 = Timer , Prescale = 8
Timer1 = 55536
Enable Timer1
On Timer1 Isr_von_timer1

Dim Soft_pwm As Byte

Config Porta.0 = Output
Porta.0 = 0
Pwm_1 Alias Porta.0

Enable Interrupts


Do

!nop

Loop

End

Isr_von_timer1:
Timer1 = 55536
Incr Soft_pwm
If Soft_pwm = 255 Then Softpwm = 0
If Soft_pwm <= 127 Then
Pwm_1 = 1
Else
Pwm_1 = 0
End If
Return


Gruß
Chris

YaNnIk
22.08.2009, 16:33
Hmmm Leider funktiert der Code bei mir nicht richttig.. Bei mir Blink die LED nur im Sekundentakt ??!!??!! Bist du sicher, das der Code richtig ist?

for_ro
22.08.2009, 16:56
Würde ich jetzt so ungefähr erwarten.
Die Timer ISR wird 200 mal pro Sekunde aufgerufen. Also wird auch Soft_pwm ebenso oft erhöht. Nach 127 Aufrufen wird der Ausgang umgeschaltet. Beim Überlauf (nach weiteren 128 Aufrufen) dann wieder umgeschaltet.

Gruß

Rolf

Che Guevara
22.08.2009, 17:00
Oh, sorry. . habe eine Variable vergessen.
Hier der richtige code:



'Software Pwm an Porta.0
'Frequenz = 200Hz

$regfile = "m32def.dat"
$crystal = 16000000


Config Timer1 = Timer , Prescale = 8
Timer1 = 55536
Enable Timer1
On Timer1 Isr_von_timer1

Dim Soft_pwm As Byte
Dim Counter_pwm As Byte

Config Porta.0 = Output
Porta.0 = 0
Pwm_1 Alias Porta.0

Enable Interrupts


Do

Soft_pwm = 20 'Einstellen des Tastverhältnisses

Loop

End

Isr_von_timer1:
Timer1 = 55536
Incr Counter_pwm
If Counter_pwm = 255 Then Counter_pwm = 0
If Counter_pwm <= Soft_pwm Then
Pwm_1 = 1
Else
Pwm_1 = 0
End If
Return


Hoffe es funktioniert jetzt, kanns gerade nicht testen

Gruß
Chris

YaNnIk
22.08.2009, 18:37
Also das funktioniert auch nicht wirklich -.- Man kann noch seeeeeeeeeeeeehr das Blinken erkennen.. Auch den Prescal auf 1 zu setzen hat nur ein bisschen gebracht...

for_ro
22.08.2009, 18:37
Wenn du dann mal wirklich die Helligkeit der LED regeln willst, musst du allerdings die Timerfrequenz stark erhöhen. Im Moment kannst du über die Variable Soft_pwm die Led nur zwischen 1/200s und 1,27s einschalten und entsprechend umgekehrt lange aus. Die Wiederholfrequenz ist also etwa 0,8Hz.
Damit man kein Flimmern mehr erkennt, sollte die Wiederholfrequenz des ganzen Ablaufs mindestens 50 Hz sein. Dies musst du dann noch mit der gewünschten Auflösung des PWM multiplizieren. Bei 256 Schritten ergibt sich eine Überlauf Frequenz des Timers von 12800 Hz. Also muss der Timer alle 1250 Takte überlaufen. Ein 8-bit Timer würde vollkommen ausreichen, du kannst das aber auch mit dem 16-bit Timer machen.
Bei 16MHz geht das z.B. mit
Prescale 64 und
Load Timer1, 20
Da die ISR sehr häufig aufgerufen wird, würde ich dort absolut keine unnötigen Befehle machen. Die könnte dann so aussehen:
Isr_von_timer1:
Load Timer1, 20
Incr Counter_pwm
PWM_flag=1
Return

Und die Main Loop so
Do
'... evtl andere Befehle zum Berechnen des Tastverhältnisses (Wert von Soft_pwm)
If Pwm_flag=1 Then
Pwm_flag=0
If Counter_pwm < Soft_pwm Then
Pwm_1 = 1
Else
Pwm_1 = 0
End If
End If
Loop

Gruß

Rolf