mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt beim AVR


Autor: Oilaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche mich gerade daran einen Interrupt (INT0) auszulösen.
Mit dem Beispielprogramm aus dem "AVR-Tutorial interrupts" komme ich in 
dem AVR Studio 3.56 aber nicht ganz klar. Nach dem Assemblieren versuche 
ich den Interrupt in einem IO-Fenster Port D 0x12 Portpin PD2 von Hand 
auszulösen, aber nichts passiert. Erst wenn im DDRD 0x11 den DDD2 auf 1 
setze klappt das auslösen von Hand nur dass dann ja der PD2 als Ausgang 
geschaltet ist. So ungefähr verhält sich auch meine Schaltung da 
allerdings mit einem AT90S2313.
Für einen Tipp was ich falsch mache, wäre ich dankbar.

Gruß Olaf

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR Studio 3.56 ist schon eine Zeit lang abgehangen und ich könnte das 
nur mit einem neueren AVR Studio testen (4.12 oder 4.13). Hängst du 
trotzdem mal deinen Quelltext an?

Autor: Oilaf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Es ist eigentlich ähnlich gemacht, wie im "AVR-Tutorial interrupts".
das Verhalten ist bei beiden Quelltexten gleich.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hat etwas länger gedauert.

Ich hatte zuerst das falsche Target (Attiny2313 statt AT90S2313) und ein 
paar Probleme mit dem AVR Studio Simulator bis ich begriffen hatte wie 
und wann man PIND2 ändern darf (im Break).

Dein Programm habe ich auf das wesentliche (INT0-Demo) abgespeckt.

; ################
; ### Includes ###
; ################
.include "2313def.inc"
; TARGET = AT90S2313

; ####################
; ### Definitionen ###
; ####################
.def    temp    =r16

; #####################
; ### Vektortabelle ###
; #####################
.org 0x0000
         rjmp  main         ; Reset Handler
.org INT0addr
         rjmp  INT0_Handler  ; IRQ0 Handler

; #####################
; ### Hauptprogramm ###
; #####################
main:
    ; ########################
    ; ### Stack einrichten ###
    ; ########################
  ldi  temp, RAMEND
  out  SPL, temp
         
    ; #############################
    ; ### Interrupts einstellen ###
    ; #############################

    ; ISC01 (1<<1) 1 und ISC00 (1<<0) 0 
    ; => FALLENDE Flanke von INT0 erzeugt Interrupt
  ldi  temp, 0b00000010
;  ldi  temp, 0b00000000  ; altern.: LOW an PD2 gibt INT0
  out  MCUCR, temp

  ldi  temp, 0b01000000  ; INT0 (1<<6) an PD2 zulassen
  out  GIMSK, temp

  sei        ; Interrupts allgemein aktivieren
  
    ; #######################
    ; ### Arbeitsschleife ###
    ; #######################
loop:
  rjmp  loop       ; loop forever

; ########################
; ### Interrupthandler ###
; ########################
    ; ############
    ; ### Int0 ###
    ; ############
INT0_Handler:
  push  temp
  in  temp,sreg
  ; hier Nutzcode einfügen
  out  sreg,temp
  pop  temp
  reti

; Simulation in AVR Studio
;
; Der Interrupt bei fallender Flanke tritt auf, 
; wenn PIND2 auf HIGH gesetzt war und im Break 
; auf LOW gesetzt wird.
;
; 1/ Breakpoint auf "push temp" in INT0_Handler
; 2/ Run (F5)
; 3/ Break (Strg-F5)
; 4/ PIND2 ändern in Fenster I/O-View
; 1/ ...
;
; ENDE 


Autor: Oilaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,
vielen Dank für Deine Hilfe, aber mein eigentliches Problem ist offenbar 
nicht ganz deutlich geworden, ich habe mich wohl missverständlich 
ausgerückt. Das Problem besteht weniger darin, dass ich mit der 
Konfiguration des Interuts oder des Simulators nicht klar komme. Der 
Portpin scheint das Problem zu sein.
Konfiguriere ich ihn als Eingang
  ldi  temp, 0b11111011
  out  DDRD, temp
