- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 17

Thema: Kein Interrupt nach Reset/Neustart

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    29.07.2013
    Beiträge
    11

    Kein Interrupt nach Reset/Neustart

    Guten Tag,

    ich habe mit meinem mini-Programm ein Problem.

    Jedes mal nach dem Neustarten oder Reseten des Kontrollers wird die Interrupt-Funktion ausgeführt und erst dann das Hauptprogramm.

    Nun habe ich schon gelesen ,dass man in Assembler die erste Speicheradresse überspringen muss, um das zu unterbinden.
    Aber ich finde nichts ,wie ich sowas in "C" machen kann.

    Kann mir vlt. jemand helfen?

    Vielen Dank!
    Code:
    /*
     * Ampel.c
     *
     * Created: 07.08.2013 10:36:06
     *  Author: en
     */ 
    
    #define F_CPU 1600000UL
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    
    // eigene Bezeichnungen
    #define		rot		PC0
    #define		gelb	PC1
    #define		gruen	PC2
    #define		ein		1
    #define		aus		0
    
    //volatile unsigned char _taster=1;
    
    
    ISR (INT1_vect)
    {
    	_delay_ms(80);
    	PORTC	 |= (1 << PC4);
    	_delay_ms(1000);
    	PORTC &=~(1<<PC4);
    	
    	
    }
    
    void rot_schalten(unsigned int i)
    {
    	if (i==ein){PORTC	 |= (1 << rot);}   // Setzen
    	else {PORTC &= ~(1 << rot);}  // Rücksetzen
    	//_delay_ms(1000);
    	
    	
    	};
    
    void gelb_schalten(unsigned int i)
    {
    	if (i==ein){PORTC	 |= (1 << gelb);}   // Setzen
    	else {PORTC &= ~(1 << gelb);}  // Rücksetzen
    	//_delay_ms(1000);
    	
    	
    };
    
    
    void gruen_schalten(unsigned int i)
    {
    	if (i==ein){PORTC	 |= (1 << gruen);}   // Setzen
    	else {PORTC &= ~(1 << gruen);}  // Rücksetzen
    	//_delay_ms(1000);
    	
    	
    };
    
    
    int main(void)
    {  cli();
    	
    	 GICR |= (1 << INT1);               
    	 MCUCR |= (1 << ISC11);
    	//PORT A als Ausgang
    	PORTC	=	0x00;
    	DDRA	=	0xFF;
    	
    	//PORT C als Ausgang
    	PORTC	=	0x00;
    	DDRC	=	0xFF;
    	
    	//PORT D als Eingang
    	
    	DDRD	=	1<<PD3;
    	PORTD	=	1<<PD3;
    	SREG |= (1<<7);
    	
        while(1)
        {
    		
    		
    		rot_schalten(ein); 
    		_delay_ms(1000);
    		gelb_schalten(ein);
    		_delay_ms(600);
    		rot_schalten(aus);
    		gelb_schalten(aus);
    		gruen_schalten(ein);
    		_delay_ms(1000);
    		gruen_schalten(aus);
    		gelb_schalten(ein);
    		_delay_ms(600);
    		gelb_schalten(aus);
    		
        }
    }

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    48
    Beiträge
    1.146
    Hi,

    die Speicherorganisation übernimmt der Linker beim Compilieren automatisch, Du musst also nicht wie in Assembler selber den Interrupt-Adressbereich überspringen.
    Bist Du sicher, dass der Interrupt wirklich vor main() aufgerufen wird und nicht erst vor dem Sprung in Deine Hauptschleife (while(1){...})?
    Denn mit
    Code:
    DDRD    =    1<<PD3;
    PORTD    =    1<<PD3;
    löst Du den Interrupt vor der Hauptschleife manuell aus.

    Gruß,
    askazo

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    29.07.2013
    Beiträge
    11
    Habe mich falsch ausgedrückt.Natürlich wird es in "main()" ,aber noch vor der schleife ausgeführt.

    Nur verstehe ich nicht wie ich mit
    Code:
    DDRD    =    1<<PD3;
    PORTD    =    1<<PD3;
    Interrupt auslöse?
    Der ist doch auf abfallende Flanke eingestellt.Sprich gegen Masse.
    Und wenn das doch der Fall ist und ich löse ihn tatsächlich selber aus.Wie mache ich das denn korrekt?
    Könntest die Programmzeilen richtig stellen?!

    Riesen Dank!

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    48
    Beiträge
    1.146
    Du wechselst mit
    Code:
    DDRD = 1<<PD3;
    von einem offenen Eingang (floating) zu einem definierten Low-Pegel, was schon als fallende Flanke erkannt wird. Das Interrupt-Flag wird auch gesetzt, wenn das I-Bit nicht aktiviert ist. Sobald dieses dann aktiviert wird, wird der Interrupt ausgeführt.
    Am besten konfigurierst Du zuerst den Port und aktivierst dann den externen Interrupt. Also
    Code:
    DDRD    =    1<<PD3;
    PORTD    =    1<<PD3;
    MCUCR |= 1<<ISC11;
    GICR |= 1<<INT1;
    
    GIFR |= 1<<INTF1;
    sei();
    Somit wird der Interrupt erst scharf geschaltet, wenn der PD3 schon einen definierten High-Pegel hat.
    Sicherheitshalber habe ich mit der vorletzten Zeile das Interrupt-Flag ausdrücklich gelöscht.

    Gruß,
    askazo

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    29.07.2013
    Beiträge
    11
    Was soll ich sagen..
    Das war die Lösung!Einfach die Plätze tauschen...

    Erst Eingänge setzten ,dann interrups definieren.

    Vielen Dank!!
    -----------------------------------------

    Ganz andere frage:
    Macht es Sinn die "Delay`s" aus dem Programm rauszunehmen und stattdessen Timer zu verwenden?
    Und wenn ja, könnte mir jemand ein "Stoß" bzw Tipp geben wie ich das am besten mache?
    Also kein Code,sondern so ein kleines Flussdiagramm.
    Nach meinem derzeitigen Plan, brächte ich mindestens drei Timer...für rot ,gelb,grün..

  6. #6
    Erfahrener Benutzer Roboter-Spezialist Avatar von robo_tom_24
    Registriert seit
    04.02.2012
    Ort
    Burgenland, Österreich
    Beiträge
    485
    Wieso machst du ds eigentlich mit einer Interrupt routine?

    Klar, Timer sind besser, bei delays rechnet die CPU andauernd, bei Timern nicht da dies ein externes Modul am die ist und unabhängig von der cpu läuft. Am besten eine Timer machen, der alle 100ms einen Interrupt auslöst, diese Interrupts mit einer static variable mitzählen und je nach Zählerstand handeln (nach 10x100ms => 1s Rot aus, Gelb ein; nach 16x100ms => 1.6s Gelb aus, usw), wenn man dann einmal durch ist mit dem Ampelprogramm Variable zurücksetzten und das Spiel beginnt von neuem

Ähnliche Themen

  1. Kein Reset mit angeschlossenem ISP Programmer
    Von Markus87 im Forum Schaltungen und Boards der Projektseite Mikrocontroller-Elektronik.de
    Antworten: 5
    Letzter Beitrag: 23.08.2011, 13:22
  2. kein RXD Empfang nach "Reset"
    Von neo3000 im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 0
    Letzter Beitrag: 10.10.2010, 13:39
  3. Motorport wird nach Neustart angesteuert am ATMEGA 32 ?
    Von M.Huhnke im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 20.01.2010, 15:00
  4. Problem nach RESET
    Von bombatz im Forum Assembler-Programmierung
    Antworten: 7
    Letzter Beitrag: 12.08.2006, 11:10
  5. Timer1 reset nach Compare1A
    Von Theo16505 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 11.02.2006, 22:33

Stichworte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad