-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: ATtiny2313 ISR wirft mein Timing durcheinander

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    23.07.2011
    Beiträge
    16

    ATtiny2313 ISR wirft mein Timing durcheinander

    Anzeige

    Mein Ziel ist es von zwei LEDs die eine im definierten Abstand blinken zu lassen, während die andere über den Fast PWM Modus von Timer0 an/aus fadet. Dabei verwende ich zum hoch/runterzählen der OCR0A keine Schleife mit den (üblichen) 12ms als Wartezeit (also nicht _delay_ms(12); wie ich es vorher hatte), sondern hab den Prescaler auf 64 eingestellt und lasse eine ISR bei Compare Match OCR0A verändern. Das kommt auch ganz gut hin, also der Verlauf sieht so flüssig aus, wie ichs gerne hätte, jedoch kommt die andere, blinkende LED immer wieder ins Stocken.
    Code:
    #define F_CPU 1000000UL
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h> 
    
    volatile  uint8_t OCR0Adirection=0, OCR0Avalue=1; 
    			 //0->OCR0A raufzählen 1-> OCR0A runterzählen
    
    	ISR(TIMER0_COMPA_vect){
    
    		if(OCR0Adirection==0){
    			OCR0Avalue += 1;
    			if(OCR0Avalue==254) OCR0Adirection=1;
    		}else
    
    		if(OCR0Adirection==1){
    			OCR0Avalue -= 1;
    			if(OCR0Avalue==1) OCR0Adirection=0;
    		}
    		OCR0A = OCR0Avalue; //nur einmal schreiben, statt zweimal lesen und einmal schreiben
    	}
    
    
    
    int main (void)
    {
                         
                    TCCR0A = (1 << COM0A1) | (1 << COM0A0) | (1 << WGM00) | (1 << WGM01);
                    
    
    		TCCR0B = (1 << CS00) | (1 << CS01);
    
                    OCR0A = 1; 
    
                    DDRB = (1 << PB2); //pin PB2 auf Ausgang (das ist OC0A)
    				
                    DDRD = (1 << PD5);//die blinkende led
                   	
    		TIMSK = (1 << OCIE0A);
    			   	
    		sei();
    
                    while(1){
                           
    					PORTD &= ~(1<<PD5); //pins auf 0
    					_delay_ms(100);
                   		PORTD |= (1<<PD5);  //pins auf 1
    					_delay_ms(100);
              
                    }
    }
    Immer wenn die LED an PB2 grade besonders hell oder besonders dunkel ist, also an den Wechselpunkten,
    macht die LED an PD5 nur noch ganz kurze delays im Aus-Zustand.
    Meine Theorie ist, dass es an den Ifs liegt, die OCR0Adirection umschreiben, was anderes, besonderes passiert ja nicht.
    Kann man das irgentwie besser ins Gleichgewicht bringen? Meine ISR ist ja eigentlich gar nicht so lang und wenn die den Programmablauf schon so sehr beeinflusst, wie würde es dann erst bei etwas längeren Methoden aussehen...

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Bei dem Programm hätte ich erwartet das die LED immer relativ schnell blinkt. 100 ms sind ja nicht so lang, auch wenn das dann durch die Interrupts nochmal etwas gedehnt wird. Länger wird die Verzögerung, wenn ohne Optimierung übersetzt wurde.

    So langsam sollten die Interrupts so auch nicht werden. Da muss noch was anderes Faul sein.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    23.07.2011
    Beiträge
    16
    Also die blinkende LED blinkt vom Empfinden her ca. eine viertel Sekunde lang, also so, dass man es noch deutlich als blinken wahrnimmt. Wie gesagt, sind die Aus-Phasen an den (ich nenne sie mal) Scheitelpunkten des Timers nur noch ganz kurz, man sieht kaum noch, dass sie überhaupt mal aus geht.
    Was mir noch aufgefallen ist; wenn man statt der 5V USB_Spannung zwei Batterien anschließt (~3V), sind die LEDs natürlich dunkler, aber außerdem scheint das Problem ins Gegenteil umzuschlagen.
    Die fadende LED am Timer geht nun so langsam an/aus, dass man sie flackern sieht (sie ist an Timer0-Fast PWM mit 255 Schritten angeschlossen). Die blinkende LED hingegen blinkt dann konstant mit immer der selben Geschwindigkeit.
    Ich dachte durch eine niedriegere Spannung verringert sich der CPU-Takt und es wären alle Komponenten gleichermaßen betroffen. Aber anscheinend muss es zwischen Taktgeber und Timer0 etwas geben, dass den Timer bei niedrigerer Spannung nochmals zusätzlich verlangsamt und dass es zwischen Taktgeber und CPU (also der main-Funktion) nicht gibt.
    Wie es aussieht wird die ISR wegen dem verlangsamten Timer nun nur noch so selten aufgerufen, dass mehr Leistung für die Schleife im Hauptprogramm übrig bleibt.

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.190
    Ich habe dein Programm mal in mein Testboard gespielt. Deinen beschriebenen Fehler kann ich nicht nachvollziehen.
    Die LED blinkt konstant, auch das faden ist konstant.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    23.07.2011
    Beiträge
    16
    Das ist ja sehr merkwürdig. Worin könnten sich unsere Aufbauten denn unterscheiden... Ich hab den 2313 auf einem Steckbrett mit Leitungen von den Pins zu vier Transistoren (versorgen die LEDs mit Strom, da ich nicht wusste ob mir sonst irgentwann noch der Chip durchbrennt) und als Board das DFRobot USBTinyISP.
    Jetzt bin ich noch verwirrter als vorher^^. Aber danke fürs Austesten.
    Eigentlich war das sowieso nur eine Art Verständnistest; ums mal gemacht zu haben.
    Ich denke mal diese Wartefunktion wird man in der Praxis, also einem etwas "sinnvolleren" Vorhaben sowieso möglichst nicht einsetzen. Inzwischen hab ich die rausgenommen und statt der einen blinkenden jetzt drei LEDs angeschlossen, die im Zeitabstand der Reihe nach leuchten sollen. Dieser Abstand kommt aber nicht mehr durchs Warten zu stande, sondern ist an die Variable, die ich für den OCR0A-Wert hab, gekoppelt. Das funktioniert auch alles so wie ichs mir vorgestellt hab.


    Code:
    #define F_CPU 1000000UL
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h> 
    
    volatile  uint8_t OCR0Adirection=0, OCR0Avalue=1; 
    			 //0->OCR0A raufzählen 1-> OCR0A runterzählen
    
    	ISR(TIMER0_COMPA_vect){
    
    		if(OCR0Adirection==0){
    			OCR0Avalue += 1;
    			if(OCR0Avalue==254) OCR0Adirection=1;
    		}else
    
    		//if(OCR0Adirection==1){ //kann eingespart werden
    		{
    			OCR0Avalue -= 1;
    			if(OCR0Avalue==1) OCR0Adirection=0;
    		}
    		OCR0A = OCR0Avalue; //nur einmal schreiben, statt zweimal lesen und einmal schreiben
    	}
    
    uint8_t CurrentLED=0;
    
    void LEDleuchten(){
    
    	if(OCR0Avalue==1 || OCR0Avalue==64 || OCR0Avalue==128 
    					|| OCR0Avalue==192 || OCR0Avalue==254){//wenn timer0 am endpunkt
    
    		switch(CurrentLED){//erst die betroffene LED aus
    			case 0: PORTB &= ~(1<<PB4); break;
    			case 1: PORTD &= ~(1<<PD5); break; 
    			case 2: PORTA &= ~(1<<PA0); 
    		}
    
    		CurrentLED++;//dann zur nächsten wechseln
    		if(CurrentLED==3)CurrentLED=0;
    		
    		switch(CurrentLED){//und diese anschalten
    			case 0: PORTB |= (1<<PB4); break; 
    			case 1: PORTD |= (1<<PD5); break; 
    			case 2: PORTA |= (1<<PA0); 
    		}	
    
    		while(OCR0Avalue==1 || OCR0Avalue==64 || OCR0Avalue==128 
    		   || OCR0Avalue==192 || OCR0Avalue==254){}//weil sonst sofort weitergeschaltet wird		
    	}	
    }
    
    int main (void)
    {
            
                   
                    TCCR0A = (1 << COM0A1) | (1 << COM0A0) | (1 << WGM00) | (1 << WGM01);
                    
    
                    //TCCR0B = (1 << CS01);
                    //Prescaler auf CPU/8 -> perfekt^^
    				TCCR0B = (1 << CS00) | (1 << CS01);
    
                    OCR0A = 1; //Startwert, pendelt dann zwischen 0..255
    
                    DDRB = (1 << PB2); //pin PB2 auf Ausgang (das ist OC0A)
    				
    				//blinkende led PB4, PD5, PA0
                   	DDRD |= (1 << PD5);
    				DDRB |= (1 << PB4);
    				DDRA |= (1 << PA0);
    
    				TIMSK = (1 << OCIE0A);
    			   	
    				sei();
    
                    while(1){
    
    					LEDleuchten();
                           
    					
                   		
    
              
                    }
    
    }

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Ein Unterschied könnten die Optionen beim compilieren sein. Wenn man delay verwendet sollte man unbedingt mit Optimierung übersetzen. Auch kann sich die Länger der ISR dadurch verändern. Es macht da schon einen Unterschied ob die ISR 40% oder 90 % der Rechenzeit benötigt.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    23.07.2011
    Beiträge
    16
    Bei Optimierungen steht bei mir im Avr-Studio 4 -Os aber weiß nicht was das genau bedeutet. Dass man die bei delay an haben sollte, hab ich auch schonmal gelesen, und dachte die wären default-mäßig an.

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.190
    Mit -Os kompiliere ich auch. Muss doch was mit dem Aufbau zu tun haben. Ich habe das Eval-Board von Pollin.
    Wie nach deinem letzten Code die Led an PortA leuchtet würde mich interessieren.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    23.07.2011
    Beiträge
    16
    Die leuchtet eigentlich wie die anderen auch, oder hast du irgenteine Unstimmigkeit entdeckt?
    Das Einzige was mich etwas wundert ist, wieso am Anfang die an PD5 leuchtet. Es sollte doch mit PB4 anfangen..

  10. #10
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.190
    Ich habe einen Quarz dran, daher ist der PortA bei mir nicht verfügbar, das ist die Unstimmigkeit.
    Du schaltetst die Leds aus, erhöhst und schaltest dann ein.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Atmega8 identify wirft wechselnde id
    Von apohero im Forum AVR Hardwarethemen
    Antworten: 8
    Letzter Beitrag: 20.03.2008, 14:16
  2. AVR controller.. bin durcheinander
    Von Robin1508 im Forum AVR Hardwarethemen
    Antworten: 19
    Letzter Beitrag: 11.11.2007, 21:35
  3. Antworten: 6
    Letzter Beitrag: 09.09.2006, 10:46
  4. Motor bringt Controller durcheinander
    Von scales im Forum Elektronik
    Antworten: 8
    Letzter Beitrag: 01.09.2006, 18:36
  5. RN-Control piept bei Programmablauf - kommt durcheinander
    Von robinhh im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 10.02.2006, 09:53

Berechtigungen

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