dann reagiert er nicht, weder im Simulator noch in der Schaltung.
Konfiguriere ich ihn als Ausgang
  ldi  temp, 0b11111111
  out  DDRD, temp
dann funktioniert es zwar im Simulator, aber in der Schaltung bedeutet 
das für den angeschlossenen Temperatursensor SMT 160-30 quasie ein 
Kurzschluss und ein Interrupt wird schon gar nicht ausgelöst.
Ich habe schon alles (mir) mögliche ausprobiert, aber alles ohne Erfolg.

Gruß Olaf

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Simulator kann keine externen Ereignisse erkennen, die must Du also 
manuell auslösen. Die Hardware in Deinem Fall wird nur funktionieren, 
wenn der Interruptpin als Eingang geschaltet ist. Warum probierst Du das 
Programm nicht auf dem Controller selbst? Schalte in der 
Interruptservice-Routine eine LED an / aus.

Autor: Oilaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja richtig alle Deine Vorschläge habe ich schon ausprobiert, ohne 
Erfolg. Wenn ich Port D Pin 2 (0x12 bit 2), bei auf Eingang (0x11 bit 2 
auf 0) konfigurierten DDRD, im Simulator hin und her schalte wird kein 
Interrupt ausgelöst. Die Sache mit der LED im INT0_Handler habe ich auch 
schon probiert, es verhält sich wie oben beschrieben.

Gruß Olaf

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kenne zwar Deinen Sensor nicht, vermute aber, dass er einen 
open-Collector (open-Drain)-Ausgang hat, da brauchst Du einen 
PullUp-Widerstand. Oder bringt der Sensor selbst L- und H-Pegel?

Wenn Du den internen PullUp nutzen willst, dann muss DDR auf 0 (Eingang) 
und PORT auf 1 (PullUp ein).

...

Autor: Oilaf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte auch schon einen Schalter am PD2 angeschlossen, aber der 
SMT160 ist TTL/CMOS- kompatibel. Ich verstehe das nicht, es ist ja 
letzlich die gleiche Situation wie im AVR-Tutorial interrupts, das haben 
doch bestimmt schon viele Leute ausprobiert. Also muss der Fehler doch 
in meinem Aufbau/Programm liegen.

Gruß Olaf

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Abgesehen davon, Du benutzt einen Tiny2313, richtig? Nicht etwa einen 
90S2313? Noch ein Gedanke: der Sensor spuckt eine Rechteckfrequenz mit 
variablem Tastverhältnis aus. Wäre es in dem Fall nicht besser, den 
Input Capture Interrupt zu benutzen? Das würde die Zeitmessung erheblich 
vereinfachen.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch etwas: es hat sich allgemeinhin als sinnvoll erwiesen, eine 
komplette Interrupt-Vektorentabelle an den Anfang des Codes zu stellen 
(anstatt einzelner .org-Segmente) und das eigentliche Programm immer 
nach den Interruptvektoren anfangen zu lassen. Somit können 
versehentlich aktivierte und ausgelöste Interrupts abgefangen werden, 
die ansonsten ein Chaos beim Einspringen in durch Programmcode belegte 
Vektoren anrichten könnten.

Autor: Oilaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch es ist der 90S2313 gibt es mit dem ein Problem?
Natürlich kann ich das auch anders machen, das werde ich auch sicher 
irgendwann, wenn ich mich erst mal richtig in die AVR´s eingearbeitet 
habe.
Aber ich werde sicher wieder auf das Problem stoßen einen Interrupt 
auslösen zu müssen, und dann fange ich wieder an dieser Stelle an. Das 
ist sicher auch ein persönliches Problem, wenn ich mich erst mal an 
einer Sache festgebissen habe, dann kann ich nicht mehr loslassen.

