Donnerstag, 9. Februar 2012, 00:30 UTC+1

Sie sind nicht angemeldet.

  • Anmelden
  • Registrieren

toschido

LedStyles Newbie

1

Dienstag, 9. März 2010, 13:20

Timingprobleme mit Soft PWM am Meg32 mit 16Mhz

Hallo,

ich versuche auf dem Mega32 mit 16Mhz eine Software PWM zu bauen.
Wenn ich eine Taktfrequenz von ca. 122Hz erzeugen will, dann sollte das
doch mit einem prescaler von 256 zu machen sein ?!

Das erzeugt aber nur ein wirres hektisches blinken, <Erst mit einem
prescaler von 1 ist soetwas wie dimmen zu erkennen.

Was mach ich da falsch ??


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

$lib "mcsbyte.lbx"


Dim Pwm_stufen As Byte
Dim Pwm_wert As Byte
Dim Pwm_zaehler As Byte


Config Portd.4 = Output
Config Portd.5 = Output

Led1 Alias Portd.5
Led2 Alias Portd.4

Const An = 1
Const Aus = 0

Pwm_stufen = 254
Pwm_wert = 0
Pwm_zaehler = 0


'-------- Timer initialisieren ---

Config Timer0 = Timer , Prescale = 1

Enable Timer0
Enable Interrupts

On Timer0 timer0_ueberlauf


Do

' no loop

Loop

End



timer0_ueberlauf:


If Pwm_zaehler >= Pwm_stufen Then
Pwm_zaehler = 0
Incr Pwm_wert
Else
Incr Pwm_zaehler

End If

If Pwm_wert >= Pwm_stufen Then
Pwm_wert = 20
End If


If Pwm_zaehler < Pwm_wert Then
Led2 = An
Else
Led2 = Aus
End If


Return<IMG alt="" src="http://bascom-forum.de/Themes/dilbermc/images/icons/modify_inline.gif" align="right" />
  • Zum Seitenanfang

naeschd

Senior LedStyler

Beiträge: 284

Wohnort: Heilbronn

Beruf: selbstverständlich

2

Dienstag, 9. März 2010, 15:23

Servus!

also meiner Meinung nach ist da ein logischer Fehler in deinem Code drin... Wenn du dir mal den Verlauf deiner Zählerzustände mal aufzeichnest merkst du recht schnell, dass das nicht funktionieren kann.... Da kommt auf jeden Fall keine konstanter Duty Cycle raus (Ich vermute, dass du das bei deinem Code erreichen willst...)

Versuch mal das:

If Pwm_zaehler < Pwm_wert Then
Led2 = An
Else
Led2 = Aus
End If

durch das zu ersetzen:

If Pwm_wert < 20 Then
Led2 = An
Else
Led2 = Aus
End If

Da is deine Frequenz bei ca 300Hz...
Bei Fragen bzgl. ULC einfach hier ins Forum oder auch gerne per PN an mich...
  • Zum Seitenanfang

turi

LedStyles Genie

Beiträge: 1 846

Wohnort: Leipzig

3

Dienstag, 9. März 2010, 17:06

Ich kenne mich da in Bascom nicht so genau aus, aber habe SoftPWM im MoodLight-Projekt (Lobby) realisiert, allerdings in C. Ich habe da allerdings fertige Bibliotheken eingesetzt, welche die Funktionalität sehr gut umgesetzt haben. Dann kann man sich auf die eigentliche Anwendung konzentrieren.
  • Zum Seitenanfang

feigling

Junior LedStyler

4

Dienstag, 9. März 2010, 17:18

Ich habe da allerdings fertige Bibliotheken eingesetzt, welche die Funktionalität sehr gut umgesetzt haben
Magst du den Namen der Bibliothek vielleicht nennen? Das wäre klasse :) . Ich denke mal, da kann vielleicht auch der Threadersteller von profitieren (sollte er ein wenig C können bzw den C Code auf Bascom ableiten können.
  • Zum Seitenanfang

toschido

LedStyles Newbie

5

Dienstag, 9. März 2010, 17:30


Ich habe da allerdings fertige Bibliotheken eingesetzt, welche die Funktionalität sehr gut umgesetzt haben
Magst du den Namen der Bibliothek vielleicht nennen? Das wäre klasse :) . Ich denke mal, da kann vielleicht auch der Threadersteller von profitieren (sollte er ein wenig C können bzw den C Code auf Bascom ableiten können.
Ja, er kann ein wenig :-)
  • Zum Seitenanfang

dgoersch

Silver LedStyler

Beiträge: 4 218

Wohnort: Viersen

