-         

Ergebnis 1 bis 8 von 8

Thema: Led dimmen mit PWM

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168

    Led dimmen mit PWM

    Anzeige

    Hallo Leute,

    ich habe mal eine Frage:
    Ich habe eine LED, die an einem ATmega168 mit einem Vorwiderstand angeschlossen ist und möchte diese von 100 % Leistung runterdimmen.
    Dazu habe ich hier schon die Suchfunktion benutzt aber nicht wirklich was gefunden.
    Dann habe ich bei mikrocontroller.net gesucht und einen Artikel für Assembler gefunden, aber der ist für den ATmega8 geschrieben:

    Code:
    .include "m8def.inc"
     
    .def temp  = r16
     
    .def PWMCount = r17
     
    .def ocr_1 = r18                      ; Helligkeitswert Led1: 0 .. 127
    .def ocr_2 = r19                      ; Helligkeitswert Led2: 0 .. 127
    .def ocr_3 = r20                      ; Helligkeitswert Led3: 0 .. 127
    .def ocr_4 = r21                      ; Helligkeitswert Led4: 0 .. 127
    .def ocr_5 = r22                      ; Helligkeitswert Led5: 0 .. 127
    .def ocr_6 = r23                      ; Helligkeitswert Led6: 0 .. 127
     
    .org 0x0000
            rjmp    main                  ; Reset Handler
    .org OVF0addr
            rjmp    timer0_overflow       ; Timer Overflow Handler
     
    main:
            ldi     temp, LOW(RAMEND)     ; Stackpointer initialisieren
            out     SPL, temp
            ldi     temp, HIGH(RAMEND)
            out     SPH, temp
    	
            ldi     temp, 0xFF            ; Port B auf Ausgang
            out     DDRB, temp
     
            ldi     ocr_1, 0
            ldi     ocr_2, 1
            ldi     ocr_3, 10
            ldi     ocr_4, 20
            ldi     ocr_5, 80
            ldi     ocr_6, 127
     
            ldi     temp, 0b00000001      ; CS00 setzen: Teiler 1
            out     TCCR0, temp
     
            ldi     temp, 0b00000001      ; TOIE0: Interrupt bei Timer Overflow
            out     TIMSK, temp
     
            sei
     
    loop:   rjmp    loop
     
    timer0_overflow:                      ; Timer 0 Overflow Handler
            inc     PWMCount              ; den PWM Zähler von 0 bis
            cpi     PWMCount, 128         ; 127 zählen lassen
            brne    WorkPWM
            clr     PWMCount
     
    WorkPWM:
            ldi     temp, 0b11000000      ; 0 .. Led an, 1 .. Led aus
     
            cp      PWMCount, ocr_1       ; Ist der Grenzwert für Led 1 erreicht
            brlt    OneOn
            ori     temp, $01
     
    OneOn:  cp      PWMCount, ocr_2       ; Ist der Grenzwert für Led 2 erreicht
            brlt    TwoOn
            ori     temp, $02
     
    TwoOn:  cp      PWMCount, ocr_3       ; Ist der Grenzwert für Led 3 erreicht
            brlt    ThreeOn
            ori     temp, $04
     
    ThreeOn:cp      PWMCount, ocr_4       ; Ist der Grenzwert für Led 4 erreicht
            brlt    FourOn
            ori     temp, $08
     
    FourOn: cp      PWMCount, ocr_5       ; Ist der Grenzwert für Led 5 erreicht
            brlt    FiveOn
            ori     temp, $10
     
    FiveOn: cp      PWMCount, ocr_6       ; Ist der Grenzwert für Led 6 erreicht
            brlt    SetBits
            ori     temp, $20
     
    SetBits:                              ; Die neue Bitbelegung am Port ausgeben
            out     PORTB, temp
     
            reti
    (Quelle: http://www.mikrocontroller.net/artic...-Tutorial:_PWM)

    Da ich aber mit C arbeiten möchte hilft mir der Code nicht wahrlich weiter.
    Ich würde mich freuen, wenn ihr mir Tipps geben könntet, die mir bei der Umsetzung helfen würden.
    Danke im Voraus!

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    48
    Beiträge
    524
    Hallo,

    schnapp dir das Datenblatt und diesen Artikel aus dem Wissenbereich.
    Achte halt drauf, das die LED am richtigen PIN sitzt und der PIN als Ausgang definiert ist. Wenn's dann nicht klappt, haben wir eine Grundlage mit der wir arbeiten können.

    Gruß

    Jens

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    Hallo Jens,

    danke für die Infos.
    Ich werde mich dann mal gleich zu Hause dransetzen und testen.
    Wenn das nicht klappt werde ich mich mal melden ...
    Bzw. wenn es geklappt hat ...

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    So hier ist nun mein Programm:

    Code:
    #include <avr/io.h>
    #include <util/delay.h> //Warteschleife für die Demo-Ausgabe. Für die eigentliche PWM nicht benötigt!  
    
    int main()
    {
    
    //  PWM-Beispiel für Mega168 mit dem Timer2	
    
    // 1. Den Prescaler einstellen, der die Frequenz festlegt
    	TCCR2B |= (1<<CS22); //Prescaler 256
    	
    // 2. Den Timer in den Fast PWM Mode, 8 Bit schalten
    	TCCR2A |= (1<<WGM20);
    	TCCR2A |= (1<<WGM21);
    	
    // 3. Compare Output mode einstellen: Pin geht auf high bei Compare match, auf low bei Überlauf. Ergibt nichtinvertierte PWM.	
    	TCCR2A |= (1<<COM2B1);	
    	
    // In diesen Registern wird der gwünschte PWM-Wert abgelegt. Erlaubter Bereich: 0 bis 255.
    	OCR2B =	255;	
    
    // 4. Zuletzt den Pin als Ausgang konfigurieren. Erst jetzt liegt das PWM-Signal an dem Pin an!	
    	DDRD |= (1<<PD3);
    
    /*Nun ist der PWM-Modus aktiv! Der Ausgangswert kann nun über das Register OCR2B vorgegeben werden. 
    Man könnte ihnen per define noch einen Zweitnamen verpassen, zb */
    #define LED OCR2B
    
    LED = 0;
    
    
    
    /*PWM-Demo: Die PWM-Werte werden erst bis zum Maximalwert erhöht und dann wieder verringert. 
    Eine angeschlossene LED wird langsam heller und wird dann wieder verdunkelt*/
    	uint8_t wert;
    	while(1)
    	{
    		for (wert=0; wert<255; wert++)
    			{
    				OCR2B = wert;
    				_delay_ms(20);
    			}
    	
    		for (wert=255; wert>0; wert--)
    			{
    				OCR2B = wert;
    				_delay_ms(20);
    			}	
    	}
    }
    Das Programm läuft erstmal so wie ich es möchte.

    EDIT: Kommentare aus dem Code überarbeitet

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    Zitat Zitat von H3llGhost
    So hier ist nun mein Programm:....
    Das Programm läuft erstmal so wie ich es möchte.
    Es läuft so, wie Du möchtst? Das wundert mich schon ein bisschen. Du bist wohl ein kleiner Scherzkeks ! ? ! ?

    Zitat Zitat von H3llGhost
    ... LED ... ATmega168 ... runterdimmen ... ... PWM-Beispiel für Mega16/32 ...
    Na ja, ok, man kann natürlich statt mit em m168 auch mit m32/16 dimmen - wie Du es ja wohl tust.

    Zitat Zitat von H3llGhost
    ... Timer1 ... 8 Bit ...
    Dein code ist aber doch für den Timer 2 ! ? Ist wegen der 8 Bit auch sinnvoller.

    Zitat Zitat von H3llGhost
    ... Timer1 im Fast PWM Mode, 8 Bit ...
    Fast PWM ? Wieso? Wo ist die Parameterisierung?

    Zitat Zitat von H3llGhost
    ... Beispiel für Mega16/32 ... TCCR2A |= (1<<COM2B1); ...
    In meinem ATmega32-doc2503 und im mega16-doc2466 gibts weder ein TCCR2A noch ein COM2B1. Ist das ein neuartiger mega16/32 ? ? Und die WGM20/~21 stehen im TCCR2 - das ist der ohne "A". ... und so weiter, etliche Ungereimtheiten.

    Also doch ein mega168. Scheint eine Denksportaufgabe zu sein.

    Zitat Zitat von H3llGhost
    ... DDRD |= (1<<PD3); ...
    Jaaa, hier ist ja (noch) ein Hinweis auf den m168.

    Zitat Zitat von H3llGhost
    ... Fast PWM Mode ...
    Da Du Dich nicht um die COM0x* nicht kümmerst, weiss ich nicht ob das stimmt. Oder liegt hier eine weitere Denksportaufgabe?

    Zitat Zitat von H3llGhost
    ... Das Programm läuft erstmal so wie ich es möchte.
    Dann ist´s ja gut.
    Ciao sagt der JoeamBerg

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    Ich hätte vielleicht die alten Kommentare entfernen können ...
    Das ist der Code für einen ATmega168.

    Zitat Zitat von oberallgeier
    Zitat Zitat von H3llGhost
    ... Fast PWM Mode ...
    Da Du Dich nicht um die COM0x* nicht kümmerst, weiss ich nicht ob das stimmt. Oder liegt hier eine weitere Denksportaufgabe?
    Warum sollte ich denn das Register COM0x* einstellen?!
    Ich benutze doch den Timer2 und dann benutze ich doch das Register COM2B1.

  7. #7
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.551
    Zitat Zitat von H3llGhost
    ... Warum sollte ich denn das Register COM0x* einstellen?! ...
    Tut mir leid, war mein Fehler.

    Zitat Zitat von H3llGhost
    Ich hätte vielleicht die alten Kommentare entfernen können ...
    Stimmt, am Besten vorm Fragen. Nix ist so alt, wie der Kommentar vom letzten (abgeänderten) Code.
    Ciao sagt der JoeamBerg

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    Zitat Zitat von oberallgeier
    Stimmt, am Besten vorm Fragen. [...]
    Ich habe doch keine Frage gestellt oder?
    Ich habe einfach nur mein Ergebnis mit komischen Kommentaren gepostet oder? :-P

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •