- 12V Akku mit 280 Ah bauen         
Seite 2 von 5 ErsteErste 1234 ... LetzteLetzte
Ergebnis 11 bis 20 von 47

Thema: Mit Atmega8 Hardware PWM mit Timer2

  1. #11
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.05.2008
    Ort
    Oststeinbek
    Alter
    35
    Beiträge
    607
    Anzeige

    Praxistest und DIY Projekte
    Du kannst, um den Timer abzuschalten einfach den Prescaler auf 0 setzen (in TCCR2).
    Genauso kanst du TCCR2 ganz löschen (auf 0x00 setzten), was fast den selben Effekt hat, nur dass es zusätzlich (zu deinem Vorteil) die normale Port-operation wieder freigibt (also vergiss nicht den PORT als Ausgang, und auf GND zu legen).

    Wie schaltest du den Timer wieder an?: du Setzt TCCR2 einfach wieder auf den Wert, der er vorher war, bevor du das Register gelöscht hast.
    Und wann stellst du den Timer wieder an?: Hierzu benutzt du den "Input Capture Interrupt" des 16bit-Timers, der ja jede 20ms auftritt. (ISR(TIMER1_CAPT_vect){...}). Vergiss nicht, ihn zu initialisieren: TIMSK |= (1<<TICIE1);
    In ihm machst du also: TCCR2 = (1<<WGM20) | (1<<COM21) | (1<<CS22);

    So sollte es eigentlich funktionieren. Wenn nicht, schick mir das Programm, dann schau ich mir das nochmal an.

    Gruß, Yaro

  2. #12
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Klappt leider nicht, es scheint als würde TCCR2 nicht auf Null gesetzt werden. Oder der Timer gleich wieder gestartet.
    Mein Code sieht komplett im Moment so aus:

    Code:
    #include <avr/io.h>         // I/O Port definitions 
    #include <avr/interrupt.h>   // Interrupt macros 
    
    #define F_CPU 16000000 
    #define timer 236
    
    volatile int ms = 0;
    
    void pwm_init(void) 
    {
    	TIMSK |= (1<<TICIE1);
    		
    	//Timer 1 (Port 0/1)
    	TCCR1A = (1<<COM1A1)| (1<<COM1B1); 	//Clear OC on Comp Match when up-count, set downcount
    	TCCR1B = (1<<WGM13) | (1<<CS11) ;	//PWM Phase abd Freq Correct. Prescaler 8
    
    	ICR1 = 20000;	//Periodendauer Servo 20ms
    	OCR1A = 1000;	//Servosignal (Port 0)
    	OCR1B = 1000;	//Servosignal (PORT 1)
    
    	//Timer 2 (Port 2)
    	TCCR2 = (1<<WGM20)| (1<<COM21) /*| (1<<CS21)*/ | (1<<CS22);
    	OCR2 = 150;
    	
    };
    
    ISR(TIMER2_OVF_vect)
    {
    	TCCR2 = 0x00;
    };
    
    ISR(TIMER1_CAPT_vect)
    {
    	TCCR2 = (1<<WGM20) | (1<<COM21) | (1<<CS22);
    };
    
    /*void timer_init(void)
    {
    	
    	TCCR0 |= (1<<CS01);
    	TCNT0 = timer;
    	TIMSK |= (1<<TOIE0);
    	TIFR |= (1<<TOV0);
    };
    
    ISR(TIMER0_OVF_vect)
    {
    	TCNT0 = timer;
    	ms++;
    	if (ms >= 1000)
    	{
    		OCR1A++; 
    		ms = 0; 
    	}
    	if (OCR1A >= 2000)
    		OCR1A = 1000;
    
    };*/
    
    int main(void) 
    {
    	//Initialisierungen
    	sei(); //Globale Interupts zulassen
    	pwm_init();	//PWM initialisieren
    	/*timer_init(); //Timer initialisieren*/
    
    	DDRB |= (1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3);			//B... AUSGANG
    	PORTB &= ~((1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3));		//B.. Low
    
    	while(1)
    	{
    
    	}
    
    }

  3. #13
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.05.2008
    Ort
    Oststeinbek
    Alter
    35
    Beiträge
    607
    Damit ein Interrupt ausgelöst wird muss generell folgendes geschehen: das I-bit in SREG muss gesetzt sein, der Interrupt muss freigeschaltet sein, das interruptauslösende Ereigniss muss auftreten.
    2 davon hast du gemacht, 1 nicht. =)

    TIMSK | = (1<<TOIE2);

    Nicht vergessen: immer, wenn du ein interrupt benutzen willst, musst du ihn erstmal erlauben (freischalten)

    Damit sollte es funktionieren.

    Und noch ein Tipp: wenn du Konstanten eingibst, die größer sind als 32768, dann schreibe ein UL (= unsigned long) dahinter, denn viele compiler nehmen konstanten generell als ein int auf, was bei den AVRs 16bit ist. Also: F_CPU 16000000UL (ist besser).

    Gruß, Yaro

  4. #14
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Ok, das hat was geändert. Danke dir
    Aber ich krieg jetzt ein Signal das .5ms high .8ms low .6ms high und dann
    14ms low ist.

  5. #15
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.05.2008
    Ort
    Oststeinbek
    Alter
    35
    Beiträge
    607
    wow.....das ist wirklich seltsam......
    Wie kommst du auf diese Zeiten? Wie hast du sie gemessen? Mit einem Oszi?
    Wenn es digital ist, könntest du dann die Kurven posten (neu und alt)?
    Du könntest versuchen, TCNT2 im Interrupt des 16bit Timers auf 0x00 zu setzen, sollte aber nur minimalen Erfolg bringen.

    [edit]Versuch den Timer2 mal auf Fast-PWM umzustellen, das sollte eine deutlich Verbesserung bringen. Achte dabei auf die Frequenz, wirst den Prescaler auf eine Stufe höher stellen müssen, da Fast-PWM doppelt so schnell ist, wie phase-correct PWM.

  6. #16
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Ich hab jetzt das ganze invertiert, sprich es wird gesetzt beim hochzählen und gelöscht beim runterzählen.
    So funktionierts, mit dem Nachteil das ich auch OCR2 invertiert übergeben muss.

    Da gibts aber noch Fast PWM und das funktioniert perfekt (Es sieht auf jedenfall so aus )

    Vielen herzlichen dank für deine wirklich tolle Hilfe =D>

  7. #17
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.05.2008
    Ort
    Oststeinbek
    Alter
    35
    Beiträge
    607
    Immer doch gerne.

    Mich interessiert trotzdem noch, wie du die Zeiten gemessen hast =)

    Gruß, Yaro

  8. #18
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Achso entschuldige, mit einem Oszi
    Das Ding ist sowas von praktisch wen's um solche Signale geht.

  9. #19
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    02.05.2004
    Alter
    39
    Beiträge
    388
    Ich krieg die Krise

    Die sache läuft ja jetzt... könnte man meinen.

    Auf dem Oszi sehen alle Signale gleich aus.

    Wen ich die ersten beiden PWMkanäle benutze fahren die Servos bei 1,5ms Highflanke in die mitte,
    Wen ich aber den dritten Kanal benutze fährt das Servo an eine Positon die weiter liegt als der mechanische Anschlag. Also völlig falsch da es auch zur Mitte fahren sollte.

    Ich hab mit dem Oszi die Signale verglichen. Und der einzige Unterschied von Signal drei zu den anderen ist der, dass es 10ms später startet.
    Das heisst die beiden ersten Signale haben im gleichen Moment die Highflanke und das dritte hat erst 10ms später die Highflanke.

    Aber das sollte dem Servo doch egal sein, das interessiert sich doch nur für die 1-2ms High und eine Periodendauer von 20ms.

    Am Servo liegt es nicht!

    Ich bin am verzweifeln.

    Die ersten beiden Signale:
    Bild hier  
    Das erste und das dritte Signal:
    Bild hier  

  10. #20
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.05.2008
    Ort
    Oststeinbek
    Alter
    35
    Beiträge
    607
    Hmm das ist wirklich sehr komisch! Dem Servo sollte das eigentlich egal sein... er weiß doch nicht, wie sich die beiden anderen verhalten... und sollte sich dafür auch nicht kümmern.

    Wie sieht es denn mit deiner Hardware aus? was genau hast du gebaut? besteht womöglich die Möglichkeit, dass der dritte Servo gestört wird? Hast du vielleicht irgendeinen unbemerkten Kontakt mit einem anderen Leiter? (jetzt nicht auf der Signalleitung sondern auf der Versorgungsleitung des Servos)

    Diese 4 (2Paar) Pukte in der unteren Mitte der Bildes, kommen die vom Controller, oder zeichnet sie das Oszi immer dahin?

    Gruß, Yaro

Seite 2 von 5 ErsteErste 1234 ... LetzteLetzte

Berechtigungen

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

12V Akku bauen