Nach einer Interrupt Routine wird der PORT zurückgesetzt

OP #659884
Lesenswert?

Hallo Zusammen,

ich habe ein Problem mit meinem AVR. Wenn ich während eines Externen 
Interrupts das Ports setze, dann werden diese nach Verlassen ser 
Interruptroutine zurückgesetzt. Wenn ich den untenstehenden Quell Code 
im AVR Studio simulieren bleibt der Port jedoch gesetzt? Kann mir jemand 
helfen? Was ich erreichen möchte, ist das immer wenn ein Interrupt 
ausgelöst wurde die Ausgänge an Port C verändert werden. Möchte damit 
eine Art Freigabe Schaltung für einen Sensor realisieren. Ist es 
überhaupt möglich die Ports innerhalb der Interrupts dauerhaft zu 
setzen, so das diese Ports dann auch weiter im Hauptprogramm benutzt 
werden können?

Vielen Dank im Voraus

1
#include <avr/io.h>         
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4
#define INT0_vect                     _VECTOR(1)
5
#define INT1_vect                     _VECTOR(2)
6

7
volatile uint8_t temp; 
8

9

10
ISR(INT0_vect) 
11
{
12
   PORTC = 0x01;
13
}
14
  
15
ISR(INT1_vect) 
16
{
17
        switch (temp)
18
  {
19
  case 0:
20
  PORTC = 0x01;
21
  temp++;
22
  break;
23

24
  case 1:
25
  PORTC = 0x02;
26
  temp++;
27
  break;
28

29
  case 3:
30
  PORTC = 0x03;
31
  temp=0;
32
  break;
33
  }
34
}
35

36
int main (void) {          
37

38
    
39
  
40
sei();  // Globales Interrupt Enable Flag setzen
41
   
42
         
43
DDRC  = 0xff;  // Port C als Output
44
PORTC = 0x00;  
45
DDRD  = 0x00;  // Port D als Input
46

47

48
MCUCR |= (1<<ISC01)|(1<<ISC00)|(1<<ISC10)|(1<<ISC11);
49
GIMSK |=(1<<INT0)|(1<<INT1);
50

51
   while(1) {             
52

53
   /* "leere" Schleife*/;
54
   }   
55

56
   /* wird nie erreicht */
57
   return 0;
58
}
Gast #659897
Lesenswert?

1
MCUCR |= (1<<ISC01)|(1<<ISC00)|(1<<ISC10)|(1<<ISC11);

womit wird der Interrupt ausgelöst ? Taste ?
Ich habe keine Lust in Dattenblatt zu schauen, ich meine aber, daß Du 
Levelinterrupt geschaltet hast und kein Flankeninterrupt.

Gruß Sebastian
Gast #659901
Lesenswert?

Versetze das   sei();  // Globales Interrupt Enable Flag setzen
wie unten.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#define INT0_vect                     _VECTOR(1)
#define INT1_vect                     _VECTOR(2)

volatile uint8_t temp;


ISR(INT0_vect)
{
   PORTC = 0x01;
}

ISR(INT1_vect)
{
        switch (temp)
  {
  case 0:
  PORTC = 0x01;
  temp++;
  break;

  case 1:
  PORTC = 0x02;
  temp++;
  break;

  case 3:
  PORTC = 0x03;
  temp=0;
  break;
  }
}

int main (void) {

DDRC  = 0xff;  // Port C als Output
PORTC = 0x00;
DDRD  = 0x00;  // Port D als Input


MCUCR |= (1<<ISC01)|(1<<ISC00)|(1<<ISC10)|(1<<ISC11);
GIMSK |=(1<<INT0)|(1<<INT1);

sei();  // Globales Interrupt Enable Flag setzen

   while(1)
   {
    asm volatile ("nop");
   }

   /* wird nie erreicht */
   return 0;
}
Persönliche Seite #659905
Lesenswert?

Daniel V. wrote:
> Ja der Interrupt wird durch einen Taster ausgelöst. Laut Datenblatt
> werden die beiden Interrupts mit Steigender Flanke getriggert.

Taster an Interrupts zu hängen ist generell eine schlechte Idee, da 
Taster nicht direkt von "Auf" nach "Zu" gehen, wenn man draufdrückt, 
sondern noch eine Weile "prellen".

Hier hilft eine Hardware-Entprellung mit RC-Tiefpass oder auf Interrupts 
verzichten und mit Peter Danneggers Bullet-Proof-Taster-Polling zu 
arbeiten.

PS: Was soll eigentlich das hier?
1
#define INT0_vect                     _VECTOR(1)
2
#define INT1_vect                     _VECTOR(2)
Gast #659914
Lesenswert?

Ja sorry, hast recht, Du triggerst auf steigender Flanke.
Dann prellt Deine Taste, wie simon schon gesagt hat.
Warum machst Du temp global ?
besser wäre es, temp als static in der ISR zu deklarieren

Gruß Sebastian
OP #659922
Lesenswert?

Ich habe es nun ausprobiert wenn ich das sei() umsetzte, trotzdem keine 
Änderung. Über die Beschaltung der Interrupts muss ich mir im ersten 
Schritt denke ich keine Sorgen machen. Ich benutze die auf dem Pollin 
Board befindlichen Taster dür die Interrupts. Dort befinden sich Pullup 
Widerstände und ein Kondensator zur Entprellung drauf. Ich sehe ja auch 
das der Port kurz geschaltet wird nur dann erlischt er wieder. Aber er 
soll ja auch nachdem die Interrupt routine verlassen wurde gesetzt 
bleiben.
Geht das überhaupt das?

