Forum: Mikrocontroller und Digitale Elektronik Atmega32 PWM LED mit 3 Eingängen


von Thomas (Gast)


Lesenswert?

Hallo Leute,

ich hab da ein echtes Problem. Ich möchte mit einem Atmega 32 über drei 
PWM`s eine LED ansteuern, die drei Eingänge hat für rot, grün und blau.
Je eine PWM soll eine Farbe einstellen.

Der Aufbau der Schaltung sieht folgendermßen aus. Ich nehme die 
Boardspannung 5V und schalte parallel dazu drei Potis und die Ausgänge 
der Potis liegen auf den Eingängen ADC0, ADC1 und ADC2. Nun will ich das 
jeder dieser ADC´s das Signal des Potis in eine Zahl umwandelt und diese 
dann für die PWM_erzeugung nutzt und das jeweilige PWM Signal dann über 
den OC2, OC1A und OC1B ausgeben soll.

Eine PWM hab ich erzeugt und das klappt prima, habe den TCCR2 
initialisiert mit 0x65 verodert. Dann hab ich OC2 gleich ADCH gesetzt. 
ADMUX hab ich auf 0x60 verodert. Klappt wunderbar. Aber ich schaffe es 
nicht, den ADMUx auf die anderen ADC`s zu setzen und die TCCR1A und 
TCCR1B so zu initialiesieren, das ein vernünfitges PWM aufgegeben wird. 
Um genau zu sein kommt da gar kein PWM Signal.

TCCR2 |= 0x65;

ADMMUX |= 0x60;

OCR2 = ADCH;

Alles andere klappt nicht.......

Hoffe auf gute Ratschläge....

LG

von Floh (Gast)


Lesenswert?