Beruf: Fachinformatiker / Entwickler Linux/Asterisk

6

Dienstag, 9. März 2010, 17:34

Eine extrem simple Soft-PWM ohne Beschränkung der Frequenz (was die CPU/der Timer grad hergibt) nutze ich bei meinem allerersten Projekt, der Wolke für meinen Sohn: http://projekte.dgoersch.info/avr/wolke#firmware
  • Zum Seitenanfang

chris16

Senior LedStyler

Beiträge: 301

Wohnort: Düsseldorf

7

Dienstag, 9. März 2010, 18:15

Hallo toschido,
hab mal etwas in meiner Codekiste gewühlt und etwas für eine RGB Ansteuerung gefunden,ist zwar für einen Atmega16 aber das läßt sich ja mit wenigen klicks abändern.Vielleicht kannst Du daran Deinen Code anpassen. ;)
Easymod RGB.zip
Gruss aus NRW
Chris
  • Zum Seitenanfang

toschido

LedStyles Newbie

8

Dienstag, 9. März 2010, 19:30

@Chris16
@dgoersch

Erst einmal vielen Dank. Werde mir die Sachen einmal ansehen
  • Zum Seitenanfang

Pesi

Golden LedStyler

Beiträge: 6 322

Wohnort: Home of the Pope

Beruf: Mischling

9

Dienstag, 9. März 2010, 20:52

Wenn ich eine Taktfrequenz von ca. 122Hz erzeugen will, dann sollte das
doch mit einem prescaler von 256 zu machen sein ?!

Das erzeugt aber nur ein wirres hektisches blinken, <Erst mit einem
prescaler von 1 ist soetwas wie dimmen zu erkennen.
Das ist schon richtig so - der Timer läuft ja immer bis 255, dann gibt's nen Timer Overflow, und die Routine wird ausgelöst. In der Routine zählst Du den PWM-Zähler hoch, wieder bis 255 (normalerweise, k.A. warum's bei Dir nur bis 254 geht...?!?)

Bei nem Prescaler von 256 wird ja der Timer nur alle 256 Takte um 1 weitergezählt, also erst alle 65.536 Takte ein Timer Overflow ausgelöst - das mal 255 (einmal Dein PWM-Zähler durch von 0 bis 254) macht dann eben ne PWM-Frequenz von ca. 1 Hz, also "blinken" - bei nem Prescaler von 1 hast Du dann ca. 244 Hz...

PWM ist ja immer nur einen Zähler durchzählen, mit dem Helligkeitswert vergleichen, und dann je nach drunter oder drüber an oder aus... Du hast das ja im Prinzip schon richtig gemacht, naeschd hat sich das nicht genau angesehen, das ist schon ein konstanter Duty-Cycle, Du fadest halt in der PWM-Routine gleich die LED mit hoch - normalerweise macht man das ausserhalb, entweder mit warteschleifen oder in nem extra Timer...

Die reine PWM-Routine wäre dann eben so:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
timer0_ueberlauf:

If Pwm_zaehler >= Pwm_stufen Then
   Pwm_zaehler = 0
Else
   Incr Pwm_zaehler
End If

If Pwm_zaehler < Pwm_wert Then
   Led2 = An
Else
   Led2 = Aus
End If

Return
Das ist schon alles! - in Assembler spart man sich das Vergleichen des PWM-Zählers, da macht man nur "inc", weil nach 255 kommt ja eh' automatisch wieder 0 - ausser natürlich, man will ne kleinere Auflösung... aber k.A., ob das in Bascom auch so ist...? - wenn ja, und wenn Du alle 255 Stufen haben willst, dann kannst Du Dir diesen Vergleich auch noch sparen, je kürzer so ne ISR ist, desto besser...
It's only light - but we like it!

Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!
  • Zum Seitenanfang

turi

LedStyles Genie

Beiträge: 1 846

Wohnort: Leipzig

10

Dienstag, 9. März 2010, 21:40

