Forum: Mikrocontroller und Digitale Elektronik ATMega168 INT0 ohne ISR


von Alex_PvG (Gast)


Lesenswert?

Hallo liebe Gemeinde,

ist vermutlich eine blöde Anfängerfrage...
ich möchte gern alle 5 sec prüfen, ob seit der letzten Prüfung eine 
fallende Flanke an INT0 vorlag. Ich möchte allerdings nicht die ISR für 
den INT0 nutzen. Im Simulator des AVR Studio 4.18 und 5 geht das auch 
prima. PINB1 schaltet alle 5 sec um, PINB0 nur wenn fallende Flanke 
vorlag.
Die fallende Flanke wird am gesetzten Flag INTFR0 im EIFR Register 
erkannt.
Wenn ich die hex in meinen Microcontroller übertrage, gibt es keine 
Reaktion auf die fallende Flanke die ich durch einen Taster auf GND 
simuliere. Kann mal bitte jemand auf meinen Codeschnipsel schauen ob ich 
hier vieleicht einen Denkfehler gemacht habe? Oder verhält sich der 
Mega168 in real anders als der Simulator?

Vielen Dank im Voraus!
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define CPU_CLOCK 3686400 
5
6
ISR(TIMER1_COMPA_vect){
7
  if (bit_is_set(EIFR,INTF0))
8
  {
9
    EIFR|=(1<<INTF0); // write one for clear interrupt flag
10
    PORTB^=(1<<PINB0); // change state of PINB0
11
  }
12
  PORTB ^=(1<<PINB1); // change state of PINB1
13
};
14
15
int main(void)
16
{
17
  PORTD |=(1<<PIND2); // Pull up enable - PIN for external INT0 (button is low active)
18
  EICRA |= (1<< ISC01);  //INT request on falling edge
19
  DDRB |= (1<<PINB0)|(1<<PINB1); // PB0, PB1 as output
20
  
21
  // configure timer0
22
  OCR1A = 18000; //OCR1A for 5 seconds
23
  TCCR1B|= (1<<WGM12); //clear timer on match
24
  TCCR1B|=(1<<CS10)|(1<<CS12); //scaler =1024
25
  TIMSK1|= (1<<OCIE1A); // enable Timer1 Compare match A ISR
26
  sei();
27
  
28
  // infinite loop
29
  while(1)
30
    {
31
        asm("NOP"); 
32
    };
33
}

von Thomas E. (thomase)


Lesenswert?

Alex_PvG schrieb:
> hier vieleicht einen Denkfehler gemacht habe?
Und zwar einen gewaltigen.

Wenn ein Interrupt ausgelöst wird, MUSS eine Isr vorhanden sein, sonst 
macht der Controller einen Reset.

Alex_PvG schrieb:
> if (bit_is_set(EIFR,INTF0))
>   {
>     EIFR|=(1<<INTF0); // write one for clear interrupt flag
Sowas in einem Timer-Interrupt abzufragen, ist nicht der Weisheit 
letzter Schluss.

char nInt0 = 0;

ISR(INT0_vect)
{
   nInt0 = 1;
}

ISR(TIMER1_COMPA_vect)
{
  if (nInt0)
  {
    nInt0 = 0;

    Mach was...
  }
}

Alex_PvG schrieb:
> while(1)
>     {
>         asm("NOP");
>     };
Das "nop" kannst du weglassen. Es reicht, wenn er einfach nur auf der 
Stelle trampelt.

mfg.

von Helfer (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> char nInt0 = 0;

noch ein volatile dazu, dann funzt's auch. :)

von Thomas E. (thomase)


Lesenswert?

Helfer schrieb:
> noch ein volatile dazu, dann funzt's auch. :)
Jo.

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Thomas Eckmann schrieb:
> Alex_PvG schrieb:
>> hier vieleicht einen Denkfehler gemacht habe?
> Und zwar einen gewaltigen.
>
> Wenn ein Interrupt ausgelöst wird, MUSS eine Isr vorhanden sein, sonst
> macht der Controller einen Reset.

Er hat doch den INT0 gar nicht zur Behandlung durch eine ISR 
freigegeben. Im EIMSK ist das entsprechende Bit nicht gesetzt worden.
Er fragt lediglich das Flag im Flagregister ab. Und das ist durchaus 
legitim, wenn auch das Rücksetzen fehlerhaft gemacht wurde (was aber zur 
Zeit nicht das Problem darstellt)

von Peter D. (peda)


Lesenswert?

Thomas Eckmann schrieb:
> Sowas in einem Timer-Interrupt abzufragen, ist nicht der Weisheit
> letzter Schluss.

Natürlich kann man jedes Interruptereignis auch pollen, bei der UART 
wird das sogar oft gemacht.
Man muß nicht jedesmal einen Interrupthandler verschwenden.


Peter

von Thomas E. (thomase)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Er hat doch den INT0 gar nicht zur Behandlung durch eine ISR
> freigegeben.

Peter Dannegger schrieb:
> Natürlich kann man jedes Interruptereignis auch pollen, bei der UART
> wird das sogar oft gemacht.

Ihr habt ja Recht.
Aber dann müsste das bei ihm auch so funktionieren.

mfg.

von Thomas E. (thomase)


Lesenswert?

Nochmal von vorne.
Der Code funktioniert.

Aber was ist das?
Alex_PvG schrieb:
> #define CPU_CLOCK 3686400
#ifndef F_CPU
 #define F_CPU 3686400UL
#endif

Läuft der Controller mit dem richtigen Takt(Fuses)?

mfg.

von J.-u. G. (juwe)


Lesenswert?

Thomas Eckmann schrieb:
> Läuft der Controller mit dem richtigen Takt(Fuses)?

Hab ich mich auch schon gefragt. Er hat aber nur davon geschrieben, dass 
PINB0 sich nicht wie erwartet verhält. PINB1 scheint ja ordnungsgemäß zu 
toggeln (@Alex_PvG: ist das so?).

von Alex_PvG (Gast)


Lesenswert?

Hallo,

vielen Dank für die vielen Hinweise. Hatte gestern leider keine Zeit 
reinzuschauen. PINB1 toggelt wie erwartet im geplanten Zeitintervall. 
CPU läuft mit externem Baudratenquarz, fuses sind entsprechend gesetzt.

Das Löschen des Interrupt flags durch schreiben eines Bits
1
EIFR|=(1<<INTF0)
habe ich aus der ATMEL Beschreibung des Prozessors. Funktioniert im 
Simulator auch so.

Ich muss dann wohl mal schauen ob der PIND2 (INT0) eventuell abgeraucht 
ist. Mal anderen Prozessor ausprobieren...

von Alex_PvG (Gast)


Lesenswert?

... achso: das
1
asm("NOP")
 hab ich drin, damit ich schrittweise testen kann. Sonst läuft der 
Simulator durch.

Danke nochmal!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.