Forum: Mikrocontroller und Digitale Elektronik PWM mit Atmega32 (in C)


von ChrisLiebig (Gast)


Lesenswert?

Hallo Leute, ich möchte mit einem Atmega32 eine LED dimmen,. Leider habe 
ich dabei einige Startschwierigkeiten. Ich weiß, dass ich PB3 (OC0) 
nutzen kann. Diesen muss ich auch als Ausgang schalten, also DDRB=0x07;, 
oder?
Was muss ich für Register setzen und wie kann ich das ganze in eine 
Endlosschleife einbauen, die schon in meinem Programm existiert? Achja, 
mein uC läuft mit 16MHz.

von Johannes M. (johnny-m)


Lesenswert?


von ChrisLiebig (Gast)


Lesenswert?

Das habe ich mir schon durchgelesen, nur werde ich nciht so richtig 
schlau dadraus. Hat jemand ein Beispiel oder nen Tipp für mich?

von Johannes M. (johnny-m)


Lesenswert?

Was ist denn unklar? Im Tutorial steht eigentlich alles Wissenswerte 
drin...

von ozo (Gast)


Lesenswert?

In den Datenblättern von Atmel sind (meine ich) kurze Codeschnipsel 
dabei. Ansonsten Forensuche oder Onkel Google...
http://www.mikrocontroller.net/articles/AVR_PWM

von ChrisLiebig (Gast)


Lesenswert?

Ja, die Register und das alles steht schon drin...aber ich weiß nciht so 
recht wie ich es machen soll. Sagen wir ich habe solch ein 
Programmaufbau:


int main(){

//Schreiben der Register

while(1){

//Ermitteln von Helligkeit

//OCR0 = Helligkeit;

//Restlicher Programmablauf

};

};

geht das so?

von ChrisLiebig (Gast)


Lesenswert?

Hat keiner ne Antwort?

von winne (Gast)


Lesenswert?

Ich fürchte du hast gar nicht verstanden, worum es sich bei der 
Puls_Weiten_Modulation handelt?

in der Sache geht es darum das die LED ständig an und ausgeschaltet 
wird. Das Verhältnis zwischen ein und Ausschaltdauer, Pulsweite bezogen 
auf die Zyclendauer bestimmt die Helligkeit der LED.

Hintergrund ist die zeitliche integration des aufgebachten 
Eenergieäquivalents einer andauernden Energiezufur mit geringerer 
Leistung.

Am einfachsten realsiert du das in dem du nen Timer durchlaufen läst. 
immer beim overflow(timmer ==0) schaltet den HP die LED ein wenn der 
timer einen wert X erreicht schaltest du die LED aus. so kannst du das 
Tastverhähltnis (die relative Pulsweite) bestimmen.

Wenn du das alles verstanden hast kannst du den HW-Timeer auch direkt 
für die PWM-Erzeugung benutzen. Dazu must du dessen Steuerregister 
entsprechend setzen. so bleibt der prozessor frei für weniger simple 
Funktionen.

von ChrisLiebig (Gast)


Lesenswert?

Also kann ich nicht einfach einmal Programmablauf den Wert setzen und 
die Hardware macht das dann alleine?

von winne (Gast)


Lesenswert?

Doch aber erst wenn du verstanden hast wies geht, das findest du im 
ausführlichen Datasheet des ATMega32.

von ChrisLiebig (Gast)


Lesenswert?

Hmm, ich dachte, dass mir jemand einen Tipp geben kann...

von winne (Gast)


Lesenswert?

tip selber lesen

von winne (Gast)


Lesenswert?

und probieren ;-)

von Tobi (Gast)


Lesenswert?

Beispiel:

  TIMER1_CLOCK_SELECT(TIMER1_PRESC_8);
  TIMER1_WGM_MODE(TIMER1_PWM10_BIT);    //PWM, 10 Bit
  OCA1_PIN_CONFIG(TIMER1_OC_PIN_CLEAR);  //Clear at Compare Match, Set 
at TOP

  OCR1A=0x0100;  //Compare-Match RegisterA

von winne (Gast)


Lesenswert?

eine Alternative bietet Der CVAVR compiler

der besitzt eine Codewizard der deneriert dier da s fix und fertig, wenn 
du ihm deine Wünsche in denentsprechenden eingabefeldern mitteilst.

Um das für dich zu machen müßte ich den anderen Rechner starten. Hier im 
Wohnzimmer ist das nicht installiert.

Aber mehr lernst du durch selber erarbeiten, als wenn du es nur 
abschreibst.

von ChrisLiebig (Gast)


Lesenswert?

Ok, dann probier ichs mal...also, ich denke mal, dass entscheidene 
Register is TCCR0.

Also müsste das gaze doch so aussehn:

TCCR0 = (1 << WGM00) | (1 << COM01) | (1 << ...);

oder?

aber wie komme ich nun auf den Clock?

von winne (Gast)


Lesenswert?

@ tobie

meinst du er kann deinen Tip verarbeiten?

von ChrisLiebig (Gast)


Lesenswert?

ist das mit dem TCCR0 nicht der richtige ansatz?

von Thilo M. (Gast)


Lesenswert?

Ich hätte auch einen Tipp:
1
TCCR1A = _BV(WGM10)|_BV(WGM11)|_BV(COM1A1);
2
TCCR1B = _BV(CS10);
3
TCNT1 = 0;
4
  
