Forum: Mikrocontroller und Digitale Elektronik AVR INT1 löst bei INT0 aus


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Da M. (da_ma)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich wollte anfangen mich mit der Programmierung von Mikrocontrollern zu 
beschäftigen. Dazu habe ich mir zu Beginn eine ganz einfache Schaltung 
zusammengebastelt. Die Schaltung findet ihr im Anhang.

Die beiden Taster sollen lediglich die LEDs durchschalten. Damit wollte 
ich erstmal kontrollieren ob alles funktioniert und mich mit der 
Controller-Familie vertraut machen, bevor es an die größeren Projekte 
geht.

Jetzt habe ich das Problem das, egal welchen der beiden Taster ich 
drücke, nur die ISR für INT1 aufgerufen wird.


Hier der dazugehörige Quellcode:

/*****************************************************************/
// #include Dateien
/*****************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>

/*****************************************************************/
// Funktionen und Interrupt-Routinen
/*****************************************************************/
void isr_init(void)
{
  MCUCR |= 0b00001010;  // Interrupts bei fallender Flanke
  GICR |= 0b11000000;  // aktiviert INT0 und INT1
  sei();      // aktiviert Global Interrupts
}


ISR(INT0_vect)        // ISR für INT0
{
  PORTC = 0b00001010;
}


ISR(INT1_vect)        // ISR für INT1
{
  PORTC = 0b00000101;
}
/******************************************************************/
// main
/******************************************************************/
int main(void)
{
  isr_init();

  DDRC = 0x0F;
  PORTC = 0b00001110;

  while(1);

  return 0;
}


Habt ihr eventuell Ideen woran es liegen könnte?

Schon mal Danke im Voraus :)

: Bearbeitet durch User
von m.n. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wenn Du die Taster per Interrupt auswerten möchtest (gleich geht das 
Gechreie wieder los), mußt Du sie anders verdrahten und auswerten.
Beitrag "EIN-AUS mit Taster per Interrupt, ATtiny25 o.ä."

von Georg G. (df2au)


Bewertung
0 lesenswert
nicht lesenswert
Aus dem Datenblatt des Prozessors:
AVCC is the supply voltage pin for the A/D Converter, Port C (3..0), and 
ADC (7..6). It should be
externally connected to VCC, even if the ADC is not used. If the ADC is 
used, it should be connected
to VCC through a low-pass filter. Note that Port C (5..4) use digital 
supply voltage, VCC.

von H.Joachim S. (crazyhorse)


Bewertung
0 lesenswert
nicht lesenswert
Wie schon angedeutet - Taster im Interrupt ist und bleibt Mist. Bringt 
nichts, macht nur Sorgen.
Trotzdem scheint das Programm auf den ersten Blick richtig. Unschön die 
Schreibweise. Wenn man nicht ein Gedächtnis wie ein Elefant hat und 
diesem auch noch 100% vertrauen kann, kann man z.B. damit
GICR |= 0b11000000;
erstmal nicht viel anfangen ohen nachzuschlagen.
GICR|=(1<<INT1) | (1<<INT0);
ist selbsterklärend und weniger fehleranfällig (bei der binären 
Schreibweise kann schon mal ne Null fehlen :-) )

Bleibt noch die Hardware: 100n, die du mit einem Taster kurzschliesst, 
zerstören auf Dauer den Taster. Entweder noch einen Widerstand einfügen 
oder noch besser den Kondensator weglassen und die Tasten gescheit 
einlesen samt Softwareentprellung.

von Da M. (da_ma)


Bewertung
-1 lesenswert
nicht lesenswert
Danke schon mal für die schnellen Antworten.

Wenn das Auswerten der Taster per Interrupts Mist ist, dann frag ich 
mich wie man sonst anständig Taster abfragt. Man kann es natürlich hier 
auch in die while-Schleife einfügen. Aber bei größeren Programmen, bei 
denen der Controller mehr zu tun hat, als in meinem kleinen Projekt 
hier, finde ich das ziemlich unschön.

Mit der Schreibweise geb ich dir natürlich recht :)

