Forum: Compiler & IDEs Interupt Problem


von Robert M. (xertno)


Lesenswert?

Hi,
ich habe ein Problem mit dem INT1. durch ein Externes Bauelement wird 
nach der Anfrage von Daten dem MC über den Interrupt angezeigt ob die 
Daten zur Abholung bereit sind. Dafür löst der Sensor eine LOW- HIGH 
Flanke aus. Dies ist auch messbar. Das Problem ist das diese Flanke vom 
MC nicht verarbeitet wird. Das heißt im realen in der Simulation im AVR 
Studio funktioniert die Programmierung. Ich werde mal Teile vom 
Programmcode Posten.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <avr/iom644.h>
#ifndef F_CPU
#define F_CPU 36000UL
#endif
#include <util/delay.h>
…
ISR(INT1_vect)
{
  cli();
  x.Int1Merker = 1;
  sei();
}
…
void Funktion(void)
{
  x.Int1Merker=0;

  PORTB |=  (1<<3);
  _delay_ms(5);
  PORTB &= ~(1<<3);

  while (x.Int1Merker==0);

//Das ist die Bedingung die in der Simulation erfüllt wird aber im 
realen nicht.

  PORTB &= ~(1<<1);
…

Vielleicht ist es die Äußeren Beschaltung die nicht richtig ist. Ich 
habe keine Ahnung mehr ich habe schon einiges Ausprobiert. hoffentlich 
hat jemand eine Idee.
MC: ATMEGA644
Programiert: GCC

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wie ist die Struktur definiert, auf die Du da mit

  x.Int1Merker=0;

zugreifst? Fehlt da womöglich ein "volatile"?

von Robert M. (xertno)


Lesenswert?

struct
{
volatile unsigned Int0Merker:1;
volatile unsigned Int1Merker:2;
volatile unsigned Int2Merker:3;
volatile unsigned Int3Merker:4;
} x;

von Andreas Paulin (Gast)


Lesenswert?

Das sei() / cli() in der ISR brauchste nicht, das geschieht automatisch.
Aber:
Sind die Interruptflags (global und INT1) in main() auch definitiv 
freigeschaltet?

von Robert M. (xertno)


Lesenswert?

Ich habe es oben nicht geschrieben aber das INT0 ist ebenfalls 
angeschlossen und funktioniert auch aber auf eine High - Low Flanke hin. 
In der Main habe ich dies hier geschrieben:
EIMSK  =  0b00000011;
                  //Interrupt wird aktiviert am Port INT0 sowie Port 
INT1
    //Hier PD2 Pin 16 / PD3 Pin 17

EICRA  =  0b00001110;
                  //Interupt an INT0 bei fallender Flanke
    //Interupt an INT1 bei steigender Flanke
sei();

Aber vielleicht stimmt hier irgendwas nicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Robert M. wrote:

> struct
> {
> volatile unsigned Int0Merker:1;
> volatile unsigned Int1Merker:2;
> volatile unsigned Int2Merker:3;
> volatile unsigned Int3Merker:4;
> } x;

Nur ganz nebenbei: die Bitfelder hast du noch nicht richtig
verstanden...  Du belegst eins mit 1 Bit Breite (OK), das zweite
mit 2 Bit Breite, das dritte mit 3 Bit Breite und das vierte mit
4 Bit Breite.  Ich denke nicht, dass das das ist, was du wolltest...

Falls du nicht gerade an chronischem RAM-Mangel leidest, kannst du
auch lieber uint8_t- oder bool-Variablen (#include <stdbool.h>)
benutzen, das ist schneller und weniger Code.

von Robert M. (xertno)


Lesenswert?

Nee das habe ich wohl nicht - Danke dafür.

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.