Gruß Olaf

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kenne ich. Nein es gibt keine Probleme mit dem 90S2313, zumindest 
dort nicht. Es sollte gehen. Allerdings solltest Du das temp, in das Du 
das SREG gesichert hast, noch auf den Stack schreiben, sonst kannst Du 
es in der gesamten ISR nicht mehr verwenden. Hast Du denn jetzt auf dem 
Controller von Hand schon einen Interrupt ausgelöst? Wie sieht die 
Portregisterdefinition aus? Poste doch mal das Gesamtprogramm!

Autor: Oilaf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das ist ja das Problem, ich kriege den Interrupt nicht ausgelöst. 
An dem Quellcode habe ich noch nichts geändert (Posting gestern 16:08). 
Zur Sicherheit habe ich noch mal den eigentlich bekanntetn Schaltplan 
dran gehängt, den SMT160 bzw. einen Schalter gegen Masse mit PullUp kann 
man sich sicher leicht dazudenken.
Hilfreich wäre ja auch ein Projekt, in dem die Sache mit einem Interrupt 
in der AVR-Basicline schon mal umgesetzt wurde und nachweislich 
funktioniert hat, ich habe noch nichts passendes gefunden.

Gruß Olaf

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte mir Dein Programm gestern schonmal kurz angesehen, hatte es 
aber gleich wieder geschlossen, weil es sehr schwer lesbar ist. Da 
passen die Kommentare nicht zu dem Code, da werden Bits nicht beim Namen 
genannt, sondern als kryptische Binärzahlen. Da fehlte mir echt die 
Lust, wegen jedem Bit im Datenblatt nachzuschauen, was denn nun gemeint 
ist. Dazu kommt dann noch die Art der Interrupt-Vektoren und der 
unverständliche Unsinn in der Mainloop. Da aber zur Zeit einige Leute 
darüber meckern, wie hier Anfänger behandelt werden, habe ich mich mit 
der Kritik erstmal zurückgehalten.

Du fragst nach einem Programmcode, der im 2313 mit externem Interrupt 
arbeitet. Hier ist einer, der macht aber nicht das, was Du brauchst:
http://www.hanneslux.de/avr/mobau/impdecoder/idec2313.asm
Die Beschreibung dazu ist hier:
http://www.hanneslux.de/avr/mobau/impdecoder/idec.html

Nun zur Aufgabe, die Du erledigen willst...
Du willst eine Impulsbreite mit einem externen Interrupt messen, also 
ein Software-ICP.
Du hast in Deinem Programmentwurf in Main Int0 auf fallende Flanke 
eingestellt (MCUCR). Um eine Impulsbreite zu messen, brauchst Du aber 
beide Flanken. Du musst in der ISR die Flanke umschalten.

Hier ist eine Impulsbreitenmessung mit ext.-Int für Tiny15:
http://www.hanneslux.de/avr/mobau/fr_t15/T15frb01.asm
mit Beschreibung http://www.hanneslux.de/avr/mobau/fr_t15/fr_t15.html
und hier http://www.hanneslux.de/avr/index.html noch ein paar andere 
Beispiele.
Hier http://www.hanneslux.de/avr/pollin_ir8/index.html findest Du eine 
Impulsbreitenmessung im Tiny2313, die mit ext.-Int arbeitet. Da ist auch 
zu sehen, wie ich jetzt die Int-Vektoren anordne.

Zum Analysieren Deines Quelltextes bis ins Detail fehlt mir aufgrund der 
kryptischen Bitnamen immernoch die Lust, sorry.

...

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Interrupt funktioniert mit Sicherheit. Hast Du den Spannungswechsel 
an PD2 mal mit einem Multimeter gemessen, ob Du tatsächlich Low 
erreichst?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Oilaf

Was du mit DDRD rummachst, verstehe ich nicht.

Hier die Erweiterung zum Toggeln der LED an PB0 aus deinem Schaltbild, 
wenn ein INT0 (Fallende Flanke: PD2 wechselt von HIGH auf LOW) auftritt.

; ################
; ### Includes ###
; ################
.include "2313def.inc"
; TARGET = AT90S2313