Mit der Softwareentprellung tue ich mich, ehrlich gesagt noch etwas 
schwer. Hab versucht mich zu dem Thema mal zu belesen, aber das scheint 
ja eine Glaubensfrage zu sein...

Zu dem Hinweis mit dem AVCC, diesen hatte ich erstmal weggelassen, da 
ich weder den ADC noch die anderen Pins verwende. Bei den Pins(3..0) 
wird die Spannung durch den Controller ja lediglich auf GND gezogen.

von Migel C. (migelchen)


Bewertung
0 lesenswert
nicht lesenswert
Da M. schrieb:
> ISR(INT0_vect)        // ISR für INT0
> {
>   PORTC = 0b00001010;
> }
>
> ISR(INT1_vect)        // ISR für INT1
> {
>   PORTC = 0b00000101;
> }

Hallo,

ich bin nicht unbedingt der Meinung, dass die Taster das ursprüngliche 
Problem sind...

Meine Theorie ist eine andere.
Ich bin da ja nun auch kein Profi, aber kann es sein, dass du bei keiner 
deiner Interupt-Routinen wieder zum Auslösepunkt zurückspringst?

Wenn also INT0 ausgelöst wird, arbeitet er INT0 ab und danach direkt den 
danachfolgenden Befehl.

Gab es dafür nicht den Befehl "Reti" oder so?

Was passiert bei dir, wenn INT1 ausgelöst wird?

Gruß
Migelchen

: Bearbeitet durch User
von Georg G. (df2au)


Bewertung
1 lesenswert
nicht lesenswert
Da M. schrieb:
> Zu dem Hinweis mit dem AVCC, diesen hatte ich erstmal weggelassen, da
> ich weder den ADC noch die anderen Pins verwende. Bei den Pins(3..0)
> wird die Spannung durch den Controller ja lediglich auf GND gezogen.

AVCC ist die Versorgung des gesamten Ports, nicht nur der 
Ausgangstreiber. Das "should" in einem englischen Datenblatt hat die 
Bedeutung "muss".

Migel C. schrieb:
> Gab es dafür nicht den Befehl "Reti" oder so?

Das macht der C-Compiler von sich aus.

von Da M. (da_ma)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe schon verschiedene Sachen durchprobiert.

Ich habe die ISR einfach mal vertauscht:

ISR(INT1_vect)        // ISR für INT0
{
  PORTC = 0b00001010;
}


ISR(INT0_vect)        // ISR für INT1
{
  PORTC = 0b00000101;
}

Aber auch hier springt er nur zu INT1, egal welche der beiden Tasten ich 
drücke.

Auch habe ich in der main() die while schleife verändert um zu sehen ob 
er vielleicht in der ISR festhängt:

while(1)
{
  PORTC = 0b00001110;
}

Auch das sah gut aus. Er springt als auf jeden Fall aus der ISR wieder 
zurück zur main()


Da ich jetzt nicht mehr weiter weiß, dachte ich, ich frag mal die 
Community :)


Edit: ich werde nachher mal an AVCC 5V anlegen und schauen ob das was 
ändert

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Bewertung
0 lesenswert
nicht lesenswert
Da M. schrieb:
> Zu dem Hinweis mit dem AVCC, diesen hatte ich erstmal weggelassen, da
> ich weder den ADC noch die anderen Pins verwende.

Du musst ihn aber trotzdem speisen, denn wenn AVCC um mehr als ein paar 
zehntel Volt von VCC abweicht, ist das ein Verletzen der Specs. Wieviel 
genau die Abweichung sein darf steht im Datenblatt, und, wie o.a., auch 
der Hinweis, das man auf jeden Fall speisen muss.

Wenn du den MC mit dem Strom verbindest, dauert es übrigens auch eine 
Weile, ehe die 100nF geladen werden, du hast also schon mal eine 
steigende Flanke.

Zur Entprellung:
https://www.mikrocontroller.net/articles/Entprellung

Es gibt hard- und softwarebasierte Methoden. Wenn in der Software eh 
schon einer Timerinterrupt verwendet wird, bietet sich Software an.