Magst du den Namen der Bibliothek vielleicht nennen? Das wäre klasse :) . Ich denke mal, da kann vielleicht auch der Threadersteller von profitieren (sollte er ein wenig C können bzw den C Code auf Bascom ableiten können.
Na ich dachte, ihr lest auch einfach mal den Artikel in der Lobby ?( Da steht es doch drin:

Zitat von »turi«

Da es sich bei 2x2 RGB-Pixeln nur um 12 Kanäle handelt und das Modul auch einzeln betrieben werden soll', habe ich mich für Software-PWM entschieden. In Mikrocontroller.net gibt es einen sehr guten Artikel, der verschiedene Varianten beschreibt und dabei in Hinblick auf die Prozessor-Auslastung Optimierungen vornimmt. Leider wird dabei maximal ein Port angesprochen, also nicht ausreichend Kanäle. Für die Erweiterung fehlte mir etwas die Ruhe, so dass ich nach ein wenig Suchen das passende (darauf aufbauende) gefunden habe: http://www.the-powl.de/knowhow/softpwm/index.php.
  • Zum Seitenanfang

feigling

Junior LedStyler

11

Mittwoch, 10. März 2010, 00:17

Na ich dachte, ihr lest auch einfach mal den Artikel in der Lobby ?( Da steht es doch drin:
Whops sorry, habe "MoodLight-Projekt (Lobby)" komplett überlesen bzw. das Lobby nicht gesehen.
  • Zum Seitenanfang

Pesi

Golden LedStyler

Beiträge: 6 322

Wohnort: Home of the Pope

Beruf: Mischling

12

Samstag, 13. März 2010, 19:03

Und, Toschido, schon ausprobiert....? ;)

Zu dem hier:
in Assembler spart man sich das Vergleichen des PWM-Zählers, da macht man nur "inc", weil nach 255 kommt ja eh' automatisch wieder 0 - ausser natürlich, man will ne kleinere Auflösung... aber k.A., ob das in Bascom auch so ist...? - wenn ja, und wenn Du alle 255 Stufen haben willst, dann kannst Du Dir diesen Vergleich auch noch sparen, je kürzer so ne ISR ist, desto besser...
noch ein Update: ich habe mir die von Turi verlinkte Seite noch mal genauer durchgelesen (den Absatz über den Wertebereich), und noch mal nachgedacht: eigentlich ist das ja falsch, mit dem Zähler einfach überlaufen lassen, der sollte schon bei 254 wieder auf 0 gesetzt werden - aus folgendem Grund:

bei mir läuft das so, dass die Bits für die LEDs in einem temp-Byte erst mal gesetzt werden, dann wird verglichen, ist der Zähler kleiner als der LED-Wert, wird weitergesprungen, ansonsten das Bit gelöscht, also LED aus.

Das ist Anfangs auch richtig: hat die LED den Wert "0", dann ist bei PWM-Zähler "0" dieser nicht kleiner als 0, also wird das Bit gelöscht, die LED bleibt gleich aus - ne LED, die den Wert "1" hat, wird beim nächsten Durchgang gelöscht, also ist sie 1 Segment lang an, passt - und so weiter...

nur bei 255 gibt's ein kleines Problem: PWM-Zähler 255 ist *nicht* kleiner als LED-Wert 255, also wird die LED ausgemacht - und erst beim nächsten Durchgang (PWM-Zähler = 0) wieder an - sie ist also immer für ein Segment lang aus, obwohl sie eigentlich *dauernd* an sein sollte (100%).

Daher einfach den Zähler nur bis 254 zählen lassen, dann ist er immer kleiner als der Maximal-Wert 255, die LEDs mit 255 bleiben also an - die mit 254 werden ja bei Zähler 254 gelöscht, anschließend (beim nächsten Aufruf) kommt wieder 0, sie sind also für 1/255 lang aus, passt!

Also: sorry für die Verwirrung, jetzt ist mir auch klar, warum Du nur bis 254 zählst, diese kleine Unstimmigkeit am Ende des PWM-Zyklus (bei mir) hatte ich immer übersehen! (fällt ja auch nicht auf, ob die LED nun 255/255 oder 255/256 leuchtet... :D)

EDIT: Noch mal Verwirrung - es muss natürlich bis 255 gehen, das letzte Segment geht ja von 254 bis 255 - also den Zähler dann auf 0 setzen, wenn er 255 erreicht hat - da sind wir beide jeweils einen Tick daneben gelegen, ich einen zu viel, Du einen zu wenig... ;)

Ich finde es Sch***ade, dass es in Assembler nur den Befehl cpse (Compare, Skip if Equal) gibt, aber nicht "Compare, Skip if not Equal" - da könnte man das mit dem Zähler ganz einfach machen, statt

Quellcode

1
2
3
4
5
cpi PWM_Zaehler, 255
brlo weiter
clr PWM_Zaehler

weiter:

würde man schreiben (wenn der Befehl cpsne hiesse):

Quellcode

1
2
cpsne PWM_Zaehler, 255
clr PWM_Zaehler

und hätte schon wieder eine Zeile/einen Takt gespart - so was in der Art könnte ich öfter gut brauchen, k.A., warum die das nicht implementiert haben.... ?(
It's only light - but we like it!

Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Pesi« (14. März 2010, 14:38)

  • Zum Seitenanfang