Forum: Mikrocontroller und Digitale Elektronik Software PWM mit Bascom


von Dennis B. (danrulz81)


Lesenswert?

Hallo zusammen,

ich überlege gerade, wie ich ne Software PWM für meinen mega8515L mit 
BASCOM realisiere. Klingt das so geschickt:

Wenn Timerwert = 100 dann die LED einschalten, ansonsten aus

Oder sollte ich lieber den Timer bei sagen wir 155 starten lassen, und 
beim Interrupt die LED einschalten, und wenn der Interrupt wieder weg 
ist, ausschalten?

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Dennis Brenzel schrieb:
> Hallo zusammen,
>
> ich überlege gerade, wie ich ne Software PWM für meinen mega8515L mit
> BASCOM realisiere. Klingt das so geschickt:
>
> Wenn Timerwert = 100 dann die LED einschalten, ansonsten aus

Nö, denn dann kannst Du auf den Interrupt verzichten und den Port direkt 
von der Compare-Einheit des Timers schalten lassen, also Hardware-PWM.

>
> Oder sollte ich lieber den Timer bei sagen wir 155 starten lassen, und
> beim Interrupt die LED einschalten, und wenn der Interrupt wieder weg
> ist, ausschalten?

Auch das ist es nicht...

Es gibt verschiedene Varianten der Soft-PWM, eine (die leicht 
verständlichere) funktioniert so:

Ein Timer generiert in regelmäßigen Zeitabständen Interrupts. In diesem 
Interrupt wird:

- ein PWM-Zähler hochgezählt
- bei Erreichen des PWM-Zählumfangs wird der PWM-Zähler auf 0 gesetzt 
und
  der Portpin eingeschaltet
- bei Erreichen des Tastgrades (PWM-Wertes) wird der Portpin wieder
  ausgeschaltet
- Dies kann für mehrere PWM-Kanäle mit eigenen PWM-Werten und Portpins
  quasi gleichzeitig erfolgen.

In Bascom hast Du allerdings eine schwerwiegende Einschränkung: Bei 
jedem Interrupt werden alle 32 Register auf Stack gesichert, was 128 
CPU-Takte zusätzlich kostet. Dies reduziert die erreichbare 
Interruptfrequenz drastisch und begrenzt die erreichbare PWM-Frequenz. 
So richtig flimmerfrei wird die PWM also kaum werden.

von Dennis B. (danrulz81)


Lesenswert?

> - bei Erreichen des Tastgrades (PWM-Wertes) wird der Portpin wieder
>   ausgeschaltet

Das hab ich irgendwie nicht ganz verstanden. Der PWM - Zähler zählt 
dabei nochmals auf den eingestellten Wert hoch und schaltet dann wieder 
zurück, oder was ist mit Tastgrad gemeint.

von Dennis B. (danrulz81)


Lesenswert?

Ah, jetzt hab ich es glaube ich verstanden. Der Timer löst sagen wir bei 
200 einen Interrupt aus, zählt aber weiter bis 255. Bei diesem Interrupt 
schaltet er eine LED ein. Hat der Timer 255 zählt er wieder zurück auf 
0. Wenn er die 200 unterschreitet, löst er wieder einen Interrupt aus, 
der die LED dann ausschaltet. Wobei ich beim nächsten Problem wäre:
Wie lass ich nen Timer rückwärts laufen, und wie sag ich dem Timer dann, 
welchen Interrupt er auslösen soll?

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Der PWM-Zähler zählt von 0 bis zum PWM-Zählumfang, und zwar bei jedem 
Timer-Interrupt nur einen Schritt.

Bei Erreichen des Zählumfangs wird er wieder auf 0 gesetzt. Gleichzeitig 
werden alle PWM-Kanäle auf H-Pegel gesetzt (eingeschaltet).

In jedem Timer-Interrupt wird der PWM-Zähler mit den PWM-Werten 
(Sollwert Tastgrad) aller Kanäle verglichen und bei Gleichstand der 
entsprechende PWM-Kanal ausgeschaltet.