von Helmut L. (helmi1)


Bewertung
0 lesenswert
nicht lesenswert
Da M. schrieb:
> Wenn das Auswerten der Taster per Interrupts Mist ist, dann frag ich
> mich wie man sonst anständig Taster abfragt.

In einem Timerinterrupt wird das gemacht. Man schaut sich in einem 
Timerinterrupt den zustand des Tasters an und wenn er mehrfach 
hintereinander derselbe war dann ist die Taste erkannt. Die Zeit 
zwischen zwei mal anschauen des Tasteneingangs sollte dabei groesser 
sein als die maximale Prellzeit des Tasters.

von Georg G. (df2au)


Bewertung
0 lesenswert
nicht lesenswert
Noch ein Hinweis: Setzt doch das DDRD passend, so dass die beiden Taster 
Pins auch Eingänge sind. Im Sinne einer defensiven Programmierung ist 
das sinnvoll.

von H.Joachim S. (crazyhorse)


Bewertung
0 lesenswert
nicht lesenswert
Ich denke, du hast eine Brücke zwischen D2 und D3.
Egal, welchen Taster du drückst werden beide Ints ausgelöst und in der 
Reihenfolge Int0 dann Int1 abgearbeitet. NAch aussen scheint es, als ob 
nur Int1 aktiv war.

von Hubert G. (hubertg)


Bewertung
0 lesenswert
nicht lesenswert
Also an deinem Programm liegt es sicher nicht. Hatte gerade einen Mega8 
am Steckbrett und deine Schaltung getestet, funktioniert.
Also solltest du mal deinen HW-Aufbau kontrollieren.

von Da M. (da_ma)


Bewertung
0 lesenswert
nicht lesenswert
Helmut L. schrieb:
>> Wenn das Auswerten der Taster per Interrupts Mist ist, dann frag ich
>> mich wie man sonst anständig Taster abfragt.
>
> In einem Timerinterrupt wird das gemacht. Man schaut sich in einem
> Timerinterrupt den zustand des Tasters an und wenn er mehrfach
> hintereinander derselbe war dann ist die Taste erkannt. Die Zeit
> zwischen zwei mal anschauen des Tasteneingangs sollte dabei groesser
> sein als die maximale Prellzeit des Tasters.

Ja das ist natürlich ne gute Idee. Darauf kam ich bisher nicht. Danke. 
Was ist denn so eine Standardzeit auf die man den Timerinterrupt setzen 
sollte? Ich hab mal irgendwo gelesen, dass ein Tastenprellen bis zu 10 
ms dauert.

Edit: Ich habe auch schon mal versucht mit dem Multimeter auf die Suche 
zu gehen. Eine Brücke ist da auf jeden Fall nicht zu finden. Habe auch 
geschaut ob bei einem Tastendruck an den Pins jeweils 0 V anliegt. Auch 
das sah gut aus. Bin mir eigentlich ziemlich sicher das der Aufbau 
korrekt ist... Oder zumindest wie in der oben gezeigten Schaltung ;)


Ich werde dann eure Tipps nachher, wenn ich wieder zuhause bin, gleich 
ausprobieren und hoffen. Aber schon mal vielen Dank. Man merkt das ihr 
das schon etwas länger macht :P

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Bewertung
0 lesenswert
nicht lesenswert
Da M. schrieb:
> Ich werde dann eure Tipps nachher, wenn ich wieder zuhause bin, gleich
> ausprobieren und hoffen.

 Ich an deiner Stelle würde in Int1 gar nichts machen, weil ich die
 Meinung von H.Joachim S. teile.

 Also, in main() periodisch die LEDs ausschalten (etwa 1 Mal/sec) und
 nur in Int0 etwas machen, dann siehst du auch gleich, ob die Routine
 angesprungen wird.

: Bearbeitet durch User
von Helmut L. (helmi1)


Bewertung
0 lesenswert
nicht lesenswert
Da M. schrieb:
> Was ist denn so eine Standardzeit auf die man den Timerinterrupt setzen
> sollte? Ich hab mal irgendwo gelesen, dass ein Tastenprellen bis zu 10
> ms dauert.

