- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 10 von 23

Thema: PWM mit ATMega8 und Timer2

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    19.04.2011
    Ort
    Aachen
    Alter
    35
    Beiträge
    22
    Hallo nochmal,

    ich weiß nun, dass es eigentlich klappen müsste, denn wenn ich den Prescaler entsprechend hochsetze, z.B. 1024, dann sehe ich die LED flackern. Wenn ich den Prescaler soweit runtersetze, dass ich kein flackern mehr sehe (derzeit Prescaler 64), dann kann ich leider keine Helligkeitsunterschiede feststellen, egal ob ich OCR2 mit 0xFF oder 0x00 lade...
    Das wird wohl an der logarithmischen Helligkeitswahrnemung unseres Auges liegen, was ich auf Mikrocontroller.net gelesen habe, damit unser Auge einen möglichst großen Helligkeitsbereich wahrnehmen kann.

    Gibt es da vielleicht noch einen Trick um doch irgendwie deutlichere Ergebnisse zu erzielen?

    Mein Code sieht derzeit so aus:
    Code:
    	ldi temp, 0x01	; Zur Kontrolle die ersten beiden LEDs einschalten
    	out PORTB, temp
    	out PORTD, temp
    
    	ldi temp, 1<<OCIE2 | 1<<TOIE1 | 1 <<TOIE0	; Timer0-Overflow und Timer1-Overflow und Timer2-Compare "erlauben"
    	out TIMSK, temp
    	ldi temp, 1 << COM20 | 1 << WGM21 | 0 << CS22 | 1 << CS21 | 0 << CS20	; Phasenkorrekte PWM und Prescaler setzen
    	out TCCR2, temp
    	ldi temp, 0x00	; Irgendein Startwert fuer OCR2 (Unsere Helligkeit)
    	out OCR2, temp
    Vielen Dank im Voraus

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    54
    Beiträge
    407
    Hallo,

    in deinem Programm wo das OCR2-Register mit dem Wert Null lädst, wird dadurch ein Dauer-Low-Signal oder je nachdem ob invertiert oder nicht ein Dauer-High-Signal erzeugt.
    Im Datenblatt auf Seite 116 nach einer Formel steht dazu folgendes.

    The extreme values for the OCR2 Register represent special cases when generating a PWM
    waveform output in the phase correct PWM mode. If the OCR2 is set equal to BOTTOM, the output
    will be continuously low and if set equal to MAX the output will be continuously high for noninverted
    PWM mode. For inverted PWM the output will have the opposite logic values.

    Bernd_Stein

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    19.04.2011
    Ort
    Aachen
    Alter
    35
    Beiträge
    22
    Das ist allerdings seltsam, dann müsste bei 0x00 die LED immer aus sein und bei 0xFF immer an, aber genau das ist nicht der Fall. Die LED leuchtet immer mit derselben Helligkeit.
    Stimmt vielleicht doch etwas mit meiner PWM nicht?
    Warum konnte ich denn ganz klar ein blinken/flackern mit größerem Prescaler feststellen?

  4. #4
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    54
    Beiträge
    407
    Zeig uns doch mal dein ganzes Programm.
    Ein Oszilloskop scheinst Du ja leider nicht zu besitzen, da könnte man schön sehen was Überhaupt passiert.
    Versuche mit Prescaler auf 1024 brachten doch Erfolg. Es gibt ja noch die Möglichkeit den Systemtakt zu verringern.
    Entweder durch einen anderen Quarz oder durch einen Vorteiler. Dazu muß man glaube ich an den FUSE-Bits etwas ändern.
    Da sollte man jedoch gur aufpassen, sonst kann es passieren das der µC nicht mehr Ansprechbar ist.

    Bernd_Stein

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    19.04.2011
    Ort
    Aachen
    Alter
    35
    Beiträge
    22
    Gerne, das ist allerdings schon etwas umfangreicher. Bitte entschuldigt auch, wenn es nicht aufgeräumt ist, bin ja noch mitten im Testen und baue deswegen oft um...
    Das prog-Register wird am Anfang übrigens mit 4 geladen, damit ich direkt im Fading-Programm bin und testen kann. Normalerweise wird das Register mit 0 geladen...

    Hier der Code
    Code:
    ;**********************************************************************************
    ;Beschreibung:
    ;Dieses Programm lässt verschiedene "Licht-Programme" an PortB und Port D des
    ;des Mikrocontrollers ablaufen. Timer1 ist der "Programm-Timer" und
    ;Timer0 der BlinkTimer für die Programme. Timer2 dient zum LED-Fading als PWM.
    ;**********************************************************************************
    
    .include "m8def.inc"  ;Die Definitionsdatei des ATmega8 einfügen.
    
    .def temp   	= R16	;Es werden in diesem Programm 2 Arbeitsregister benötigt.
    .def temp2  	= R17	;benötigt: R16 und R17 (ginge auch mit nur einem).
    .def prog		= R18	;Aktuelles Programm
    .def runs		= R19	;Erster Timerdurchlauf
    
    rjmp RESET ; Reset Handler
    reti	; IRQ0 Handler
    reti	; IRQ1 Handler
    rjmp Timer2_CompareHandler	; Timer2 Compare Handler	=> Zur LED-Dimmung
    reti	; Timer2 Overflow Handler	
    reti	; Timer1 Capture Handler
    reti	; Timer1 CompareA Handler
    reti	; Timer1 CompareB Handler
    rjmp Timer1_Overflow	; Timer1 Overflow Handler		=> Programmwechsel
    rjmp Timer0_Overflow	; Timer0 Overflow Handler		=> zyklischer Programmablauf (blinken, aufsteigend, absteigend, ...)
    reti	; SPI Transfer Complete Handler
    reti	; USART RX Complete Handler
    reti	; UDR Empty Handler
    reti	; USART TX Complete Handler
    reti	; ADC Conversion Complete Handler
    reti	; EEPROM Ready Handler
    reti	; Analog Comparator Handler
    reti	; Two-wire Serial Interface Handler
    reti	; Store Program Memory Ready Handler
    
    reset:
    ldi temp, LOW(RAMEND)	;Initialisieren des StackPointers:
    out SPL, temp
    ldi temp, HIGH(RAMEND)
    out SPH, temp
    
    ;============================ Int. Oszillator kalibrieren ============================
    ldi temp, $C2		;Diesen Wert im STK500-Steuerpanel ablesen unter "Advanced" (dort wird	
    out OSCCAL, temp 	;auch die gewünschte Frequenz des int. Oszillators eingestellt).
    
    ;============================ Timer0 ============================	(Erstmal auskommentiert, denn Timer0 soll in Timer1 gestartet werden)
    ;ldi temp, 0b101 ;Timer0 starten mit Vorteiler 1:1024 (Teilt die Blinkfrequenz durch 1024)
    ;out TCCR0, temp ;TCCR0 ist das Kontrollregister des Timers 0
    
    ;============================ Timer ============================
    ldi temp, 1<<TOIE1 | 1 <<TOIE0	; Timer0-Overflow und Timer1-Overflow "erlauben"
    out TIMSK, temp
    
    ldi temp, 0xFF			; Timer1 "vorspulen"
    out TCNT1H, temp
    ldi temp, 0xFE
    out TCNT1L, temp
    ldi temp, 1<<CS12|1<<CS10	;Timer1 starten mit Vorteiler 1:1024 (Teilt die Frequenz durch 1024)
    ;ldi temp, 1<<CS11	; nur zu Debug-Zwecken
    out TCCR1B, temp
    
    
    ser temp				;Arbeitsregister "temp" mit Einsern füllen.
    out DDRB, temp			;Datenrichtungsregister des Ports B mit Einsern aus "temp" füllen (= alle Pins des Ports als AUSGANG)
    out PORTB, temp			;Alle Pins des Ports auf's High-Level bringen
    
    out DDRD, temp			; Alle Pins von PortD als Ausgang festlegen
    out PORTD, temp			; Alle Pins auf HIGH setzen
    
    ldi prog, 4				; Bei Programm 0 beginnen
    
    
    sei		;Interrupts freigeben
    ;------------------------------
    
    ; ============================ Hauptprogramm ============================
    loop:	
    	;Warten auf Timer0/1-Überlauf in einer Endlosschleife.
    rjmp loop
    
    ; ============================ Hauptprogramm Ende ============================
    
    
    
    ; ============================ Programmwechsel-Timer ============================
    Timer1_Overflow:
    push temp		    ; Sichern von "TEMP" im Stack
    in	 temp, SREG		; Einlesen des SREG 
    push temp	    	; Schreiben von  SREG  im Stack (KOPIE)
    
    cpi prog, 5			; Programmüberlauf?
    BRGE resetProg
    rjmp continue
    resetProg:
    	CLR prog
    continue:
    ldi temp, 0b000		; Timer0 beenden (Kein Blinken)
    out TCCR0, temp
    
    ldi temp, 0xFF		; LEDs jetzt an
    out PORTB, temp
    out PORTD, temp
    ldi runs, 0
    
    cpi prog, 0
    brne Prog1
    	;Prog0 ausfuehren: LEDs an (schon geschehen)
    	rjmp ende
    Prog1:
    	cpi prog, 1
    	brne Prog2
    	;Prog1 ausfuehren: LEDs blinken
    	ldi temp, 0xFE
    	out TCNT0, temp
    	ldi temp, 0b101 ;Timer0 starten
    	out TCCR0, temp
    	rjmp ende
    Prog2:
    	cpi prog, 2
    	brne Prog3
    	;Prog2 ausfuehren: LEDs absteigend
    	ldi temp, 0xFF
    	out TCNT0, temp
    	ldi temp, 0b101 ;Timer0 starten mit Vorteiler 1:1024 (Teilt die Blinkfrequenz durch 1024)
    	out TCCR0, temp
    	rjmp ende
    Prog3:
    	cpi prog, 3
    	brne Prog4
    	;Prog3 ausfuehren: LEDs aufsteigend
    	ldi temp, 0xFF
    	out TCNT0, temp
    	ldi temp, 0b101
    	out TCCR0, temp
    	ldi temp, 0
    	out PORTB, temp
    	out PORTD, temp
    	rjmp ende
    Prog4:
    	cpi prog, 4
    	brne ende
    	; Prog4 ausfuehren: Test-Fading
    	ldi temp, 0x01	; Zur Kontrolle die ersten beiden LEDs einschalten
    	out PORTB, temp
    	out PORTD, temp
    
    	ldi temp, 1<<OCIE2 | 1<<TOIE1 | 1 <<TOIE0	; Timer0-Overflow und Timer1-Overflow und Timer2-Compare "erlauben"
    	out TIMSK, temp
    	ldi temp, 1 << COM20 | 1 << WGM21 | 0 << CS22 | 1 << CS21 | 0 << CS20	; Phasenkorrekte PWM und Prescaler setzen
    	out TCCR2, temp
    	ldi temp, 0x00	; Irgendein Startwert fuer OCR2 (Unsere Helligkeit)
    	out OCR2, temp
    
    
    	rjmp ende
    ende:
    	inc prog
      	pop  temp      		; LESEN von SREG vom STACK (KOPIE)
      	out  SREG, temp		; Wiederherstellen von SREG
      	pop  temp      		; Wiederherstellen von "TEMP" 
      	reti
    
    ; ============================ Programmwechsel-Timer Ende ============================
    
    
    
    ; ============================ Timer0 Overflow (Blinken) ============================
    Timer0_Overflow: ;Die Blink-ISR lässt die LED am Pin 0 am PORTB (=PB0) blinken.
    push temp		    ; Sichern von "TEMP" im Stack
    in	 temp, SREG		; Einlesen des SREG 
    push temp	    	; Schreiben von  SREG  im Stack (KOPIE)
    
    ; ==== Programmreihenfolge ====
    cpi prog, 2
    breq blinken
    cpi prog, 3
    breq absteigend
    cpi prog, 4
    breq aufsteigend
    cpi prog, 5
    breq fading
    rjmp end
    
    blinken:
    	sbic PORTB, 0		;Nächsten Befehl überspringen, falls Bit0 abm PortB ist AUS (= LED ist EIN)	
    		rjmp led_ein	;Ansonsten LED einschalten (s. unten).
    	sbis PORTB,0		;Überspringen, falls Bit0 abm PortB ist EIN (= LED ist AUS)	
    		rjmp led_aus	;Ansonsten LED ausschalten (s. unten).
    
    	led_ein:		;Zum Einschalten:
    		ldi temp, 0x00
    		out PORTB, temp
    		out PORTD, temp
    		rjmp end	;und beenden.
    	led_aus:		;Zum Ausschalten:
    		ldi temp, 0xFF
    		out PORTB, temp
    		out PORTD, temp
    		rjmp end
    
    absteigend:
    	in temp, PORTB	; Aktuellen Zustand holen
    	LSL temp		; Linksshift
    	out PORTB, temp	; Ausgeben
    	out PORTD, temp
    	cpi temp, 0
    	breq absteigend2
    	rjmp end
    absteigend2:
    	LDI temp, 0xFF
    	out PORTB, temp
    	out PORTD, temp
    	rjmp end
    
    aufsteigend:
    	in temp, PORTB	; Aktuellen Zustand holen
    	COM temp
    	LSL temp		; 0 rein
    	COM temp		; Aus reingekommener 0 eine 1 machen
    	out PORTB, temp	; Ausgeben
    	out PORTD, temp
    	cpi temp, 0xFF
    	breq aufsteigend2
    	rjmp end
    aufsteigend2:
    	LDI temp, 0
    	out PORTB, temp
    	out PORTD, temp
    	rjmp end
    
    fading:	; ==== TODO ====
    		; Hier später Helligkeit variieren
    
    end:
    	inc runs
    	rjmp exit
    
    exit:
    	pop	temp			; LESEN von SREG vom STACK (KOPIE)
    	out	SREG, temp		; Wiederherstellen von SREG
    	pop	temp			; Wiederherstellen von "TEMP" 
    	reti				; ISR beenden.
    ; ============================ Timer0 Overflow (Blinken) Ende ============================
    
    Timer2_CompareHandler:
    ; Hier später LEDs an PORTB und D togglen
    reti
    (Am interessantesten sollte wohl die Prog4-Headline oder Prog4-Marke oder Prog4-Label oder wie das heißt sein)

    Was das Programm machen soll, habe ich ja schon im ersten Post geschrieben...
    Gibt es hier eigentlich auch spezielle Assembler-Tags anstatt der generischen Code-Tags?

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von Bernd_Stein
    Registriert seit
    19.09.2008
    Ort
    Deutschland : Nordrhein-Westfalen ( NRW )
    Alter
    54
    Beiträge
    407
    Hallo,

    ich werde einfach nicht aus deinem Code schlau.
    Du erzeugst ja verschiedene Lichtspiele die nacheinander ablaufen.
    Prog2 => blinken, Prog3 => absteigend, Prog4 => aufsteigend.
    Fading wäre ja Prog5 und dort ist ja erstmal nichts.

    Funktionieren die Programmteile ( Prog2 usw. ) denn für sich alleine ?
    Damit meine ich das z.B. nur immer Prog2 läuft.

    Bernd_Stein

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    19.04.2011
    Ort
    Aachen
    Alter
    35
    Beiträge
    22
    Ja, die funktionieren an und für sich. Das Programm 5 (Fading) in Timer2 leer ist, liegt daran, dass ich erstmal die PWM testen wollte. Wenn die später funktioniert, wollte ich in Timer2 die Helligkeit variieren lassen.
    Solange das da noch leer ist, wird Programm 5 ähnlich Programm 1 (Alle LEDs an => braucht kein Timer) nur im Programmwechseltimer (Timer 1) ausgeführt.
    Ich hab von anderer Stelle einen Tipp bekommen, dass ich WGM21 auf 1 gesetzt habe, was dem CTC-Mode entspricht. Für eine Phasenkorrekte PWM müsste aber WGM21 auf 0 und WGM20 auf 1 gesetzt werden.

    Ich werde das heute abend mal testen und mich dann wieder melden...

    Schönen Nachmittag noch

    EDIT: Das verwirrt mich aber auch wieder. Laut Datenblatt kann Timer2 doch nur eine phasenkorrekte PWM. Warum steht im Datenblatt in Table42 dann, dass ich WGM21 und WGM20 auf 1 setzen muss, um eine FastPWM zu benutzen??

Ähnliche Themen

  1. Atmega8 PWM - Timer2 - Pin17 ?
    Von hellraider im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 9
    Letzter Beitrag: 03.07.2011, 16:23
  2. Mit Atmega8 Hardware PWM mit Timer2
    Von hosti im Forum C - Programmierung (GCC u.a.)
    Antworten: 46
    Letzter Beitrag: 12.07.2009, 18:16
  3. Timer2 Atmega8
    Von Brantiko im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 17.03.2009, 07:13
  4. Problem mit dem Timer2 eines ATMega8
    Von sloti im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 01.07.2008, 21:48
  5. Servosteuerung mit Timer2 Atmega8
    Von apfeldieb im Forum Motoren
    Antworten: 0
    Letzter Beitrag: 05.04.2008, 17:29

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress