mikrocontroller.net

Forum: Projekte & Code AVR: Fast-PWM (BAM) 12 Bit für 8 Kanäle


Autor: Peter D. (peda)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Anbei mal meine Version der 8 * 12Bit BAM komplett als Knight Rider.
Bei 8MHz CPU-Takt ergibt sich eine PWM von 2kHz.
Verschiedene PWM- und Dimmstufen kann man in der "main.h" ausprobieren.

Benutzt wird ein 16Bit Timer mit 2 Compare-Interrupts.
Für 8 LEDs braucht man ja eh mindestens einen ATtiny24.
Eine Änderung auf >12 Bit oder 16 Ausgänge sollte kein Problem sein.
Bei 16 Ausgängen ist die Bitzeit natürlich 2 Zyklen.

Der Interrupthandler wurde auf den GAS umgeschrieben, was nicht so 
schwer war. Auch werden alle Register gesichert, so daß es keine 
Probleme mit den C-Routinen gibt. Damit lassen sich alle nicht 
zeitkritischen Routinen bequem in C schreiben.
Die unterschiedliche Laufzeit der beiden Interrupts bis zur Portausgabe 
wird im OCR1BL-Wert korrigiert.

Die Umwandlung der PWM-Werte in die Ausgabedaten erfordert ein 
Umsortieren von quer nach längs. Das wird mit Bitbefehlen gemacht (SBRS 
+ OR). Der Compiler hat das auch sofort gemerkt und alle Variablen in 
Register gehalten. Dadurch ist der Code klein und sauschnell.
Die Polarität der LEDs ist per Define einstellbar.

Die Umwandlung der Helligkeitsstufen in PWM-Werte erfolgt über eine 
Tabelle.


Anmerkungen:

Der Latenzausgleich umfaßt nur 3 Zyklen, es sind also keine anderen 
Interrupts erlaubt. Man könnte Interrupts in der letzten Bitzeit 
erlauben, dann sind ~2000 Zyklen bis zum nächsten PWM-Interrupt Zeit.

Das Einschreiben der neuen PWM-Daten ist nicht interruptfest. Erfolgt 
eine Änderung von 2047 auf 2048 oder umgekehrt, kann es flackern.
Falls das stört, muß man das Ändern mit der letzten Bitzeit 
synchronisieren. Z.B. wartet man in der Routine, bis TCNT1 größer als 
die letzte Bitzeit und noch genügend Zeit zum Laden vor dem nächsten 
Zyklus ist.

Die 2kHz mögen viel klingen, sind es aber nicht unbedingt.
Die LEDs des STK500 sind klein und punktförmig, bewegt man die Augen, 
ist bei nur 100Hz ein deutliches Flackern zu sehen.
Mit 2kHz ist man also auf der sicheren Seite, die PWM sieht quasi wie 
Gleichstrom aus.

: Bearbeitet durch User
Autor: Masl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich kann hier auf Arbeit das Zip grad nicht downloaden.
Kannst du vielleicht sagen wieviele Cycles die ISR braucht?

Autor: Info (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert

Autor: Marc V. (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Anbei mal meine Version der 8 * 12Bit BAM komplett als Knight Rider.
> Bei 8MHz CPU-Takt ergibt sich eine PWM von 2kHz.

 Entschuldige wenn ich da etwas Falsch verstehe, aber...
 BAM mit 2KHz wurde heissen, dass bit0 weniger als 16Cy hat -
 mit jump, reti usw... ?

Autor: Peter D. (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Bitzeit = 1/8MHz = 125ns
8MHz / 4095 = 1,95kHz

Die ersten 7 Bits werden im Compare-A Interrupt erzeugt, d.h. 127 
Zyklen. Insgesamt dauert der Interrupt 159 Zyklen.
Die weiteren Compare-B Interrupts dauern 51 Zyklen.
Das ergibt bei 12Bit:
(159 + 4 * 51) / 4095 = 9% CPU-Last

Autor: Marc V. (Firma: Vescomp) (logarithmus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Die ersten 7 Bits werden im Compare-A Interrupt erzeugt, d.h. 127
> Zyklen. Insgesamt dauert der Interrupt 159 Zyklen.

 Sorry, war zu faul um mich durchzulesen. Bei mir habe ich nur
 die bits 0 und 1 ins bit7 verlegt, bin aber nicht besonders
 glücklich damit.

Autor: der alte Hanns (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur für die Registratur (und um zu zeigen, dass das Projekt interessiert 
und Anklang findet):

in pwm.c
>   TCCR1B = 1<<WGM12 | 1<<CS00;                  // CTC-mode, F_CPU / 1

sollte es wohl eher CS10 heißen.

Autor: Äxl (geloescht) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der alte Hanns schrieb:
> Nur für die Registratur (und um zu zeigen, dass das Projekt interessiert
> und Anklang findet):
>
> in pwm.c
>>   TCCR1B = 1<<WGM12 | 1<<CS00;                  // CTC-mode, F_CPU / 1
>
> sollte es wohl eher CS10 heißen.

Da gerade Beitrag "Suche günstigen 5V Mikrocontroller mit 6 PWM Channel für LED Steuerung" drauf 
verwiesen wird...

ist im Define (hier mal die iom8.h genommen) aber (auch nach vier 
Jahren) mit der gleichen Zahl hinterlegt, (Schwein gehabt - hihi)
Aber: der Ordnung halber hast Du Recht.
/* TCCR0 */
/* bits 7-3 reserved */
#define CS02    2
#define CS01    1
#define CS00    0  <---
...
...
/* TCCR1B */
#define ICNC1   7
#define ICES1   6
/* bit 5 reserved */
#define WGM13   4
#define WGM12   3
#define CS12    2
#define CS11    1
#define CS10    0  <---

VlG Äxl

Autor: Äxl (geloescht) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
*im Beitrag... :|

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.