www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Türkontakt an Atmega8


Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe einen Türkontakt an PD2 (INT0) eines Atmega8 gegen GND hängen.
Ich möchte, dass ein Interrupt ausgelößt wird, wenn die Tür auf oder 
zu geht.

Aus dem Datenblatt des Atmega8 habe ich entnommen, dass mit "MCUCR |= 
1<<ISC00;" "any logical change on INT0" einen Interrupt auslößt.

Folgender Code funktioniert trotzdem nicht (es wird nur ein Interrupt 
ausgelößt wenn die Tür aufgeht und er wird weiter ausgelößt solange die 
Tür auf ist, was auch unerwünscht ist):
int main(void)
{
        DDRD = 0x00;
        GIMSK |= 1<<INT0;
        MCUCR |= 1<<ISC00;
        sei();
        while(1) {
                if( GIFR & (1 << INTF0)) {
                        uart_puts("Gerade ist die Tür auf oder zu gegangen\n");
                }
        }

        return 0;
}

        
}

Ich habe keine Ahnung was falsch ist und finde leider auch nichts im 
Netz.
Es würde mich freuen wenn mir jemand helfen könnte.

Gruß,   Dieter

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass' mal "sei()" weg -- und wenn's dann geht, lies nochmal nach was 
Interrupt bedeutet...

scnr, Jörg

Autor: Andreas W. (geier99)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg G. schrieb:
> Lass' mal "sei()" weg -- und wenn's dann geht, lies nochmal nach was
> Interrupt bedeutet...
>
> scnr, Jörg

aber dann muss er auch das Interupt-Flag selber löschen.

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> aber dann muss er auch das Interupt-Flag selber löschen.
Ist besser als der Reset wegen der fehlenden ISR...

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne das sei() geht leider garnichts.

Gruß,   Dieter

Autor: Andreas W. (geier99)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Ohne das sei() geht leider garnichts.

das hatte ich schon fast befürchtet. Da wahrscheinlich die serielle 
Ausgabe auch Interrupts verwendet.

Also, mach das mit dem Interrupt richtig: :-)
1) ISR funktion für INT0 schreiben, in der Du einfach ein Flag setzt 
dass die Tür betätigt wurde

2) dieses Flag fragst Du in Deiner Hauptschleife ab (auch das 
Zurücksetzen dieses Flags dann nicht vergessen)

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Andreas für die Antwort.

Genau das hatte ich auch schon versucht, ging aber auch nicht (wenn ich 
dich richtig verstanden habe)

Du meinst so?
volatile uint8_t flag;

ISR(INT0_vect)
{
        flag=1;
}

int main(void)
{
        DDRD = 0x00; // Eingang
        GIMSK |= 1<<INT0;
        MCUCR |= 1<<ISC00;
        uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
        sei();

        while(1) {
                if(flag == 1) {
                 uart_puts("Tür auf oder zugegangen\n");
                 flag=0;
                 }
        }

        return 0;
}

Das macht genau das gleiche wie mein Code oben.

Gruß,   Dieter

Autor: Bernd Kempa (viper)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Kenn mich mit C nicht so gut aus, mehr mit ASM, aber so wie du das 
gemacht hast, hast das gleiche als wenn du FLAG nicht abfragen würdest, 
weil solange die Tür auf ist setzt er FLAG=1.

Du musst das Setzten des Flags nur einmal ausführen, wenn die Tür auf 
gemacht wird und dann solange überspringen bis die Tür wieder zu ist.

Aber warum willste das Ganze mit nem Interruptpin machen, das geht doch 
auch super mit nem normalen Eingangspin ?

CU
Bernd

Autor: Andreas W. (geier99)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieter schrieb:
> Danke Andreas für die Antwort.
>
> Du meinst so?

Vom Prinzip her ja, dann werde ich wohl mal mein STK 500 rausholen 
müssen und es mal selbst probieren.

Autor: Andreas W. (geier99)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm,

ich habs jetzt bei mir mal nem ATMega16 probiert und da funktioniert es 
problemlos. Hier ist mal mein Code (Achtung die Syntax ist leicht etwas 
anderst, da ich den CodeVision AVR C verwende).
volatile unsigned char ucFlag=0;           // Statusflag für INT0 ist aufgetreten


// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
  if(ucFlag<255) ucFlag++;
}

void main(void)
{
.....
// Port D initialization
PORTD=(1<<PD2);    // Pull Up für INT0 (PD2) aktivieren
DDRD= (1<<PD4);    // Debug LED an Port D4

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Any change
// INT1: Off
// INT2: Off
GICR  |= (1<<INT0);           
MCUCR  = (1<<ISC00); 
MCUCSR = 0x00;
GIFR   = (1<<INTF0);
.......
// Global enable interrupts
#asm("sei")

while (1) {
    if(ucFlag) {
        ucFlag--;
        printf("Tür auf oder zugegangen\n");
    }
    #asm("wdr")
};  // end while
}

Einziger Unterschied, was mir noch zu Dir auffällt ist, dass ich für den 
INT0 sicherheitshalber noch den  PullUp aktiviert habe.
Ausserdem, bist Du Dir sicher, dass das Register MCUCR bei Dir mit 0x00 
intialisiert wurde?( Falls nicht dann schreib lieber: MCUCR = 1<<ISC00; 
)

Ansonsten, simuliere Dein Programm einfach mal im AVR-Studio da kann man 
schön sehen, woran es habert.

Bye
 Andreas

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.