5
OCR1A = 0;
Gilt natürlich für Timer 1.
Kannst ja im Datenblatt nachsehen, was die einzelnen Register und Bits 
machen, OCR1A bestimmt das Tastverhältnis. ;)

von ChrisLiebig (Gast)


Lesenswert?

Hmm, wie müsste das mit dem Timer1 denn im konkreten Anwendungsfall 
aussehen?

Es ist doch ne 10Bit PWM, oder?

Wie müsste das ganze jetzt im Code aussehn, wenn ich Beispielsweise die 
halbe Helligkeit erreichen will?

von winne (Gast)


Angehängte Dateien:

Lesenswert?

im Anhang was der CVAVR generator ausgespukt hat

PORTB
DDRB

und  alles zum Timer0 ist zu beachten

von winne (Gast)


Lesenswert?

OCR0=0xA6;


mit dem Wert kanst du spielen um die Helligkeit zu beeinflussen

von Thilo M. (Gast)


Lesenswert?

Nunja, wie das mit der Helligkeit aussieht weiß ich nicht, die LED ist 
ja nicht linear, was die Helligkeit betrifft.
Mit dem PWM (dem Tastverhältnis) stellst du den Effektivwert der 
Rechteck-Wechselspannung ein. => Frequenz fest, Tastverhältnis variabel 
über OCR1A. Bei 10 bit (0..1023) wäre die Hälfte dann logischerweise 
512, bei 8 Bit (0..255) dann 128.

von ChrisLiebig (Gast)


Lesenswert?

PORTB=0x00;
DDRB=0x08;


TCCR0=0x75;
TCNT0=0x00;
OCR0=0xA6;


so müsste das also aussehen? hmm, funktioniert leider nicht:(

von ChrisLiebig (Gast)


Lesenswert?

Achso, in dem Beispiel is ja der Takt mit ca. 11 MHz an
gegeben.  Mein Quarz läuft aber mit 16 Mhz. kann das was ausmachen?

von Stefan E. (sternst)


Lesenswert?

> Nunja, wie das mit der Helligkeit aussieht weiß ich nicht, die LED ist
> ja nicht linear, was die Helligkeit betrifft.

Die Nichtlinearität einer LED spielt da keine Rolle. Es ist ja nicht so, 
dass die LED bei einer 50% PWM irgendwie mit halber Spannung oder so 
läuft. Es bedeutet, dass die LED 50% der Zeit ganz an und 50% der Zeit 
ganz aus ist. Das Auge (oder genauer das Gehirn) macht daraus dann die 
halbe Helligkeit (sofern die Wechsel schnell genug sind). Wenn du also 
eine Nichtlinearität zwischen Duty-Cycle und Helligkeit feststellst, 
dann liegt diese in deinem Kopf. ;-)

von winne (Gast)


Lesenswert?

@ Thilo

Das ist ein interrsanter Seiteneneffekt der Dimmung via PWM.

Da die LED aussschlieslich in einem Arbeitspunkt ihrer Kennlinie ein und 
ausgeschaltet wird ist die Lichtausbeute (photonemmitting per zeit) 
proportional dem Tastverhältnis.

Da unser Auge die Helligkeit  integrierend erfasst, erfahren wir eine 
proportionale Helligkeitsänderung solange die Impulsfolgefrequenz höher 
als unser zeitliches Auflösungsvermögen ist.

 Dieses liegt bei ca.25 Hz was man jedoch bei schneller 
Auge-Objekt-Bewegung noch als verschieden Lichtquellen wahrnimmt. Erst 
ab ca. 100Hz entsteht ein flimmerfreies Bild auch in der Bewegung.

von winne (Gast)


Lesenswert?

die Frequenz des timers ist um 1/3 höher.

Auf das Tastverältnis hat das keinen Einfluss und somit nicht auf die 
Helligkeit. Diese ist lediglich von deinem Vorwiderstand, der LED und 
dem Wert in OCR0 abhängig.

von winne (Gast)


Lesenswert?

Der Punkt

geht an Stefan ich habe zulangsam getippt.

von winne (Gast)


Lesenswert?

du must an PORTB3 das ist pin $ mit deiner LED

von winne (Gast)


Lesenswert?

Pin 4

von ChrisLiebig (Gast)


Lesenswert?

Ja, das wusste ich, und es funktioniert auch:) aber leider flimmert das 
ganz doch deutlich bei niedrigeren Werten...kann man das irgendwie noch 
ändern?

von ChrisLiebig (Gast)


Lesenswert?

Ah ok, hat sich erledigt;) is echt nen besseres Gefühl selber was 
rauszufinden;)

von winne (Gast)


Lesenswert?

versuchs mal mit den Werten
weniger Vorzähler


// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 11059,200 kHz //= Systemclock
// Mode: Phase correct PWM top=FFh
// OC0 output: Inverted PWM
TCCR0=0x71;
TCNT0=0x00;
OCR0=0xA0;

while (1)
      {
      // Place your code here
       delay_ms(20);OCR0++;
      };


Die schleife  Dient dem sichtbar machen alle 20 ms ein bit hochzählen.
delay_ms(n) ist eine funktion der liberydatei delay.lib des CVAVR hier 
must du eine eigene Pausefunktion verwenden/selber schreiben. Im 
eifachsten fall verschachtelte while schleifen.

wenn die LED gegen plus geschaltet wird wird sie langsam heller. habe 
das hier gerade mal aufgebaut.

Habe dass gerade aufgebaut. Funktioniert.

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.