Den kannst du natuerlich auch fuer weiter Sachen noch gebrauchen. Um 
irgendwelche Zeiten zu erhalten, um im Hintergrund LEDs zu flashen etc.

Ich stelle den Timerinterrupt meisten auf 1ms.  So kann man 
Softwaretimer mit aufloesungen von 1ms erhalten die dann an anderer 
Stelle im Programm gebraucht werden.  Fuer die Tastenentprellung rufe 
ich dann z.B. nur bei jeden 10mal die Tastenabfrage auf (dann 10ms). 
Alles in einem Timerinterrupt.

von Arduino Fanboy D. (ufuf)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir die Schaltung auch mal angesehen ....

Die Kondensatoren an den Tastern....
Wieviel Strom müssen die Taster schalten? ;-) (rechne mal aus)
Auf die Pullup kann man evtl. verzichten, die hat der AVR eingebaut.
Und Strombegrenzungswiderstände, in Reihe zum Kondensator, ist sicher 
kein Fehler. Und seien es nur 100 Ohm

Die Kondensatoren dämpfen einen Großteil des Prellens.
Das Thema prellen ist damit schon quasi durch.


Tasterabfrage:
Ja, per Timer.
Aber auch der INT kann Sinn machen, wenn man der AVR damit aus dem 
Tiefschlaf holen möchte. PCINT ist da auch eine gute Alternative, wenn 
es der AVR kann.

Und ja, Avcc muss angeschlossen werden. Sonst drohen komische 
Erscheinungen.
Auf die Induktivität kann man verzichten, wenn der ADC nicht genau (oder 
gar nicht) arbeiten muss, aber auf den Anschluss selber nicht.

: Bearbeitet durch User
von Da M. (da_ma)


Bewertung
0 lesenswert
nicht lesenswert
So ich bin endlich dazu gekommen mich nochmal an die Schaltung zu 
setzen. Ich habe jetzt AVCC mit 5V verbunden und das DDRD Register für 
INT0 und INT1 auf Input zu setzen. Leider hat das keinen Erfolg 
gebracht.

Hab dann auch mal die ISR, die ausgelöst wird, auskommentiert. Dann 
passiert gar nichts mehr. Also liegt es daran wohl auch nicht.

Ich werd mich jetzt dran setzen und die Abfrage per Timer zu 
programmieren

: Bearbeitet durch User
von Werner P. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Miss doch erst mal mit einem Multimeter an den Eingängen ob die Pegel 
passen.

Ich denke auch dass da ein Hardwarefehler vorliegt.

von Da M. (da_ma)


Bewertung
0 lesenswert
nicht lesenswert
Das hab ich schon hinter mir. Bin jeden einzelnen Pin des Controllers 
abgegangen um zu schauen ob die gewünschte Spannung anliegt. Auch bei 
gedrückten Tastern. Alles wie es soll...

Hab den Verdacht das der Controller vielleicht ne Macke hat :(

von Hubert G. (hubertg)


Bewertung
0 lesenswert
nicht lesenswert
Da M. schrieb:
> Hab den Verdacht das der Controller vielleicht ne Macke hat :(

Das wäre natürlich auch noch eine Möglichkeit. Das Programm hat, wie 
schon geschrieben, keinen Fehler. Wenn man davon absieht das man Tasten 
besser mit Polling als mit einer ISR abfragt.

von Georg G. (df2au)


Bewertung
0 lesenswert
nicht lesenswert
Da M. schrieb:
> Verdacht das der Controller vielleicht ne Macke hat

Das habe ich auch schon oft vermutet. Leider hat sich in der Praxis 
meist herausgestellt, dass der Fehler doch vor dem Bildschirm saß.

von LostInMusic (Gast)


Bewertung
0 lesenswert
nicht lesenswert
>Leider [...]

Kann man auch positiv sehen: Fehler in der Controllerhardware wären 
wegen der praktischen Unmöglichkeit, sie zu korrigieren, schlimmer.

Ansonsten stimme ich Dir voll zu.

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]
  • [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.