Die Zeilen habe ich aus dem Tutorial aauf dieser Seite

#define INT0_vect                     _VECTOR(1)
#define INT1_vect                     _VECTOR(2)
Gast #659932
Lesenswert?

Funktioniert denn die Taste, die an INT0 hängt ?
hier sollte der PORT bei 0x01 bleiben, egal, ob die Taste prellt, oder 
nicht.
Und lösche den Quatch mit
#define INT0_vect                     _VECTOR(1)
#define INT1_vect                     _VECTOR(2)

Gruß Sebastian
Gast #660043
Lesenswert?

Wie sind INT0 und INT1 extern beschaltet?
Egal, was Besserwisser dazu meinen, ich habe schon
"Mitnahmeeffekte" bei benachbarten I/Os beobachtet.
Vielleicht noch ein "PORTD = 0xff;" ?
Schadet bestimmt nicht.
OP #660078
Lesenswert?

Nur bei Anlage des Projektes habe ich im Auswahlfenster auf der Linken 
Seite Simulation und auf der rechten Seite ATMEGA16 ausgewählt. Nach dem 
ich dann das Prog compiliert habe schicke ich es mit Ponyprog auf den 
AVR. In Ponyprog habe ich auch ATMEGA16 ausgewählt.

@ich weiss auch alles besser:

Meine INT0 und INT 1 sind über das POLLIN Board mittels eines PULLUP 
widerstandes und eines Kondensators zum entprellen beschaltet. ICh sehe 
ja auch kurzzeitig das der Interrupt ausgeführt wird. von daher sollte 
es kein Pegelproblem sein?
Persönliche Seite #660084
Lesenswert?

Daniel V. wrote:
> Meine INT0 und INT 1 sind über das POLLIN Board mittels eines PULLUP
> widerstandes und eines Kondensators zum entprellen beschaltet. ICh sehe
> ja auch kurzzeitig das der Interrupt ausgeführt wird. von daher sollte
> es kein Pegelproblem sein?

Keine Ahnung ob es bei dir das Problem sein kann, aber generell schließt 
man Taster nicht an externe Interrupts an. Wenn die externe Entprellung 
aber korrekt dimensioniert ist, sollte das nichts machen.

Wo "siehst" du denn, dass der Interrupt ausgeführt wird? Weißt du wie 
schnell ein Taster prellen kann? Das kann man mit einer LED und dem 
menschlichen Auge nicht wahrnehmen. (Du siehst ja auch nicht, dass der 
Schalter für deine Zimmerbeleuchtung prellt). Hierfür bräuchte man schon 
ein Oszilloskop.

Das Problem daran ist aber, dass der Mikrocontroller so schnell ist, 
dass er das Prellen des Taster genau "mitbekommt". Aus seiner Sicht 
gesehen, ist das Prellen des Tasters sau-lahm.
#660111
Lesenswert?

Daniel V. wrote:
> Hallo Peter,
>
> doch ich benutze den AtmEGA 16 auf dem POLLIN BOard. Bei mir wird der
> Code ohne Probleme compeliert.

Dann hast Du nicht den ATmega16 als Target definiert, der hat kein 
GIMSK.

Bei nem falschen Target stürzt das Programm natürlich ab.

Und die Zeilen
1
#define INT0_vect                     _VECTOR(1)
2
#define INT1_vect                     _VECTOR(2)
schmeiß raus.
Die sind im io.h definiert, wenn das Target stimmt.


Peter
Gast #660130
Lesenswert?

Ich tippe auch auf Tastenpreller.
Ändere mal Deine INT1-isr spasseshalber so ab, dass
sie in acht Durchläufen die acht PortC-I/Os einzeln
bedient. Oszilloskop dran und "nur ein Ping". ;-)
Gast #660144
Lesenswert?

Ist der ICP1-Eingang nach außen geführt? Vielleicht auch
einen Versuch wert, mit aktiviertem noise canceler.
Es geht natürlich nichts über einen ordentlichen Tasten-
entpreller. Ich persönlich taste Tasteneingänge über Timer-
interrupt ab, und entprelle per Software.

Feuer frei...
Gast #660581
Lesenswert?

Hi,
setz doch mal PORTC auf 255 beim Start.
Wenn der AVR neustartet, müssten dann alle LEDs an sein. Dann sieht man 
besser, wenn es einen neustart gab.
Oder Du lässt Dir über das MCUSR die Resetquelle auf PORTC ausgeben.

int main (void) {

DDRC  = 0xff;  // Port C als Output
PORTC = 0xff; <--- zum Test auf "FF" setzen
DDRD  = 0x00;  // Port D als Input

Das Target sollte schon richtig eingestellt sein, sonst gehts nicht. 
JTAG ist aus?
OP #660626
Lesenswert?

Hallo Axel,

die Idee mit dem PORT C auf FF zu setzen hat gezeigt, das der AVR einen 
Neustart macht. Und siehe da jetzt habe ich auch den Fehler gefunden. In 
meiner Entwicklungsumgebung war trotz auswahl des ATMEGA16 unter Device 
noch ATMEGA32 eingetragen. Ich denke mal das war ein typischer 
Anfängerfehler.
Trotzdem ein riesen Dankeschön an alle!!! ICh Verspreche Besserung :-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren