-         

Ergebnis 1 bis 8 von 8

Thema: Helligkeitssteuerung einer LED mit PWM

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.04.2007
    Beiträge
    21

    Helligkeitssteuerung einer LED mit PWM

    Anzeige

    Hallo!

    Also zu meinem Problem, ich möchte mit Pulsweitenmodulation die Helligkeit einer Leuchtdiode steuern. Mit einem Poti möchte ich die Pulsbreite einstellen können, also wie hell bzw dunkel sie leuchtet.
    Ich habe mir schon verschiedene Artikel durchgelesen, verstehe aber nicht wie ich das ganze umsetzen soll.
    Als Hardware habe ich das myAVR Testboard, mit dem ATmega8 µC und als Software das MyAVR Workpad.

    Folgendes habe ich mir schon überlegt:
    Durch drehen des Potis ändert sich ja die Spannung, also müsste ich das mit dem Wert 5V (Boardspannung) irgendwie mit dem Spannungswert des Potis vergleichen damit dann die PWM jeweils die Pulsbreite ändert.
    D.h. ich brauche wohl einen A/D Wandler? Dieser Wert muss dann in das PWM Register. (?)

    Kann mir da vielleicht jemand helfen?

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.07.2005
    Beiträge
    127
    hallo,

    na wenn du das myavr workpad hast kannst dir die lösung ja anschauen... datei neu -> eine vorlage laden -> Analog -> PWM LED Dimmer

    oder du setzt dir das ganze mit dem myavr codewizard einzeln zusammen...

    kurz um du holst dir den ADC wert als 8Bit wert und schaffst ihn in des vergleichsregister des timers... vorausetzung adc und timer sind richtig initialisiert... aber das kannst du ja bequem mit dem codewizard machen

    cu BT

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    01.04.2007
    Beiträge
    21
    Hallo!

    Danke für deinen Tipp. Ich habe mir das Programm ja schon angeschaut und getestet, aber dort wird ja ein ein wechselndes PWM Signal an die rote LED gegeben. Es wird dort ja kein Poti oder so verwendet.

    als Vergleichsregister meinst du damit:
    out OCR1AH,r18
    out OCR1AL,r16 ?

    sorry, anscheinend versteh ich die Lösung dort nicht wirklich...

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.07.2005
    Beiträge
    127
    joo, OCR Output Compare Register

    Kurzformel: OCR1AH/L = ADCH/L

    nimm noch das beispiel wo der ADC wert zu einer tonfrequenz gewandelt wird und zetzt beides sozusagen zusammen

    cu BT

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    01.04.2007
    Beiträge
    21
    hi nochmals!

    Habe gerade mit dem Codewizard etwas rumprobiert, (hab ihn vorher nie benutzt) und folgendes ist bei rausgekommen:

    Code:
    ;-------------------------------------------------------------------------
    ; Titel : Helligkeitssteuerung einer LED mit PWM
    ;-------------------------------------------------------------------------
    ; Funktion :
    ; Schaltung : PORTC0=Pot1, PORTB1=LED Rot
    ;-------------------------------------------------------------------------
    ; Prozessor : ATmega8
    ; Takt : 3686400 Hz
    ; Sprache : 
    ; Datum : 1.4.2007
    ; Version : 1.0
    ; Autor : 
    ; Programmer: 
    ; Port : 
    ;-------------------------------------------------------------------------
    ; created by myAVR-CodeWizard
    ;-------------------------------------------------------------------------
    .include "avr.h"
    
    begin: 	rjmp 	main 	; 1 POWER ON RESET
     	reti 	 	; 2 Int0-Interrupt
     	reti 	 	; 3 Int1-Interrupt
     	reti 	 	; 4 TC2 Compare Match
     	reti 	 	; 5 TC2 Overflow
     	reti 	 	; 6 TC1 Capture
     	reti 	 	; 7 TC1 Compare Match A
     	reti 	 	; 8 TC1 Compare Match B
     	reti 	 	; 9 TC1 Overflow
     	reti 	 	;10 TC0 Overflow
     	reti 	 	;11 SPI, STC Serial Transfer Complete
     	reti 	 	;12 UART Rx Complete
     	reti 	 	;13 UART Data Register Empty
     	reti 	 	;14 UART Tx Complete
     	rjmp 	onADC 	;15 ADC Wandlung komplett
     	reti 	 	;16 EEPROM Ready
     	reti 	 	;17 Analog Comparator
     	reti 	 	;18 TWI (I²C) Serial Interface
     	reti 	 	;19 Store Program Memory Ready
    
    ;------------------------------------------------------------------------
    ; Initialisierungen
    ;------------------------------------------------------------------------
    main:
     	;--- Stack Initialisierung ---
     	ldi r16,hi8(RAMEND)
     	out SPH,r16
     	ldi r16,lo8(RAMEND)
     	out SPL,r16
     	; Ports initialisieren
     	sbi 	DDRB,1 	; PORTB1 auf Ausgang
     	;--- Timer 1 initialisieren ---
     	ldi 	r16,0b00000010 	; Teiler 1/8
     	ori 	r16,0b00001000 	; Modus: Zählen bis Vergleichswert (WGM12=1)
     	out 	TCCR1B,r16 	; Teiler+Modus schreiben (soll 50Hz sein)
     	ldi 	r16,lo8(9216) 	; Vergleichswert speichern
     	ldi 	r17,hi8(9216)
     	out 	OCR1AH,r17
     	out 	OCR1AL,r16
     	ldi 	r16,0b01100000 	; Port, Referenzspannung und Auflösung
     	out 	ADMUX,r16
     	ldi 	r16,0b11101101 	; Modus, Interrupt und Start
     	out 	ADCSRA,r16
     	;--- Interrupts erlauben ---
     	sei
    ;------------------------------------------------------------------------
    ; Hauptprogramm-Schleife
    ;------------------------------------------------------------------------
    mainloop: 	wdr 	 	
     	; ...
     	rjmp 	mainloop 	; Sprung zum Beginn der Hauptprogrammschleife
     	
    ;--------------------------------------------------------------------
    ; onADC - Interrupt bei ADC Wandlung komplett
    ;--------------------------------------------------------------------
    onADC:
     	push 	r16 	; Register retten
     	push 	r17
     	push 	r18
     	push 	r19
     	in 	r16,SREG 	; Statusregister retten
     	push 	r16
     	; Beginn der Ereignisbehandlung
     	in 	r16,ADCH 	; Einlesen des Analogwertes
     	
     	;.....??
     	
     	pop 	r16 	; Statusregister wiederherstellen
     	out 	SREG,r16 	
     	pop 	r19 	; Register wiederherstellen
     	pop 	r18
     	pop 	r17
     	pop 	r16
     	reti 	 	;Rücksprung
    Ich habe mir beide Programme genau angeschaut, aber ich versteh einfach nicht wie ich das jetzt zusammen bekommen soll
    Meine Gedanken dazu bis jetzt wären wie folgt: Unter Mainloop würd ich jetzt ein "rcall initpwm" und dann unten dran


    Code:
    initPWM:	push	r16
    	sbi	PORTB,1
    	ldi	r16,0b10000001
    	out	TCCR1A,r16
    	ldi	r16,0b00000010
    	out	TCCR1B,r16
    	pop	r16
    	ret
    wenn das schonmal stimmt, dann frag ich mich aber wo ich denn den Analogwert, den ich ja umgewandelt (?) hab, hin muss????? Ich versteh wirklich nur Bahnhof im moment...

    *verwirrt*

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.07.2005
    Beiträge
    127
    ne init kommt nicht in die mainloop... bleib ganz ruhig der aha effekt wird sich schon einstellen...

    -------- init sequenz ---------
    initADC
    initPWM
    -------- mainloop -------------
    r16/17=getADC
    setOCR=r16/16
    ---------------------------------

    es ist einfacher als dir im moment scheint... du bekommst vom ADC eine zahl und gibst sie an in das vergleichsregister des timers... und schon dimmt deine LED das kannstz du sogar in der ISR vom ADC machen *grins*

    cu BT

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    01.04.2007
    Beiträge
    21
    wie meinst du das in der mainloop? das versteh ich nicht ganz
    -------- mainloop -------------
    r16/17=getADC
    setOCR=r16/16
    ---------------------------------
    so ich habe als init sequenz ADC und PWM jetzt drin.
    Die LED leuchtet schon mal aber wie bekomme ich jetzt den umgewandelten Analogwert in das Vergleichsregister? argh ^^
    hier nochmals mein bisheriger Code.

    ;-------------------------------------------------------------------------
    ; Titel :
    ;-------------------------------------------------------------------------
    ; Funktion :
    ; Schaltung : PORTB1=LED-Rot, PORTC0=Pot1
    ;-------------------------------------------------------------------------
    ; Prozessor : ATmega8
    ; Takt : 3686400 Hz
    ;-------------------------------------------------------------------------
    .include "avr.h"

    begin: rjmp main ; 1 POWER ON RESET
    reti ; 2 Int0-Interrupt
    reti ; 3 Int1-Interrupt
    reti ; 4 TC2 Compare Match
    reti ; 5 TC2 Overflow
    reti ; 6 TC1 Capture
    reti ; 7 TC1 Compare Match A
    reti ; 8 TC1 Compare Match B
    reti ; 9 TC1 Overflow
    reti ;10 TC0 Overflow
    reti ;11 SPI, STC Serial Transfer Complete
    reti ;12 UART Rx Complete
    reti ;13 UART Data Register Empty
    reti ;14 UART Tx Complete
    rjmp onADC ;15 ADC Wandlung komplett
    reti ;16 EEPROM Ready
    reti ;17 Analog Comparator
    reti ;18 TWI (I²C) Serial Interface
    reti ;19 Store Program Memory Ready

    ;------------------------------------------------------------------------
    ; Initialisierungen
    ;------------------------------------------------------------------------
    main:
    ;--- Stack Initialisierung ---
    ldi r16,hi8(RAMEND)
    out SPH,r16
    ldi r16,lo8(RAMEND)
    out SPL,r16
    ; Ports initialisieren
    sbi DDRB,1 ; PORTB1 auf Ausgang
    ;--- Interrupts erlauben ---
    sei
    ;--- Timer 0 initialisieren ---
    ldi r16,0b00000100 ; Teiler 1/256
    out TCCR0,r16 ; Teiler+Modus schreiben
    ldi r16,0b01100000 ; Port, Referenzspannung und Auflösung
    out ADMUX,r16
    ldi r16,0b11101101 ; Modus, Interrupt und Start
    out ADCSRA,r16
    ;----------------------------------------------------------------------
    ; PWM und ADC initialisieren

    rcall initPWM ;Schritt auf/ab
    rcall initADC
    ;------------------------------------------------------------------------
    ; Hauptprogramm-Schleife
    ;------------------------------------------------------------------------
    mainloop: wdr
    out OCR1AH,r18
    out OCR1AL,r16
    rjmp mainloop ; Sprung zum Beginn der Hauptprogrammschleife
    ;------------------------------------------------------------------------
    ; UP: ADC initialisieren
    ; Beachte: Interrupt-Vektor "onADC" setzen
    ;------------------------------------
    initADC: push r16
    ldi r16,0
    out ADMUX,r16 ; ADC Chanel
    ldi r25,0b11011101
    out ADCSRA,r25 ; enable ADC, INT, start
    sei
    pop r16
    ret
    ;------------------------------------
    ; ISR: ADC initialisieren
    ; PA: r27:r26 10Bit, r25 8Bit
    onADC: cli
    in r26,ADCL
    in r27,ADCH
    asr r27
    ror r26
    asr r27
    ror r26
    mov r25,r26
    sbi ADCSRA,6
    sei
    reti
    ;------------------------------------------------------------------------
    ; UP PWM initialisieren
    ; Parameter: keine
    ; PWM Chanel A Mode 1: 8-bit PWM, Phase-Correct, Clock/8
    initPWM: push r16
    sbi PORTB,1 ; PWM-Chanel A
    ldi r16,0b10000001 ; PWM-Mode
    out TCCR1A,r16
    ldi r16,0b00000010 ; Vorteiler / PWM Frequenz
    out TCCR1B,r16
    pop r16
    ret
    ;------------------------------------------------------------------------

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    01.04.2007
    Beiträge
    21
    Hallo nochmals, ich denke ich konnte endlich das Problem lösen...
    Nachdem ich die Register in der Hauptschleife nach den Registern in der "onADC" ISR (r27 bzw r26) benannt habe funktioniert es endlich.
    mainloop: wdr
    out OCR1AH,r27
    out OCR1AL,r26
    rjmp mainloop ; Sprung zum Beginn der Hauptprogrammschleife

    Es gibt sicher eine bessere Lösung für das Problem.
    Ich würde mich über weitere Kommentare und Tipps freuen!

    Gruß Vashan

Berechtigungen

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