Bei dieser Art der Software-PWM beginnen alle Kanäle zum gleichen 
Zeitpunkt mit dem Impuls, was eine impulsförmige Gesamtbelastung der 
Stromversorgung bewirkt. Es gibt aber auch eine andere Art der 
Software-PWM, die diesen Nachteil nicht hat. Sie braucht dafür aber für 
jeden Kanal einen eigenen PWM-Zähler. Diese Methode ist auch hier 
irgendwo im Forum beschrieben.
<such...> Hier geht's weiter:
Beitrag "Re: Software PWM auf 8 Kanälen"

Unter Tastgrad verstehe ich das Verhältnis Impulsdauer zu Periode in 
Prozent oder als Bruch.

von Dennis B. (danrulz81)


Lesenswert?

Das Problem wird für mich sein, das ganze auf BASCOM zu portieren, wie 
du ja schon beschrieben hast. Und wenns dann noch in C geschrieben ist, 
verstehe ich leider nur Bahnhof. Assembler versteh ich noch 
einigermaßen, wobei das auch schon wieder 8 Jahre her ist, und das war 
noch auf Siemens µC's. Ich danke dir auf jedenfall, ich werde versuchen 
mich da durch zu kauen.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Dennis Brenzel schrieb:
> Ah, jetzt hab ich es glaube ich verstanden. Der Timer löst sagen wir bei
> 200 einen Interrupt aus, zählt aber weiter bis 255. Bei diesem Interrupt
> schaltet er eine LED ein. Hat der Timer 255 zählt er wieder zurück auf
> 0. Wenn er die 200 unterschreitet, löst er wieder einen Interrupt aus,
> der die LED dann ausschaltet.

Nein, das Wäre Hardware-PWM im Phase-correct-Mode....

> Wobei ich beim nächsten Problem wäre:
> Wie lass ich nen Timer rückwärts laufen,

Gar nicht, das geht nur bei Hardware-PWM im Phase-correct-Mode.

> und wie sag ich dem Timer dann,
> welchen Interrupt er auslösen soll?

Die Frage erübrigt sich im speziellen Fall, war sie allgemein gemeint, 
so verweise ich auf das Kapitel Timer im Datenblatt des verwendeten 
AVRs. Auch das Benutzen von Bascom befreit nicht vom Lesen des 
Datenblattes. ;-)

Software-PWM wird durch einen Software-Timer (eine stinknormale 
Zählvariable) gesteuert. Der Timer mit seinem Interrupt sorgt nur dafür, 
dass diese Zählvariable in exakt gleichen Zeitabständen hochgezählt 
wird. Welchen Timer-Interrupt und Timer-Modus man nutzt, kommt darauf 
an, was der Timer sonst noch erledigen soll. Soll er nichts weiter als 
Software-PWM erledigen, nimmt man den Compare-Interrupt im CTC-Modus, 
denn der erübrigt Preload oder Aufaddieren des Intervalls auf das 
Compare-Register.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

Dennis Brenzel schrieb:
> Das Problem wird für mich sein, das ganze auf BASCOM zu portieren, wie
> du ja schon beschrieben hast.

Bascom ist für schnelle Folge von Interrupts absolut ungeeignet, weil es 
durch die Sicherung aller (also auch der unbenutzten) Register auf Stack 
zuviel wertvolle Rechenzeit vertrödelt. Es lohnt sich also nicht, Zeit 
dafür zu investieren. In der Zeit, bis Du merkst, dass es zu langsam 
wird, bist Du in ASM zehnmal fertig.

> Und wenns dann noch in C geschrieben ist,
> verstehe ich leider nur Bahnhof.

Das geht mir nicht besser.

> Assembler versteh ich noch
> einigermaßen, wobei das auch schon wieder 8 Jahre her ist, und das war
> noch auf Siemens µC's.

Naja, jede Architektur hat ihren eigenen Assembler, abstrahiert gesehen 
ist zwar alles ähnlich, die details unterscheiden sich aber erheblich. 
Es lohnt sich aber, mit Hilfe von ASM die Architektur des Controllers 
kennen zu lernen.