; ####################
; ### Definitionen ###
; ####################
.def    temp    =r16
.def    temp2   =r17

; #####################
; ### Vektortabelle ###
; #####################
.org 0x0000
         rjmp  main           ; Reset Handler
.org INT0addr
         rjmp  INT0_Handler  ; IRQ0 Handler

; #####################
; ### Hauptprogramm ###
; #####################
main:
    ; ########################
    ; ### Stack einrichten ###
    ; ########################
  ldi  temp, RAMEND
  out  SPL, temp

    ; ############################################
    ; ### LOW ACTIVE LED an PB0 initialisieren ###
    ; ############################################
    ; Toggelt später in INT0_Handler
  ldi  temp, 0b00000000  ; PB0 LOW (LED_AN)
  out  PORTB, temp
  ldi  temp, 0b00000001  ; PB0 Ausgang
  out  DDRB, temp
         
    ; #############################
    ; ### Interrupts einstellen ###
    ; #############################

    ; ISC01 (1<<1) 1 und ISC00 (1<<0) 0 
    ; => FALLENDE Flanke von INT0 erzeugt Interrupt
  ldi  temp, 0b00000010
  ;  ldi  temp, 0b00000000  ; altern.: LOW an PD2 gibt INT0
  out  MCUCR, temp

  ldi  temp, 0b01000000  ; INT0 (1<<6) an PD2 zulassen
  out  GIMSK, temp

  sei            ; Interrupts allgemein aktivieren
  
    ; #######################
    ; ### Arbeitsschleife ###
    ; #######################
loop:
  rjmp loop       ; loop forever

; ########################
; ### Interrupthandler ###
; ########################
    ; ############
    ; ### Int0 ###
    ; ############
INT0_Handler:
  push temp
  in   temp,sreg
  ; Anfang Nutzcode
  ; => PB0 toggeln
  push temp
  push temp2
  ldi  temp2, 0b00000001
  in   temp, PORTB
  eor  temp, temp2
  out  PORTB, temp
  pop  temp2
  pop  temp
  ; Ende Nutzcode
  out  sreg,temp
  pop  temp
  reti

; Simulation in AVR Studio
;
; !/ Keine Breakpoints
; 2/ Auto-Step (ALT-F5)
; 3/ PIND2 manipulieren und PORTB0 beobachten
;    PORTB0 toggelt, wenn PIND2 von HIGH => LOW wechselt
;.
; ENDE 



Anschluss eines Schalters an PD2:

   ^ Vcc +5V
   |
   |
  +-+
  | | Pull-Up
  | | 10K
  +-+
   |
   |
   +--------+ PD2
   |
   |  |
 L +  + H (bei PD2)
      /
     /
    /  Schalter
   +
   |
   |
  --- GND


Autor: Oilaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstmal vielen Dank für die Hilfe, ich will Euch auch nicht zu sehr 
nerven.
@ Hannes Lux,
da gebe ich Dir Recht, übersichtlich ist der Quelltext nicht gerade. Das 
liegt daran, dass ich in den Programmen immer viel ausprobiere und nach 
dem Ausprobieren nicht immer alles lösche. Ich habe sicher nicht so 
einen ganz profesionellen Programmierstil. Ich werde mir Deine Beispiele 
mal in Ruhe ansehen. Vielen Dank

@ Travel Rec.Ich schwöre, mit Oszilloskop direkt am Beinchen gemessen.

@ Stefan, ich probier deinen Quellcod nochmal aus, merkwürdig finde ich 
nur, dass das Verhalten im Simulator (AVR Studio 3.56) das Verhalten in 
der Hardware wiederspiegelt.

Gruß Olaf

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR-Studio 3.5x nimmt Niemand mehr, Du solltest aus Gründen der 
Kompatiblität mit den Helfenden auf AVR-Studio 4.xx updaten. Es muss ja 
nicht immer die allerneueste Version sein, aber zwischen 3.5x und 4.xx 
hat sich allerhand geändert.

...

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.