Thomas schrieb:
> Aber ich schaffe es
> nicht, den ADMUx auf die anderen ADC`s zu setzen und die TCCR1A und
> TCCR1B so zu initialiesieren, das ein vernünfitges PWM aufgegeben wird.

is doch nicht so schwer:
Endloschleifenstart:
  ADC0 messen
  ->Wert auf PWM0
  ADC1 messen
  ->Wert auf PWM1
  ADC2 messen
  ->Wert auf PWM2
Schleifenende

ADCx messen:
  ADMUX richtig setzen
  Conversion starten
  warten
  wert auslesen
Ende Unterprogramm

:-)

von Karl H. (kbuchegg)


Lesenswert?

Was auch nicht so schwer ist:

Nicht alles auf einmal machen!
Du hast mehrere Themenkreise
* PWM für rot
* PWM für grün
* PWW für blau

bring doch die erst mal zum laufen! Auch hier wieder: Nicht alles auf 
einmal. 1 PWM nach der anderen. Die nächste knöpfst du dir erst dann 
vor, wenn die Vorhergehende funktioniert.

Und erst dann, wenn du jede Farbe per Zahlenwert im Programm getrennt 
einstellen kannst, dann kümmerst du dich darum wo jetzt die Zahlenwerte 
herkommen. Es kommen also nocht die Themenkreise dazu
* einen ADC-Kanal auslesen
* mehrer ADC-Kanäle auslesen

Dazu benutzt du zb nicht irgendwelches Eigengemurkse, sondern die ADC 
Routinen aus dem AVR-GCC-Tutorial

Das Geheimnis größerer/komplizierterer Programme besteht nicht darin, 
dass der Programmierer gut genug ist, alles gleichzeitig zu machen. Das 
Geheimnis besteht darin, dass der Programmierer einen Fahrplan hat, in 
welcher Reihenfolge er sich um welches Teilproblem kümmert. Und zwar 
solange kümmert bis er es gelöst hat und sich erst dann dem nächsten 
Teilproblem zuwendet.
Neulinge entfachen gerne einen n-Fronten Krieg indem sie sich auf x 
Teilprobleme gleichzeitig stürzen.

von Thomas (Gast)


Lesenswert?

Danke für die schnellen Antworten,

eines verstehe ich aber nicht ganz. Ich muss bevor ich einen Wert des 
ADC auslesen kann, den ADMUX jedesmal neue initialisieren. Und dieser 
schreibt doch dann den jeweiligen Wert aufs ADCH oder ADCL je nach dem 
wie der ADMUX initialiesiert wurde. Muss ich dann den ADCH nach jeder 
Messung auslesen und auf eine Variable schreiben? Also so:

Endloschleifenstart:
  ADMUX initialisieren auf ADC0 ?
  ADC0 messen
  ->Wert ADCH auf PWM0 ?
  OCR0 = PWM0
  ADMUX initialiesiren auf ADC1 ?
  ADC1 messen
  ->Wert ADCH auf PWM1 ?
  OCR1A = PWM1
  ADMUX initialisieren auf ADC2 ?
  ADC2 messen
  ->Wert ADC2 auf PWM2 ?
  OCR1B = PWM2
Schleifenende

so stell ich mir die Schleife vor.

So hab ich es aber schon probiert, und hat leider nicht geklappt.. :(

von Karl H. (kbuchegg)


Lesenswert?

Thomas schrieb:

> Messung auslesen und auf eine Variable schreiben? Also so:
>
> Endloschleifenstart:
>   ADMUX initialisieren auf ADC0 ?
>   ADC0 messen
>   ->Wert ADCH auf PWM0 ?
>   OCR0 = PWM0
>   ADMUX initialiesiren auf ADC1 ?
>   ADC1 messen
>   ->Wert ADCH auf PWM1 ?
>   OCR1A = PWM1
>   ADMUX initialisieren auf ADC2 ?
>   ADC2 messen
>   ->Wert ADC2 auf PWM2 ?
>   OCR1B = PWM2
> Schleifenende
>
> so stell ich mir die Schleife vor.


Warum nicht einfach so
1
    ....
2
3
    ADC_Init();
4
5
    while( 1 ) {
6
      OCR0  = ADC_Read( 0 );
7
      OCR1A = ADC_Read( 1 );
8
      OCR1B = ADC_Read( 2 );
9
    }

fertig.
Zu kompliziert?

Die ADC Routinen findest du im AVR-GCC-Tutorial
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29

und wenn du wissen willst, wie sie das machen, dann studierst du einfach 
deren Code (musst du sowieso, weil du im ADC_Init die Einstellung der 
Referenzspannung anpassen musst)


ABER:
Funktionieren denn deine 3 PWM Ausgänge schon?
Sprich, wenn du in
1
    ....
2
3
    ADC_Init();
4
5
    while( 1 ) {
6
      OCR0  = 100;
7
      OCR1A = 150;
8
      OCR1B = 200;
9
    }

die Zahlenwerte veränderst, werden dann die LED heller/dunkler 
entsprechend den Zahlenwerten?

von Floh (Gast)


Lesenswert?

Allgemeines Vorgehen:
1. ADMUX einstellen
2. Messung starten (ADSC setzen)
3. warten bis Messung fertig
4. Wert im ADCH/ADCL ist jetzt fertig
5. auslesen des Wertes.

Für einen anderen Kanal beginnt das ganze von neuem.
:-)

von Lehrmann M. (ubimbo)


Lesenswert?

Karl heinz Buchegger schrieb:
> Das Geheimnis größerer/komplizierterer Programme besteht nicht darin,
> dass der Programmierer gut genug ist, alles gleichzeitig zu machen. Das
> Geheimnis besteht darin, dass der Programmierer einen Fahrplan hat, in
> welcher Reihenfolge er sich um welches Teilproblem kümmert. Und zwar
> solange kümmert bis er es gelöst hat und sich erst dann dem nächsten
> Teilproblem zuwendet.
> Neulinge entfachen gerne einen n-Fronten Krieg indem sie sich auf x
> Teilprobleme gleichzeitig stürzen.

Dem kann ich nur Zustimmen. Der Informatiker sagt da 'divide et impera' 
dazu. Vielleicht eher bekannt als 'divide and conquer'. =)

von Karl H. (kbuchegg)


Lesenswert?

Lehrmann Michael schrieb:

> Dem kann ich nur Zustimmen. Der Informatiker sagt da 'divide et impera'
> dazu. Vielleicht eher bekannt als 'divide and conquer'. =)

Und eine Abart von divide and conquer ist es, Funktionalität nicht auf 
Biegen und Brechen in eine Hauptschleife zu quetschen, sondern sich zb 
Funktionen zu machen, die eine Standardaufgabe (wie zb das Auslesen des 
ADC auf einem bestimmten Kanal) behandeln und dann diese Funktionen wie 
Bausteine zu benutzen.

Ist der Baustein erst einmal korrekt, kann man ihn beliebig oft 
einsetzen und plötzlich verlieren gewisse Probleme ihren Schrecken, weil 
die Dinge auf einmal ganz einfach werden.

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.