> Ich danke dir auf jedenfall, ich werde versuchen
> mich da durch zu kauen.

Viel Erfolg

von Dennis B. (danrulz81)


Lesenswert?

So, ich hab bis heute versucht, was Gescheites hinzubekommen, aber wie 
ihr seht, komm ich nicht weiter. Hier mein Code:
1
$regfile = "m8515.dat"
2
$crystal = 8390000
3
Dim A As Integer
4
Dim B As Integer
5
6
Config Timer0 = Timer , Prescale = 64
7
8
On Timer0 Timer0_isr
9
10
Config Portc = Output
11
Portc = 255
12
B = 120
13
A = 0
14
Enable Timer0
15
Enable Interrupts
16
Portc.1 = 0
17
18
Do
19
Loop
20
21
Timer0_isr:
22
Incr A                                                      'A eins hoch zählen
23
If A = 200 Then
24
Portc.0 = 0                                                 'Wenn A 200 ist dann portc.0 ein
25
A = 0
26
End If                                                      'A wieder nullen
27
If A = B Then                                               'Wenn A 120 ist dann
28
Portc.0 = 1                                                 'Portc.0 aus
29
A = 0                                                       'A wieder nullen
30
endif
31
Return

Ich weiß, das A nie die 200 erreichen wird, da sie vorher von den 120 
abgefangen wird, aber irgendwie steh ich momentan aufm Schlauch. Könnte 
mir jemand einen Wink mit der Blockhütte geben?

von AVRuser (Gast)


Lesenswert?

Hallo,

> If A = B Then                                               'Wenn A 120 ist
> Portc.0 = 1                                                 'Portc.0 aus
>> A = 0                                                      'A wieder 0
>>endif
>Return

In diesem Fall darf A NICHT auf Null gesetzt werden. Dann ist es soweit 
korrekt.

Den Befehl "endif" gibt es in BASCOM nicht ...

Wenn ich richtig gerechnet habe, wird die Timer-ISR alle 1,9ms 
aufgerufen.

> $crystal = 8390000

Was ist das für eine komische Frequenz?

von Dennis B. (danrulz81)


Lesenswert?

AVRuser schrieb:

> Den Befehl "endif" gibt es in BASCOM nicht ...

Ohne bekomm ich einen Fehler.

> Wenn ich richtig gerechnet habe, wird die Timer-ISR alle 1,9ms
> aufgerufen.
>
>> $crystal = 8390000
>
> Was ist das für eine komische Frequenz?

Die hab ich mit nem Frequenzzähler ermittelt. Pin toggeln in ASM und die 
Befehle umgerechnet. ist aber auch nur ungefähr.

von r-u (Gast)


Lesenswert?

wenn Du aus A und B Bytes machst statt Interger, kannst Du Deine ISR 
extrem vereinfachen, indem Du Dir den "Überlauf" zunutze machst 
(255+1=0):

Timer0_isr:
   Incr A
   if A > B then PortC.0=0 else PortC.0=1 'oder auch andersrum
return

PS: Das Speichern der Register beim ISR-Aufruf wird hier (prescaler 64) 
kaum eine Rolle spielen, man kann es aber mit Parameter NOSAVE 
verhindern.

von Dennis B. (danrulz81)


Lesenswert?

> PS: Das Speichern der Register beim ISR-Aufruf wird hier (prescaler 64)
> kaum eine Rolle spielen, man kann es aber mit Parameter NOSAVE
> verhindern.

Wo trag ich den ein?

von Weingut P. (weinbauer)


Lesenswert?

gibt aber auch nen Befehl der u.U. dafür passen würde ...

SERVO

von Dennis B. (danrulz81)


Lesenswert?

Vor allem fällt mir ein, dass ich dass dann ja für jedes Register 
explizit machen muss, welches ich nicht speichern möchte, oder hab ich 
das falsch verstanden?

von r-u (Gast)


Lesenswert?

Handbuch lesen hilft - beides steht in der Hilfe zu "ON INTERRUPT"

