mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik externer Interrupt


Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi
tut mir Leid wenn ich euch schon wieder mit sehr einfachen Frage quäle:
Ich programmiere mit einem AT90CAN128 auf einem DVK90CAN1. Ich will die 
Tasten ansteuern damit z.B.: die Leds damit aus und eingeschalten 
werden.
In der manual vom Board hab ich gelesen das die Tasten einen externen 
Interrupt aulösen. INT7 - INT4. Leider springt mir das Programm nicht in 
die ISR. Ihr könnt ihr mir sicher helfen.
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(INT7_vect){

PORTA = 0xFF;

}//end isr int7 

int main(){
DDRA = 0xFF;//direction for LEDs are output
DDRE = 0xFF;//direction is ouput
PINE = 0xFF;//PINE are set 1
EIMSK = 0xF0;//Interrupt for INT7 to INT 4 are available
EICRB = 0x00;//interrupt for INT7-INT4 are lowLevel
SREG = 0x80;//global Interrupt are available



for(;;);//endloschleife

return(0);
}//end main

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
falsch ist:
PINE = 0xFF;//PINE are set 1
richtig wäre:
PORTE = 0xFF

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort. Leider funktioniert das immer noch 
nicht. Siehst du vielleicht noch einen anderen Fehler???

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ausserdem ist dein Programmierstil etwas unübersichtlich. Probier doch 
mal folgendes:
EIMSK |= (1<<INT4) | (1<<INT5) | (1<<INT6) | (1<<INT7);
EICRB &= ((1<<ISC40) | (1<<ISC41) | ...);
SREG |= (1<<I);
Das ist zwar etwas aufwendiger, erleichtert es aber zu verstehen, was 
genau programmiert ist.

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm jetzt kenn ich mich nicht mehr aus. Wieso ist das einfacher als nur 
die Registereinstellungen in hex zuweise???

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde EICRB nich auf  low-level, sonder auf fallende Flanke 
implementieren (Datenblatt Seite 94, Table 10-3)
also:
EICRB &= ((1<<ISC40) | (1<<ISC50) | (1<<ISC60) |( 1<<ISC70));
EICRB |= (1<<ISC41) | (1<<ISC51) | (1<<ISC61) | (1<<ISC71);

Hast Du den Taster entprellt?

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wieso ist das einfacher
Weil Du so nachher (auch nach mehreren Wochen) noch genau siehst, welche 
Bits im Register nach Datenblatt gesetzt und gelöscht sind.

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du das schon mal durchgelesen?
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PORTA solltest Du am Anfang auf 0 setzen:
PORTA = 0x00;
Damit der Ausgang definiert auf 0 liegt.

Andere Frage:
Wie sind die LED beschalten? High- oder Low-activ?

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt hab ich den Fehler entdeckt.

DDRE ist ja gar kein Output.
Richtig wäre:
DDRE = 0x00;

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also mit dem & operator setz ich eine 1 und mit dem ODER-Operator 
schreib ich eine 0 ins Registerbit
Was heisst die Tasten entprellt?? Das komplette Programm was ich 
geschrieben habe hab ich eh im ersten Beitrag geschrieben.
Offensichtlich ist das Tastenansteuern nicht so einfach wie ich dachte.

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, wenn ich Dich jetzt verwirre, aber oben hab ich noch einen 
kleinen Fehler gemacht.
Es heisst nicht
EICRB &= ((1<<ISC40) | (1<<ISC41) | ...);
sondern jeweils
EICRB &= ~((1<<ISC40) | (1<<ISC41) | ...);

Ich hab das ~ vergessen.

Tasten entprellen: Entprellung

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lies das hier mal gründlich durch. Vielleicht ist dann einiges klarer:
Bitmanipulation

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke nochmals für deine Hilfe. Werd mich da mal ein bisserl einlesen 
und es dann nocheinmal programmieren

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert es denn jetzt, wenn Du DDRE als Eingang anstatt als Ausgang 
definierst?

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein da geht gar nichts. Ich hab ja die Tasten auch nicht entprellt weil 
ich dachte das beim ersten Kontakt ein Interrupt ausgelöst wird.

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ahh geht doch ich hab einen Beitrag von dir übersehen
super danke jetzt funkt so wie es soll

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dazu eine Frage an die Allgemeinheit:

Warum liest man nichts mehr von sei();? Ist das im StartupCode vom GCC 
schon drin?

An der OP:
Programcode zu schreiben, den eine Maschine versteht, kann jeder. Die 
Kunst liegt darin, den Code auch für den Menschen verständlich und 
wartbar zu halten.

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sei() ist doch nichts anderes wie
[c]SREG |= (1<<I);

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick wrote:
> sei() ist doch nichts anderes wie
> [c]SREG |= (1<<I);

ok, das war mir neu...danke.

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab die Erfrahrung gemacht das beides funktioniert. sei(); und SREG 
= 0x80;
Wenn ich das status register so SREG |= (1<<I); beschreibe bekomme ich 
eine Fehlermeldung vom Compiler

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann mach folgendes:
SREG |= (1<<7);  //Bit 7 von SREG auf 1

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick wrote:
> sei() ist doch nichts anderes wie
> [c]SREG |= (1<<I);
Doch, das ist sehr wohl was anderes! "sei()" ist atomar, Deine Version 
aber nicht! Aus Deiner Version werden 3 Assembler-Befehle, sei ist ein 
einziger.

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok das geht jetzt
danke

Autor: Tartaruga (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab da noch eine andere Frage die nicht so ganz zum Thema passt. 
Wenn ich mit dem Input Capture arbeite und mit die Periodendauer eines 
Rechtecksignals ausrechen will. Auf welchen Bus muss das signal anliegen 
das das funktioniert. Ich hab in der Manual nur immer 8-Bit Bus gelesen.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes:
Das kan man nicht so allgemein behaupten.
CodeVision macht daraus:
82 SREG |= (1<<I);
000a2 9478        BSET 7

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
crazy horse wrote:
> @Johannes:
> Das kan man nicht so allgemein behaupten.
> CodeVision macht daraus:
> 82 SREG |= (1<<I);
> 000a2 9478        BSET 7
OK, wenn CodeVision das hinbekommt... Der AVR-GCC machts nicht. Und 
bevor man jedes mal erst ins Assembler-Listing schauen muss, um zu 
erfahren, was der Compiler da wirklich draus macht, schreibt man doch 
besser gleich die richtige Anweisung hin, aus der der Compiler mit 
Sicherheit den korrekten Assembler-Code macht (OK, in CodeVision gibt es 
die "Funktion" sei() nicht, da muss man eh #asm("sei") schreiben...)

Abgesehen davon halte ich es sowieso für unsinnig, so einen Ausdruck da 
hinzuschreiben, wenn es kürzer und prägnanter geht...

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, ich hab aber verstanden. Die Wirkung ist die selbe... Viele Wege 
führen nach Ram...ähh Rom..

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niels Hüsken wrote:
> Ok, ich hab aber verstanden. Die Wirkung ist die selbe...
Nö, ist sie nicht. Das merkst Du spätestens dann, wenn Du die Interrupts 
*de*aktivieren möchtest und das eben drei Befehle braucht anstatt einen. 
Zugegeben: beim sei (also bei der Freigabe) ist es i.d.R. wirklich 
unkritisch, aber zumindest beim cli kann es zu unerwünschten 
Nebeneffekten kommen (natürlich auch nur in Ausnahmefällen, aber 
immerhin, warum sich was unsinniges angewöhnen)...

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.