mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LED PWM mit Atmega8


Autor: Christian S. (kruemel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe mir das demoprogramm aus dem Tutorial Bereich mal angeschaut zur 
PWM und LED Fading.

Möchte erstmal das Programm mit einer Fast PWm 8bit laufen lassen. Dazu 
habe ich mir den Quelltext angepasst in C auf das STK500 bzw habe ich 
versucht.
//*****************************************************************************
//*
//*  LED fading test
//*  uses exponential PWM settings to achive visual linear brightness
//*
//*  ATmega32 @ 8 MHz
//*  
//*                  
//*****************************************************************************
 
#define F_CPU 8000000L
 
#define true 1
#define false 0
 
#define STK500 true
 
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
 
// global variables
 
uint16_t pwmtable_8C[16]  PROGMEM = {0, 2, 3, 4, 6, 8, 11, 16, 23, 32, 45, 64,
                                    90, 128, 181, 255};

// long delays
 
void my_delay(uint16_t milliseconds) {
    for(; milliseconds>0; milliseconds--) _delay_ms(1);
}
 

 
// 8-Bit PWM with 16 different settings
 
void pwm_8_16(uint16_t delay){
 
    int16_t tmp;
 
#if STK500
    TCCR1A = (0<<PWM11)|(1<<PWM10)|(1<<COM1A1)|(1<<COM1A0);          // inverted PWM on OC1A, 8 Bit Fast PWM
#else
    TCCR1A = 0x81;          // non-inverted PWM on OC1A, 8 Bit Fast PWM
#endif
    TCCR1B = 0x08;
 
    TCCR1B &= ~0x7;         // clear clk setting
    TCCR1B = (1<<CS12);     // precaler 256 -> ~122 Hz PWM frequency
 
    for(tmp=0; tmp<=15; tmp++){
      OCR1A = pgm_read_word(pwmtable_8C+tmp);
      my_delay(delay);
    }
 
    for(tmp=15; tmp>=0; tmp--){
      OCR1A = pgm_read_word(pwmtable_8C+tmp);
      my_delay(delay);
    }
}
 
 
int main(void)
{
    int16_t i;
    int16_t step_time=400;      // delay in millisecond for one fading step
 
    DDRD |= (1<<PD0);           // LED uses OC1A
 
    // test all fading routines
 
    while(1) {
 
     
      for(i=0; i<3; i++) pwm_8_16(step_time/4);
      my_delay(1000);

    };
 
    return 0;
}


Da das Tutorial ja auf einen Atmega32 angepasst ist, habe ich aus dem 
Datenblatt des Atmega8 versucht die Settings für TCCR1A rauszusuchen und 
habe die oben eingesetzt. Wie ich TCCR1B setzen muss weiss ich nicht. 
Kann mir da jemand weiterhelfen?

Zur Grundfunktion möchte ich noch wissen folgendes wissen: Wozu ist der 
PWM Table gedacht, durch die beiden Vorschleifen wird die Led ja in 16 
stufen hell geschaltet und nachher wieder runtergedimmt. Was ist das für 
ein Wert? Und wie funktioniert das Programm in Bezug auf OCR1A?

Vielen Dank im vorraus

Autor: Christian S. (kruemel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann mir keiner helfen?

Autor: Thomas Drebert (thomasd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so richtig kann ich dir auch nicht helfen, aber das ASM Tutorial ist für 
den ATmega8 geschrieben, vielleicht findest du dort die Einstellungen 
für den C Code, mansche Dinge sehen doch ähnlich aus.
http://www.mikrocontroller.net/articles/AVR-Tutorial:_PWM

Schöne Grüße
Thomas

Autor: Tom M. (tomm) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian S. schrieb:
> Da das Tutorial ja auf einen Atmega32 angepasst ist, habe ich aus dem
> Datenblatt des Atmega8 versucht die Settings für TCCR1A rauszusuchen und
> habe die oben eingesetzt. Wie ich TCCR1B setzen muss weiss ich nicht.

Dazu müsste ich auch erstmal das ursprüngliche Programm analysieren und 
dann im Datenblatt des Ziel-Controllers schauen, wie die Timer zu 
initialisieren sind. Im besten Fall reicht es, dieselben Flags zu 
setzen, es kann aber auch sein, dass sich die Flags PWMxx und COMxx beim 
atmega8 in verschiedenen control registern befinden. Wie gesagt, 
Datenblatt anschauen!

> Zur Grundfunktion möchte ich noch wissen folgendes wissen: Wozu ist der
> PWM Table gedacht, durch die beiden Vorschleifen wird die Led ja in 16
> stufen hell geschaltet und nachher wieder runtergedimmt. Was ist das für
> ein Wert?

Die wahrgenommene Helligkeit ist nicht linear mit der Pulsdauer. Durch 
die Tabelle wird das korrigiert.

> Und wie funktioniert das Programm in Bezug auf OCR1A?

Vermutlich wird darüber die Pulsweite gesteuert. Der Timer läuft ja im 
PWM Modus. Schau dir das Datenblatt an, Kapitel über Timer1.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hatten wir doch schon mal. Da mus kaum was geändert werden. 
Lediglich das Ausgangspin.

Beitrag "LED-Fading Tutorial nicht übertragbar?"

MfG
Falk

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom M. schrieb:

>> Zur Grundfunktion möchte ich noch wissen folgendes wissen: Wozu ist der
>> PWM Table gedacht, durch die beiden Vorschleifen wird die Led ja in 16
>> stufen hell geschaltet und nachher wieder runtergedimmt. Was ist das für
>> ein Wert?
>
> Die wahrgenommene Helligkeit ist nicht linear mit der Pulsdauer. Durch
> die Tabelle wird das korrigiert.

@TO
Dazu ist es am allerbesten, du vergisst jetzt erst mal die super duper 
Komfortlösung und machst eine ganz banale, plain vanilla PWM mit der du 
auf die LED gehst.
Also: LED an den PWM Ausgang. Timer einstellen und einfach verschiedene 
Werte für OCR1A ausprobieren.

Dann merkst du nämlich sehr schnell, was das Problem ist.

Und dann kannst du auch ermessen, warum da eigentlich so ein Aufwand 
getrieben wird und verstehst dann auch was da eigentlich passiert.

Ausserdem ist es eine Übung im Datenblattlesen und im Umgang mit Timern. 
Und das kann ja erst mal nicht schlecht sein, wenn man zunächst bei den 
Grundlagen anfängt anstatt sich gleich auf die Lösung zu stürzen, die 
man erstens nicht versteht und die zweitens Probleme zu lösen versuchst, 
von deren Existenz du noch gar nichts weißt.

Autor: Christian S. (kruemel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vielen Dank für die Antworten.
Ich werde die Sachen mal durchackern, habe vor ein paar Tagen mit 
Versuchen zur Programmierung angefangen.
LEDs an und ausschalten gehen schonmal. Das wäre jetzt so der nächste 
Schritt mit dem ich mich gerne beschäftigen möchte.

Autor: Christian S. (kruemel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,

ich habe mich nochmal mit der PWm beschäftigt und es auch ans laufen 
bekommen. Ich habe nur noch eine prinzipielle Frage und zwar:

Werden mit der Zuweisung eines Wertes an OCR1A die Pulsweiten 
eingestellt? So wie ich verstanden habe, wird damit ja der Compare Wert 
eingestellt, ab dem der Timer von vorne anfängt zu zählen. Bei einem 
niedrigen Wert von OCR1A hätte ich dann viele schmale Pulse, bei einem 
höheren Wert von OCR1A dann die breitesten?

Zudem habe ich noch eine Codefrage:

Was wird mit den folgenden Anweisungen erreich?:

    TCCR1B = 0x08;          // Prescaler einstellen

    TCCR1B &= ~0x7;         // clear clk setting
    TCCR1B |= 4;            // precaler 256 -> ~122 Hz PWM frequency


Was bedeuten die Operatoren &= und |=, die habe ich bis jetzt noch nicht 
gesehen?
Bei der Anweisung TCCR1B |= 4; könnte ich mir vorstellen, dass nur das 
letzte Byte des 8 Bit Registers gesetzt wird?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian S. schrieb:

> Werden mit der Zuweisung eines Wertes an OCR1A die Pulsweiten
> eingestellt? So wie ich verstanden habe, wird damit ja der Compare Wert
> eingestellt, ab dem der Timer von vorne anfängt zu zählen.

Nicht notwendigerweise.
Das hängt vom Modus ab, in dem der Timer läuft.
Im Datenblatt des Prozessors gibt es da eine wunderschöne Tabelle aus 
der man entnehmen kann welches Register (wenn überhaupt) für die Zahl 
zuständig ist, bis zu der der Timer zählt.

> Bei einem
> niedrigen Wert von OCR1A hätte ich dann viele schmale Pulse, bei einem
> höheren Wert von OCR1A dann die breitesten?

No.
So funktioniert PWM nicht.

Für PWM ist einzig und alleine das Verhältnis von Puls-High zu Puls-Low 
ausschlaggebend.


> Was bedeuten die Operatoren &= und |=, die habe ich bis jetzt noch nicht
> gesehen?

Dann wirds Zeit, dass du noch einmal zu den Grundlagen zurückgehst. 
Diese beiden Operationen müssen dir in Fleisch und Blut übergehen! Da 
frag ich mich, wie du gezielt einen Port so manipulierst, dass du nur 
ein einzelnes Bit, nur ein einziges, manipulierst und alle anderen in 
Ruhe lässt.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian S. (kruemel)

>Werden mit der Zuweisung eines Wertes an OCR1A die Pulsweiten
>eingestellt?

Ist das SOOOO schwer aus dem Quelltext abzulesen?

> So wie ich verstanden habe, wird damit ja der Compare Wert
>eingestellt, ab dem der Timer von vorne anfängt zu zählen.

In dem im Tutorial verwendeten Modus nicht. Der Wert in OCR1A bestimmt, 
wann das Ausgangspin auf LOW geschaltet wird.

>Was bedeuten die Operatoren &= und |=, die habe ich bis jetzt noch nicht
>gesehen?

Siehe Bitmanipulation.

MFG
Falk

Autor: Christian S. (kruemel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja okay, ich habe den Timer auf eine 8 Bit Fast PWM eingestellt, das 
heisst der Timer zählt hier bis 255 und fängt dann wieder bei 0 an.

Okay und nochmal zu breiten und schmalen Pulsen:

Ich meinte mit schmalen und breiten Pulsen die high-Pulse, das sollte 
heißen, bei schmalen high-pulsen, habe ich breite low pulse und 
umgekehrt. Sodass ich im Verhältnis mehr low als high Zustand habe.

Bei einer sehr gedimmten LED sind doch dann schmale high pulse, jedoch 
breite lowpulse vorhanden? Und die Pulslänge, also wie lange die LED 
leuchtet bevor sie wieder ausgeht wird ,je nach Art ob inverting oder 
non inverting  dann über OCR1A bestimmt?

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.