von Dennis B. (danrulz81)


Lesenswert?

Also werden alle nicht gespeichert, so hab ich es verstanden:
1
When you specify NOSAVE, no registers are saved and restored in 
2
the interrupt routine. So when you use this option make sure to save 
3
and restore all used registers.

von Karl H. (kbuchegg)


Lesenswert?

Dennis Brenzel schrieb:
> Also werden alle nicht gespeichert,

Etwas unglücklich ausgedrückt.

no registers                         kein Register, kein einziges

are saved                            wird gesichert

and restored                         und wieder hergestellt

....                                 daher

when you use                         wenn sie das benutzen

make sure                            müssen sie sicherstellen

to save and restore                  alle benutzten Register selbst
all used registers                   zu sichern und wieder herzustellen



Wenn dir das jetzt erst mal nichts sagt, dann ist es besser du benutzt 
diese Möglichkeit erst mal nicht. Und nein, mit Registern sind keine 
Variablen gemeint, sondern die echten CPU-Register. Man muss also den 
Assembler Output studieren um festzustellen, welche davon vom Compiler 
in der ISR benutzt werden.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

> Man muss also den
> Assembler Output studieren um festzustellen, welche davon vom Compiler
> in der ISR benutzt werden.

Man benutzt aber Bascom, um genau das (sich mit Assembler befassen) zu 
vermeiden.

Und man hat auch kein Interesse daran, mal selbst die Nase in eine Doku 
(Bascom-Hilfe, Controller-Datenblatt) zu stecken, es ist ja viel 
bequemer, sich alles zusammenzufragen und hinterher doch nicht 
selbstständig denken zu können.

Ohne Verständnis der Architektur ist es (auch in einer Hochsprache) 
nicht möglich, halbwegs effiziente Programme zu schreiben. Und 
Software-PWM (auf mehreren Kanälen, denn sonst könnte man ja 
Hardware-PWM nutzen) verlangt nunmal halbwegs effiziente Programmierung, 
sonst wird es einfach zu langsam.

von Dennis B. (danrulz81)


Lesenswert?

> Also werden alle nicht gespeichert
Damit meinte ich kein Register, das mit den Variablen war mir klar.

> Und man hat auch kein Interesse daran, mal selbst die Nase in eine Doku
> (Bascom-Hilfe, Controller-Datenblatt) zu stecken, es ist ja viel
> bequemer, sich alles zusammenzufragen und hinterher doch nicht
> selbstständig denken zu können

Das ist deine Meinung. Nur wenn ich auf Arbeit bin (Die im Übrigen 
nichts mit µC's zu tun hat), kann ich schlecht die Bascom Hilfe bemühen, 
geschweige denn ein Datenblatt lesen.

von Kluchscheißernder N. (kluchscheisser)


Lesenswert?

> Nur wenn ich auf Arbeit bin (Die im Übrigen
> nichts mit µC's zu tun hat), kann ich schlecht die Bascom Hilfe bemühen,
> geschweige denn ein Datenblatt lesen.

Dann solltest Du Dich auch besser um Deine Arbeit kümmern und nicht dem 
Chef Deine Arbeitszeit stehlen... ;-)

MfG

von Paul Baumann (Gast)


Lesenswert?

Vielleicht hilft Dir das:
Beitrag "Software PWM Bascom"

MfG Paul

von Dennis B. (danrulz81)


Lesenswert?

Kluchscheißender Consulter schrieb:

> Dann solltest Du Dich auch besser um Deine Arbeit kümmern und nicht dem
> Chef Deine Arbeitszeit stehlen... ;-)

:P

Paul Baumann (Gast) schrieb:
> Vielleicht hilft Dir das:
> Beitrag "Software PWM Bascom"

Den hatte ich auch schon entdeckt, nur irgendwie war das für den Anfang 
doch etwas verwirrend und hatte leider nicht weiter geholfen. Danke 
trotzdem. Jetzt muss ich das nur noch auf die anderen LEDs konvertieren, 
damit ich mein "fadendes" Lauflicht habe.

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.