- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 35

Thema: PWM

  1. #11
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.02.2006
    Alter
    37
    Beiträge
    140
    Anzeige

    Powerstation Test
    Simmt, da hast du natürlich recht das das vielleicht ein Vorteil wäre gleich einen eigenen µC dafür zu verwende. Trotzdem würde ich gerne wissen wie Timer funktionieren.

    Wie kann ich meinen PWM Ausgang auf ein Interrupt legen? Wenn jedesmal ein Interrupt ausgelöst wird, wenn der Timmer umschaltet, kann ich ja Softwartechnisch alles dazu machen das ich daraus eine Aktion Programmiere um Ausgänge ein/aus zu schalten. Ich verstehe nur nicht wie ich einen Interrupt auslöse

    mfg Gerko

  2. #12
    Benutzer Stammmitglied
    Registriert seit
    02.05.2005
    Ort
    Bremen
    Beiträge
    35
    Hallo Gerko,
    bin auch Lernender und bin mir nicht sicher, daß ich deinen Code richtig verstehe. Wenn du einen Timer-Int willst, wenn der Timer0 einen OV-Int auslösen soll, dann muß ins Register TIMSK noch TOIE0 hinein.

    Gruß!

  3. #13
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.02.2006
    Alter
    37
    Beiträge
    140
    Hallo Leute!

    Ich habe jetzt wieder mal ein bischen herumexperimentiert, aber ich komme zu keinem Interrupt. Mitlwerweile verwende ich nicht mehr Phase Correct PWM, sondern CTC.

    Ist CTC überhaupt noch PWM?, dabei wird doch die Frequenz verändert oder?

    Mit diesem Programmcode wird zwar ein Interrupt ausgelöst, aber das Programm springt nicht in die Interruptvektortabelle, sondern einfach nur 3 zeilen weiter rauf. Das Hilft mir sogut wie garnicht.

    Code:
    .include "m16def.inc"
    
    .def temp = r16
    
    .org 0x000               ; kommt ganz an den Anfang des Speichers
    	rjmp main            ; Interruptvektoren überspringen
                             ; und zum Hauptprogramm
    	rjmp EXT_INT0        ; IRQ0 Handler
    	rjmp EXT_INT1        ; IRQ1 Handler
    	reti ;TIM2_COMP
    	reti ;TIM2_OVF
    	reti ;TIM1_CAPT       ; Timer1 Capture Handler
    	reti ;TIM1_COMPA      ; Timer1 CompareA Handler
    	reti ;TIM1_COMPB      ; Timer1 CompareB Handler
    	reti ;TIM1_OVF        ; Timer1 Overflow Handler
    	reti ;TIM0_OVF        ; Timer0 Overflow Handler
    	reti ;SPI_STC         ; SPI Transfer Complete Handler
    	reti ;USART_RXC       ; USART RX Complete Handler
    	reti ;USART_DRE       ; UDR Empty Handler
    	reti ;USART_TXC       ; USART TX Complete Handler
    	reti ;ADC             ; ADC Conversion Complete Interrupt Handler
    	reti ;EE_RDY          ; EEPROM Ready Handler
    	reti ;ANA_COMP        ; Analog Comparator Handler
    	reti ;TWSI            ; Two-wire Serial Interface Handler
    	reti ;SPM_RDY         ; Store Program Memory Ready Handler
    
    main:
    ;Stackpointer
    	ldi temp, LOW(RAMEND)
    	out SPL, temp
    	ldi temp, HIGH(RAMEND)
    	out SPH, temp
    ;Aus/Eingänge
    	ldi temp, 0x00
    	out DDRD, temp			;Eingang
    
    	ldi temp, 0xFF
    	out DDRB, temp			;Ausgang
    ;Interrupteingänge
    	ldi temp, 0b00001001	;INT0 und INT1 konfigurieren
    	out MCUCR, temp
    
    	ldi temp, 0b11000000	;INT0 und INT1 aktivieren
    	out GIMSK, temp
    ;PWM
    	ldi temp, 0b00001001	;Einstellungen siehe Seite 81-83
    	out TCCR0, temp
    
    	ldi temp, 0b00111111
    	out OCR0, temp			;Stellt die Einschaltzeit ein (Alles gesetzte --> immer ein, alles aus --> immer aus)
    	
    	ldi temp, (1<<OCIE0)
    	out TIMSK, temp
    
    	ldi temp, (1<<OCF0)
    	out TIFR, temp
    ;Interrupts freigeben
    	sei						;Interrupts allgemein aktivieren
    	
    Ende:
    	jmp ende
    	
    EXT_INT0:
    	sbi PortB, 0
    	reti
    
    EXT_INT1:
    	cbi PortB, 0
    	reti
    Im Register TIMSK habe ich nun OCIE0 aktiviert, mit TOIE0 passiert garnichts

    Im Register TIFR habe ich OCF0 aktiviert. Brauche ich das TIFR Register überhaupt für einen Interrupt?

    Ich merke allerdings je mehr ich herumprobiere, desto mehr weiche ich von einer richtigen PWM ab. Es muss doch möglich sein, das man einfach mit einer Phase Correct PWM einen Interrupt bei jeder Änderung aufruft oder?

    mfg Gerko

  4. #14
    Benutzer Stammmitglied
    Registriert seit
    02.05.2005
    Ort
    Bremen
    Beiträge
    35
    Das TIFR brauchst du dabei nicht. Du kannst aber im Simulator während er läuft auf das entsprechende Kästchen klicken, warauf dann der entsprechende Int ausgelöst wird.
    Mit Timer0 im Simular habe ich auch Probleme, weil ich noch eine ältere Version des AVR-Studio habe. Das war auch hier meine erste Frage, weil ich sicher war alles richtig gemacht zu haben, nur es einfach nicht funktionieren wollte. Ich habe dann das Ganze probehalber mit Timer1 laufen lassen und da ging es.
    Ja, es wäre vielleicht besser wenn du das Ganze ersteinmal auf eine einfache PWM-Ausgabe an einem Pin reduzierst. Wenn das Codestückchen funktioniert, dann kann man davon ausgehend dazu bauen, bzw umbauen - in kleinen Schritten.

    Weniger ist oft mehr!

    Grüße

  5. #15
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.02.2006
    Alter
    37
    Beiträge
    140
    Was mich beunruhigt ist das ich für den Timer0 nur einen Eintrag in der Interruptvektortabelle habe. Für alle anderen sind mehrere vorhanden.

    Wo ist eigentlich der unterschied zwischen Timer0, 1 und 2? Ich weiß das der Timer0 eien Auflösung von 8Bit hat, und die anderen 2 eine von 16Bit. Gibts sonst noch unterschiede?

    Sollte das OCIE0 Bit im TIMSK Register den Interrupt TIM0_OVF auslösen oder einen anderen?

    mfg Gerko

  6. #16
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Hallo.

    ich fange mal ganz oben an bei der Beantwortung der Fragen die sich bisher aufgestaut haben.
    1. Wie kann man einstellen das man nicht den OCR0 Port als Ausgang für den Timer haben will, sondern PortB, 0?

      In dem man anstatt der Hardware PWM, die manche Timer generieren können eine Software PWM nutzt.
    2. Ist es nicht möglich das man den OCR einfach mit einem anderen Ausgang verbindet?

      Nein, das ist nicht möglich.
    3. ... aber später möchte ich damit ja auch 2 Motoren steuern ...

      Wenn du dafür 2 PWM's benötigst, nimm am besten den Timer 1 oder einen µC, der dieMöglichkeit hat mit jedem Timer 2 Hardware PWM's zu generieren.
    4. Wie kann ich jetzt einstellen das ich nur in der Software einen Ausgang haben will, nicht aber bei einem Hardwareausgang?

      Du lässt die COM?0 & COM?1 Bits auf 0 stehen.
    5. ... Also wie kann ich einen Interrupt auslösen? ... {Anm: Bezug vorherige Frage}

      In dem du im TIMSK Register die einsprechenden Bits setzt.
      Damit kann z.B. ein Interupt ausgelöst werden wenn:
      a) der Zähler überläuft
      b) Der Zählerstand = dem Wert im OCR Register entspricht.
    6. Es muss doch möglich sein, das man einfach mit einer Phase Correct PWM einen Interrupt bei jeder Änderung aufruft oder?

      Wenn sich die Aussage auf eine Änderung des Zählerstandens bezieht, also z.B. von 21 auf 22, dannmuss die Antwort NEIN lauten.
    7. Was mich beunruhigt ist das ich für den Timer0 nur einen Eintrag in der Interruptvektortabelle habe. Für alle anderen sind mehrere vorhanden.

      Es sind auch mehrere ... du hast uns hier schlicht und einfach einen unterschlagen (schau mal im Datenblatt auf Seite 45).


    So, und hier noch ein kleines Codebeispiel (für den ATmega16) zum Thema: "Wie erzeuge ich an jedem X - beliebigen Pin eine Pulsweitenmodulation":

    Code:
    		.nolist
    		.include	"m16def.inc"
    		.list
    
    
    		.def		sregsave 	=	r4					; SREG Backup
    		.def		ch_1		=	r5					; PWM Werte der LED's 
    		.def		ch_2		=	r6
    		.def		ch_3		=	r7
    		.def		ch_4		=	r8
    
    		.def		temp		=	r16					; temporäre Daten
    		.def		pwm_cnt		=	r17
    
    		.CSEG
    		.ORG 0
    
    		jmp			isr_reset							; Reset Interupt Handler
    		jmp			isr_not_used						; INT 0 Interupt Handler 
    		jmp			isr_not_used						; INT 1  Interupt Handler
    		jmp			isr_not_used						; Timer 2 Compare Interupt Handler
    		jmp			isr_not_used						; Timer 2 Overflow Interupt Handler
    		jmp			isr_not_used						; Timer 1 Capture Interupt Handler
    		jmp			isr_not_used						; Timer 1 Compare A Interupt Handler
    		jmp			isr_not_used						; Timer 1 Compare B Interupt Handler
    		jmp			isr_not_used						; Timer 1 Overflow Interupt Handler
    		jmp			isr_not_used						; Timer 0 Overflow Interupt Handler
    		jmp			isr_not_used						; SPI Transfer Complete Interupt Handler
    		jmp			isr_not_used						; USART RX Complete Interupt Handler
    		jmp			isr_not_used						; USART UDR empty Interupt Handler
    		jmp			isr_not_used						; USART TX Complete Interupt Handler
    		jmp			isr_not_used						; ADC Conversion Complete Interupt Handler
    		jmp			isr_not_used						; EEPROM Ready Interupt Handler
    		jmp			isr_not_used						; Analog Comperator Interupt Handler
    		jmp			isr_not_used						; TWI Interupt Handler
    		jmp			isr_not_used						; INT 2 Interupt Handler
    		jmp			isr_t0_cp							; Timer 0 Compare Interupt Handler
    		jmp			isr_not_used						; Store Program Memory Ready Interupt Handler
    
    
    isr_reset:
    		ldi			temp,		high(RAMEND)			; STACK initialisieren
    		out			SPH,		temp
    		ldi			temp,		low(RAMEND)
    		out			SPL,		temp
    
    		in			temp,		MCUCSR					; Disable JTAG Interface
    		ori			temp,		(1<<JTD)
    		out			MCUCSR,		temp
    		out			MCUCSR,		temp
    		
    		clr			temp								; Ports konfigurieren:
    		ldi			temp,		(1<<DDA0)				; PIN A0, B0, C0, D0 -> Ausgang +H
    														; Rest: Eingang + Pullup
    		out			DDRA,		temp					
    		out			DDRB,		temp
    		out			DDRC,		temp
    		out			DDRD,		temp
    		
    		ldi			temp,		0xFF
    		out			PORTA,		temp
    		out			PORTB,		temp
    		out			PORTC,		temp
    		out			PORTD,		temp				
    
    		ldi			temp,		(1<<WGM01) | (1<<CS00)	; Timer 0 konfigurieren
    		out			TCCR0,		temp
    
    		ldi			temp,		0x80
    		out			OCR0,		temp
    
    		ldi			temp,		(1<<OCIE0)				; Timerinterupts aktivieren
    		out			TIMSK,		temp
    
    		ldi			temp,		0x80					; Defaultwerte setzen
    		mov			ch_1,		temp
    		mov			ch_2,		temp
    		mov			ch_3,		temp
    		mov			ch_4,		temp
    		clr			temp
    
    		sei												; Interupts Global aktivieren
    
    main_loop:
    
    		; Irgendwelcher sonstiger Code
    		; Irgendwelcher sonstiger Code
    		; Irgendwelcher sonstiger Code
    
    		jmp			main_loop
    
    isr_not_used:											; Blanko für nicht genutzte Interupt Handler
    		reti
    
    isr_t0_cp:												; Timer 0 Compare Interupt Handler
    		in			sregsave,	SREG					; Statusregister sichern
    
    		inc			pwm_cnt								; Hilfszähler für die PWM um eins erhöhen
    
    		cp			ch_1,		pwm_cnt					; Vergleiche gewünschtes Tastverhältniss mit aktuellem PWM Hilfszählerstand
    		brlo		PC+4
    		breq		PC+3
    		sbi			PORTA,		0
    		rjmp		PC+2
    		cbi			PORTA,		0
    
    		cp			ch_2,		pwm_cnt
    		brlo		PC+4
    		breq		PC+3
    		sbi			PORTB,		0
    		rjmp		PC+2
    		cbi			PORTB,		0
    
    		cp			ch_3,		pwm_cnt
    		brlo		PC+4
    		breq		PC+3
    		sbi			PORTC,		0
    		rjmp		PC+2
    		cbi			PORTC,		0
    
    		cp			ch_4,		pwm_cnt
    		brlo		PC+4
    		breq		PC+3
    		sbi			PORTD,		0
    		rjmp		PC+2
    		cbi			PORTD,		0
    
    		out			SREG,		sregsave				; Statusregister wiederherstellen
    		reti
    Eine Anmerkung zu diesem Code:

    Speziell auf die PWM bezogen ist er sicherlich nicht das Optimum an Code. Dieses hat unter anderem den ganz einfachen Grund, das der derselbige doch noch irgendwo verständlich erscheinen soll, auch ohne das man erst im groß im Datenblatt nachsehen muss, um beispielsweise herauszufinden: Welche Flags denn in welchem Fall bei diversen Befehlen beeinflusst werden und welche Sonderfälle in der PWM hier nun möglich sind.

    Im übrigen, ist eine Software PWM doch eher eine Taktzeitaufwändige Aktion (also in dem Fall 128 * 256 Takte für eine Periode) um die so gedimmten LED's noch flimmerfrei wahrzunehmen (also ich sag mal mit einer Refreshrate von 200 Hz) sollte der µC schon mit ca. 6,55 MHz laufen (128 x 256 x 200) was aufgerundet eben mal 8 MHz sind.

    Vielleicht sollte man noch erwähnen, das es einen kleinen Fallstrick beim STK 500 gibt, da dort die LED's nicht mit "H" sondern mit "L" Pegel leuchten.

    @ Schokohoernl:

    Sicherlich kann man mit einem Vernünftig durchdachtem Code eine 16 oder gar 24 Kanal Software PWM zum Dimmen von LED's erzeugen, aber sicherlich nicht "theoretisch" unendlich viele.

    Die limitierenden Faktoren sind direkt:
    - die Taktfrequenz des Mikrocontrollers
    - der Dauer die die Befehle zum Ausführen benötigen

    und indirekt:
    - die Programmiersprache des Programmieres.


    Grüße,

    da Hanni.

  7. #17
    Benutzer Stammmitglied
    Registriert seit
    02.05.2005
    Ort
    Bremen
    Beiträge
    35
    Hallo da Hanni,
    vielen Dank für den Code. Das meiste davon ist ja typunabhängig und den Teil zu durchblicken brauch ich ein wenig Zeit. Gleich aufgefallen ist mir aber das mit der direkten Verwendung des PC. Die Möglichkeit ist mir bislang noch nicht begegnet. Prima!

    Gruß!

  8. #18
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Zitat Zitat von rungo
    Das meiste davon ist ja typunabhängig
    Ja, sicherlich ist der Großteil recht universell auf diversen ATmegas einsetzbar.

    Zitat Zitat von rungo
    Gleich aufgefallen ist mir aber das mit der direkten Verwendung des PC. Die Möglichkeit ist mir bislang noch nicht begegnet.
    Naja, ehe ich mich bei diesem eher simpel gestricktem Code mit 20 Sprungmarken selbst verwirre, mach ich es in dem Fall lieber so.

    Aber das entscheide ich je nach Fall individuell.

    Grüße,

    Hanni.

  9. #19
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.02.2006
    Alter
    37
    Beiträge
    140
    Danke für diese Ausführliche und sehr Hilfreiche Antwort von Hanni. Ich werde jetzt noch ein Wenig an meinem Code herumbasteln, und anschließend warten bis das STK 500 kommt.

    Das das STK 500 die LEDs bei low und nicht bei high zum leichten bringt war mir bisher nicht bekannt, aber das ist ja für meine jezigen Testzwecke auch nicht so wichtig denke ich.

    Grüße,
    Gerko

  10. #20
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.07.2005
    Beiträge
    569
    Kein Problem, wenn du den Code soweit verstanden hast, meld dich einfach mal, dann erkläre ich mal eine Variante, wie man das ganze unter gewissen Voraussetzungen wesentlich verkürzen kann.

    Grüße,

    Hanni.

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

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

12V Akku bauen