- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 14

Thema: Probleme mit ATtiny2313A wärend Interruptroutine

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    04.06.2017
    Beiträge
    23
    HI Hannes!

    Danke für deine schnelle Antwort.

    Habe den Variablen in volatile Variablen geändert. Die If/Else rausgeschmissen und in switch case geändert.
    Leider bestand das Problem immer noch. Des Rätzels Lösung war, den Toggelbefehl in "else if (c == 2)" in - LED ein - warten - LED aus - warten - zu ändern. Jetzt läuft es fast so wie ich mir das vorgestellt habe.
    Das einzige Problem das jetzt noch besteht ist, dass ich den Schalter teilweise mehrmals betätigen muss um das Blinkmuster zu verändern.
    Woran kann das denn liegen?

    Hier nochmal der geänderte Code:
    Code:
    #define F_CPU 1000000UL
    
    #include <util/delay.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdio.h>
    
    #define LED1 0
    #define LED2 1
    #define LED3 2
    #define LED4 3
    
    //variablen für interrupt
    volatile int a = 1;
    volatile int b = 2;
    volatile int c;
    volatile int d;
    
    int main(void)
    {
    	
    	//I/O-Ports einstellen
    	DDRB = 0b00001111;
    	
    	//Einstellung Interrupt
    	PORTD = 0b00000100;
    	GIMSK = (1<<INT0);
    
    	//Globale interrupts aktivieren
    	sei();
    	
    	//Wert in Variable setzen
    	c = 2;
    	
    	while (1)
    	{
    		
    		switch(c)
    		
    		{
    			case 1:
    				PORTB |= ((1<<LED1) | (1<<LED3));	//LED1 und 3 ein
    				PORTB &= ~((1<<LED2) | (1<<LED4));	//LED2 und 4 aus
    		
    				_delay_ms(500);
    		
    				PORTB |= ((1<<LED2) | (1<<LED4));	//LED2 und 4 ein
    				PORTB &= ~((1<<LED1) | (1<<LED3));	//LED1 und 3 aus
    		
    				_delay_ms(500);
    			break;
    			case 2:
    				PORTB |= ((1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4));	//LED1-4 ein
    				_delay_ms(500);
    				PORTB &= ~((1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4));	//LED1-4 aus
    				_delay_ms(500);
    			break;
    			
    		}		
    		
    	}
    
    }
    
    ISR(INT0_vect)
    
    {
    	
    	{
    		
    		//switch case Abfrage
    		switch(c)
    		{
    			case 1: d = b;
    			break;
    			case 2: d = a;
    			break;
    			default: PORTB &= ~((1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4));
    		}
    	
    	c = d;
    	return;
    	_delay_ms(250);
    
            }
    }
    Gruß Alex

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Zitat Zitat von Lichti01 Beitrag anzeigen
    Das einzige Problem das jetzt noch besteht ist, dass ich den Schalter teilweise mehrmals betätigen muss um das Blinkmuster zu verändern.
    Hallo Alex,
    Taster prellen. d.h. sie schließen und öffnen bei einer Betätigung mehrmals sehr schnell bis die Kontakte ihre endgültige Lage einnnehmen. Die Prellzeit von der Betätigung bis die Kontakte zu Ruhe kommen ist vom Taster abhängig und dauert im Allgemeinen 5 bis 20ms.

    In Deinem Programm sehe ich keine Maßnahme dagegen, so daß die ISR bei einem Tastendruck öfter ausgeführt wird und dann das Blinkmuster zufällig eingestellt wird, das dann wie das vorhergehende Blinkmuster aussieht oder eben zufällig das andere ist.

    Also Tastenentprellung implementieren.



    Code:
         return;
         _delay_ms(250);
    Wozu ist das _delay_ms in der ISR gut. Es wird nie ausgeführt, da mit dem "return;" der Ablauf der ISR beendet wird und das Normalprogramm wieder aufgenommen wird.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.070
    Ich vermute auch das es Tastenprellen ist.
    Das mit dem delay nach dem return stimmt ebenfalls. Bei C benötigst du kein return aus der ISR (außer es ist gewollt).
    Delay sollte man auch in einer ISR vermeiden. Eine ISR sollte auf ein Ereignis so schnell wie möglich reagieren, das Flag wird aber erst bei beenden der ISR zurückgesetzt. Du sperrst somit alle INT (auch Timer,....).
    Außerdem gilt bei ISR: So wenig wie möglich, so viel wie nötig. Die ISR sollte so schnell wie möglich abgearbeitet werden. Langwierige Berechnungen (z.b. Berechnungen mit Float) außerhalb der ISR (wenn nötig einfach ein Flag setzten und das im Hauptprogramm abfragen).

    MfG Hannes

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Hallo,
    gerade fällt mir noch etwas auf. Die ISC00 und ISC01 Bits im MCUCR Register werden nicht gesetzt. Damit ist der low-Level Interrupt für INT0 eingeschaltet. Da ist also nicht nur das Tastenprellen ein Problem, sondern auch das Festhalten bzw Betätigungsdauer des Tasters. Solange ein low-Level am INT0 Pin anliegt, wird die ISR immer wieder aufgerufen, weil ja nach Abarbeitung ja immer noch der low-Level anliegt.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    04.06.2017
    Beiträge
    23
    HI Searcher!

    Danke für die Antwort.
    Werde mich dann mit dem Thema Tastenentprellung auseinandersetzen und diese dann implementieren.

    Gruß Alex

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Auch meine neue Antwort bitte nicht übersehen
    https://www.roboternetz.de/community...l=1#post641412

    Viel Erfolg
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    04.06.2017
    Beiträge
    23
    Habe eure neuen Antworten eben gelesen.

    Wurden mir erst nach absenden meiner Antwort angezeigt.

    Vielen DANK nochmals!
    und danke für den Link

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    04.06.2017
    Beiträge
    23
    so habe mich nun einmal mit dem Thema Tasterentprellung auseinandergesetzt. Habe einen Code im Netz gefunden und diesen in meinen Code eingebunden. Leider besteht das Problem "ich blink wie ich will" immer noch. Was habe ich falsch gemacht?

    Code:
    #define F_CPU 1000000UL
    
    #include <util/delay.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdio.h>
    
    #define LED1 0
    #define LED2 1
    #define LED3 2
    #define LED4 3
    
    //variablen für entprellung
    #define TASTERPORT PIND
    #define TASTERBIT PIND2
    volatile int r = 1;
    
    //variablen für interrupt
    volatile int a = 1;
    volatile int b = 2;
    volatile int c;
    volatile int d;
    
    //Entprellung
    char taster(void)
    {
    	static unsigned char zustand;
    	char rw = 0;
    
    	if(zustand == 0 && !(TASTERPORT & (1<<TASTERBIT)))   //Taster wird gedrueckt (steigende Flanke)
    	{
    		zustand = 1;
    		rw = 1;
    	}
    	else if (zustand == 1 && !(TASTERPORT & (1<<TASTERBIT)))   //Taster wird gehalten
    	{
    		zustand = 2;
    		rw = 0;
    	}
    	else if (zustand == 2 && (TASTERPORT & (1<<TASTERBIT)))   //Taster wird losgelassen (fallende Flanke)
    	{
    		zustand = 3;
    		rw = 0;
    	}
    	else if (zustand == 3 && (TASTERPORT & (1<<TASTERBIT)))   //Taster losgelassen
    	{
    		zustand = 0;
    		rw = 0;
    	}
    
    	return rw;
    }
    int main(void)
    {
    	
    	//I/O-Ports einstellen
    	DDRB = 0b00001111;
    	
    	//Einstellung Interrupt
    	PORTD = 0b00000100;
    	GIMSK = (1<<INT0);
    	MCUCR = (1<<ISC01) | (1<<ISC00);
    
    	//Globale interrupts aktivieren
    	sei();
    	
    	//Wert in Variable setzen
    	c = 2;
    	
    	while (1)
    	{
    		
    		switch(c)
    		
    		{
    			case 1:
    				PORTB |= ((1<<LED1) | (1<<LED3));	//LED1 und 3 ein
    				PORTB &= ~((1<<LED2) | (1<<LED4));	//LED2 und 4 aus
    		
    				_delay_ms(500);
    		
    				PORTB |= ((1<<LED2) | (1<<LED4));	//LED2 und 4 ein
    				PORTB &= ~((1<<LED1) | (1<<LED3));	//LED1 und 3 aus
    		
    				_delay_ms(500);
    			break;
    			case 2:
    				PORTB |= ((1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4));	//LED1-4 ein
    				_delay_ms(500);
    				PORTB &= ~((1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4));	//LED1-4 aus
    				_delay_ms(500);
    			break;
    			
    		}		
    		
    	}
    
    }
    
    ISR(INT0_vect)
    
    {
    	if (taster == r);	//Wenn Taster gedrückt
    	{
    		
    		//switch case Abfrage
    		switch(c)
    		{
    			case 1: d = b;
    			break;
    			case 2: d = a;
    			break;
    			default: PORTB &= ~((1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4));
    		}
    	
    	c = d;
    	
    	}	
    	
    }
    Ist das überhaupt der richtige Code für Tasterentprellung?

    Gruß
    Alex

  9. #9
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.685

    Pfeil

    Hallo Alex!

    .. Werde mich dann mit dem Thema Tastenentprellung auseinandersetzen und diese dann implementieren ..
    .. besteht das Problem "ich blink wie ich will" immer noch. Was habe ich falsch gemacht? .. Ist das überhaupt der richtige Code .. ? ..
    Falsch gemacht? Du hattest davor geschrieben ".. auseinandersetzen .." danach ".. implementieren ..". Mir siehts umgekehrt aus: ".. implementieren .." danach ".. auseinandersetzen ..".

    Beim schnellen Hinsehen fälllt mir auf, Du hast ISC00 und ISC01 gesetzt. Da kommt der Interrupt INT0 bei rising edge. Wie schaltet denn der Taster/Button? Gegen GND oder Vcc? Dass Du den INT0-Pinn (PD2) auf Ausgang setzt macht ja nix aus, denn das Datenblatt schreibt ja auch ".. even if the INT0, INT1 or PCINT17..0 pins are configured as outputs .."; es sieht für mich nur überraschend aus. Meine Taster gehen (fast) immer auf Eingänge mit PullUp und schalten gegen GND.
    Ciao sagt der JoeamBerg

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Zitat Zitat von Lichti01 Beitrag anzeigen
    Leider besteht das Problem "ich blink wie ich will" immer noch. Was habe ich falsch gemacht?

    Code:
    ISR(INT0_vect)
    
    {
        if (taster == r);    //Wenn Taster gedrückt
        {
            
            //switch case Abfrage
            switch(c)
      .
      .
    Ist das überhaupt der richtige Code für Tasterentprellung?
    Hallo Alex,
    weil ich in Bascom programmiere, kann ich C nur recht grob verstehen. Die "taster" Routine scheint Sinn zu machen, wenn sie ständig aufgerufen wird. Du rufst sie aber nur in Deiner ISR auf. Sie ist auch für Taster ausgelegt, die nach LOW schalten.

    Wie die anderen schon geschrieben haben sind dafür die ISC00 und ISC01 Bits noch nicht richtig eingestellt. Wenn die Bits dann auf fallende Flanke eingestellt sind, wird die ISR nur mit der fallenden Flanke aufgerufen und die "taster" routine kann die Zustände "Taster wird losgelassen" bzw "Taster losgelassen" nicht erreichen, da ja in dem Fall die ISR gar nicht aufgerufen wird. (Bitte ein Aufschrei wenn ich falsch liege )

    Die "taster" Routine muß also ständig unabhängig vom Taster Interrupt zB durch einen eigenen Timer aufgerufen werden. Bedeutet aber auch gößere Änderungen im Programm.

    Zum Testen Deiner main könntest Du Dein ursprüngliches Programm nehmen und zunächst auf eine unschöne aber einfache Entprellung zurückgreifen. Dazu ganz am Ende der ISR ein delay von 20ms einsetzen und danach noch das INTF0 Flag im GIFR durch Schreiben einer 1 auf das INTF0 löschen; Ende der ISR.

    Dadurch wird die ISR bei Tasterbetätigung aufgerufen, das INTF0 automatisch gelöscht, Aktionen durchgeführt und dann 20ms lang abgewartet, ob noch Tastenpreller auftreten. Wenn welche aufgetreten sind und das ist zimlich sicher, steht das INTF0 wieder. Das wird jetzt noch manuell gelöscht!, damit nicht sofort nach Beendigung der ISR diese sofort wieder aufgerufen wird.

    Bleibt der Finger auf der Taste oder wird sie losgelassen, tritt keine fallende Flanke auf und es passiert nichts weiter; nur eben dann wieder bei erneutem Tastendruck.

    Der Nachteil ist, daß wie schon mal von 021aet04 erwähnt wurde, das delay das Programm für 20ms aufhält und damit auch das 500ms Blinktiming während Tastendruck minimal verändern kann. Zum Testen würde ich das mal probieren und dann mich nochmal intensiv mit der Entprellung beschäftigen.

    Gruß und ein Frohes Neues an alle
    Searcher
    Geändert von Searcher (01.01.2018 um 11:52 Uhr) Grund: Registername für ATtiny2313A berichtigt
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

Ähnliche Themen

  1. ATTINY Spannung wärend Betrieb ändern
    Von .:markus:. im Forum AVR Hardwarethemen
    Antworten: 9
    Letzter Beitrag: 04.08.2010, 22:32
  2. Programmvariablen wärend Programmablauf ändern und speichern
    Von mat-sche im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 8
    Letzter Beitrag: 06.06.2007, 19:30
  3. Variablen aus Interruptroutine an Sub übergeben
    Von MarkusH im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 04.03.2007, 12:44
  4. Timer in interruptroutine nutzen?
    Von sebastian.heyn im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 12.01.2006, 21:04
  5. interruptroutine umschreiben in ASM
    Von emulein im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 15.02.2005, 07:20

Berechtigungen

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

LiFePO4 Speicher Test