PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C und Interrupteingänge



liggi
05.11.2007, 19:56
Hallo Leute

ich hab ein paar Fragen:
1. Wie kann man einen Eingang(INT0), der Interrupt fähig ist als Interrupteingang festlegen.
2. Bei I2C gibt es ja eine Interruptleitung, kann diese an den oben genannten Interrupteingang angeschlossen werden?
3. Bei der LCD-Erweiterung wird der oben genannte Pin benutzt kann man dies irgendwie verändern?

Vielen Dank im vorraus

Arexx-Henk
06.11.2007, 11:36
Hallo,

INT0 wird wie Interrupt funktionieren wenn enable bit INT0 in Register GICR activiert (Hoch) wird.
Mit bits ISC00 und ISC01 in Register MCUCR stellt mann ein auf welchen weise die INT0 eingang ein Interrupt erkannt.

Bei I2C finde ich kein Interrupt, nur Clock und Data.

Die LCD-Erweiterung habe ich bis jetzt leider nicht studiert.

Gruss

Henk

liggi
06.11.2007, 12:51
Hallo Henk,

könntest du mir ein Beispiel posten? Bei I2C gibt es auch noch eine optionale Interruptleitung.

mfg liggi

damaltor
06.11.2007, 18:34
i2c hat keinen interrupt, da hat henk schon recht. i2c hat NUR data (SDA) und takt (SCL). du meinst vermutlich den baustein PCF8574(A), die 8bit-Porterweiterung. diese generiert einen interrupt, welcher aber vom i2c vollkommen unabhängig ist.

liggi
06.11.2007, 19:30
Danke, dann hab ich irgendwas falsch verstanden.

mfg liggi

Ceos
12.12.2007, 09:57
mahlzeit, ich find das ganz interessant mit dem interrupt

ich hab mal folgendes versucht


void StartExtInt(void)
{
PORTD &= ~(1 << PD2);
DDRD &= ~(1 << PD2); // Switches as Input => ext. Int 1
MCUCR &= ~((1 << ISC00) | (1 << ISC01));// Low level generates interrupt
GICR |= ~(1 << INT0);
}

void StopExtInt(void)
{
GICR &= ~(1 << INT0);
DDRD |= ~(1 << PD2); // Switches as Input => ext. Int 1
PORTD |= ~(1 << PD2);
}

// die ISR hab ich in der prog-file angelegt

SIGNAL (SIG_INTERRUPT0)
{
StopExtInt();
SerWrite("SIG INT0 Done", 13);
StartExtInt();
}



meine frage, wäre das in ordnung um den INT0 port als interrupt zu schalten ?
ausserdem die frage was soll ich mit dem rotanschlus der status LED machen (im Bild mit ? markiert)? muss ich den wegkratzen ? weil wenn ich jetzt CON2 mit VCC überbrücke (mit und ohne widerstand probiert) passiert nix ... aber mein atmega scheint jedesmal neu zu starten wenn ich startswitch(); (ja ich meine startSWITCH()) aufrufe (also der aufruf im interrupt)

wo liegt mein fehler, was muss ich machen um con2 effektiv nutzen zu können ?

damaltor
12.12.2007, 10:36
nicht unbedingt: über die led wird der pin auf low gezogen. wenn du dafür sorgst dass ein HIGH pegel den interrupt auslöst musst du nichts ändern.

Ceos
12.12.2007, 10:40
und wie mach ihc das ? tut mir leid, SO weit reicht mein wissen nciht, ich hab das nur vom int1 adaptiert, bitte hilf mir >_<

ausserdem erklärt mir das noch nicht ganz warum es mir immer den IC resettet wenn ich einen taster LOSLASSE!!! (ich hab testhalber ne ausschrift nach dem init() eingebaut die dann immer wieder ausgelöst wird)

damaltor
12.12.2007, 10:48
oh oh das weiss ich auch nicht aus dem kopf...
aber schau mal ins datenblatt vom meg8
www.atmel.com/dyn/resources/prod_documents/doc2486.pdf
auf seite 67 stet was du wissen musst. hab eben mal nachgesehen, du musst ISC00 und ISC01 auf 1 setzen, dass löst eine steigende flanke den interruot aus.

Ceos
12.12.2007, 10:52
heißt ich mach aus

MCUCR &= ~((1 << ISC00) | (1 << ISC01));// Low level generates interrupt

MCUCR |= ~((1 << ISC00) | (1 << ISC01));// High level generates interrupt
? danke für die hilfen ich teste es mal ^^

damaltor
12.12.2007, 10:53
nein nicht ganz.

du machst auch noch die ~ weg in der zeile.

Ceos
12.12.2007, 10:59
>_< oh mann ... :oops:

damaltor
12.12.2007, 11:00
kleiner fehler, große wirkung... und nach sowas kann man lange suchen.

aber naja.. ich wünsch dir viel erfolg, geh jetzt erstmal an die FH.

Ceos
12.12.2007, 11:22
void StartExtInt(void)
{
PORTD &= ~(1 << PD2); // CON2 wird vom PortD genommen
DDRD &= ~(1 << PD2); // CON2 (RED_LED) auf Input => ext. Int 0
MCUCR |= ((1 << ISC00) | (1 << ISC01)); // High level interrupt
GICR |= (1 << INT0); // interrupt aktiviren (da habe ich vorher auch n ~ noch davor gehabt deswegen der kurzschluss)
}

void StopExtInt(void)
{
GICR &= ~(1 << INT0); // Interrupt löschen
DDRD |= ~(1 << PD2);
PORTD |= ~(1 << PD2);
}

SIGNAL (SIG_INTERRUPT0)
{
StopExtInt();
SerWrite("SIG INT0 Done", 13);
StartExtInt();
}


ET FUNKT ET FUNK DANKE GOTT .... äh damaltor mein ich >_<

damaltor
12.12.2007, 14:52
lol.

die neue C-konvention sagt übrigens dass es nicht mehr SIGNAL heisst sondern

ISR(NAMEDESINTERRUPTS_vect){
...}

aber wenn es funktioniert dann ist ja alles gut =)

Ceos
12.12.2007, 15:11
wenn das nicht für so n DÄMLICHES projekt notwendig wäre würd ich mir dieses experimentierborad für atmega nehm was ich bei elektronischen schaltungen gefunden habe und damit arbeiten ... dann würd ich mich hinreissen lassen alle ports einstellungen usw. selber zu machen aber dank deinr hilfe geht es jetzt ... nu wart ich nurnoch das mein bestelltest cmps modul ankomm, dann teste ich es gleich ^^

Ceos
15.12.2007, 10:17
Eine Frage hät ich noch und zwar an die Mods des Forum .... warum macht ihr nicht eine kleine Sammlung von Posts und Kommentaren als ne FAQ-Sektion, wo man solche sachen wie z.B. das benutzen des Interrup0, oder andere sachen die der Asuro KANN, aber auf die man so einfach nicht kommt, finden kann?!
Wenn man die Boardsuche anstrengt muss man schon SEHR präzise stichworte angeben um nicht in den Antworten zu ertrinken XD

iss jetzt nur mal ne frage, weil ich solche FAQs aus vielen anderen Foren kenne und schätze

damaltor
15.12.2007, 11:33
hmm... das ist zwar eine schöne idee, aber leider für einen allein kaum zu bewältigen. wenn du magst, kannst du ja mithelfen - ich eröffne dann einen neuen thread bei den "ankündigungen" ganz oben über allen anderen. wenn viele leute da mit sachen zusammentragen, dann sollte das klappen. vorschläge, was mit in die faq sollte, bitte mit links usw sammeln und dann per pn an mich. wenn ich sehe dass die beteiligung daran funktioniert, dann könnte ich mir das vorstellen.

Ceos
18.12.2007, 14:41
oh hab deine antwort noch gar net bemerkt ... könn wa gern machen, ich werd mich mal bissl durch das forum wühlen wenn der stress nachlässt .... back to topic ... ich hab n problem ..... zwischen 2 steigenden flanken liegen bei dem modul IMMER 65ms und gemessen werden muss die pulslänge -_- ich hab den interrupt jetzt aber so geschaltet das er auf steigende flanken reagiert .... kann ich das iwie dennoch lösen TROTZ der scheiss LED da dran ? also den Pin auf high, low flanken und dann auf gnd ziehen ? oder gibt das n kurzen ? wie kann ich das noch umdrehen ? oder das signal invertieren ?

damaltor
18.12.2007, 19:04
hmm die led zeiht den pin auf gnd. da ist sponzan nicht viel zu machen.

der interne pullup ist glaub ich recht hochohmig, deshalb hilft der auch nicht viel (ausser dass die statusled dauernd glimmen würde). ich glaube da wirst du die led opfern müssen. wenn jemand ne idee hat..

Ceos
19.12.2007, 11:45
ich hab noch ne idee .... wenn der impusl kommt, zündert der interrupt, den leg ich dann lahm und prüfe solange zyklisch den eingang auf high pegel bis der impuls zu ende ist, dann schreib ich die verstrichene zeit in ne variable und schalt den interrupt wieder ein.

theoretisch sollte es gehen denk ich mir mal ... oder kommt da doch wieder der hammer ?

damaltor
19.12.2007, 13:33
du könntest einen timer starten wenn der interrupt kommt; und wenn der pegel wieder high wird den counter stoppen. dann hättest du ne exakte zeitmessung.

Ceos
19.12.2007, 15:42
zwische 2 high flanken liegen leider IMMER 65ms ... ich muss schon die länge des impulses messen, d.h. die zeit zwischen high flanke und dem abfallen des impulses
ich werde aber EVENTUELL I2C benutzen ... aber der umbau iss etwas komplizierter ...

zur ersten lösung, ich hab das modul fertig angeschlossen, mit dem oszi geprüft ... alles bestens, kalibrierung iss auch super ... nun muss ich nurnoch das programm schreiben ... 37ms idle iss aber nich SO toll Q_Q

wenn ich den interrupt für die odometrie aber anlasse müsste das doch in einer verschachtelung enden oder ?

damaltor
19.12.2007, 15:44
dann warte bis high wird, starte den counter, und wenn es wieder low wird machste ihn wieder aus...

Ceos
19.12.2007, 15:50
ja aber wie oben im editierten muss ich leider 37ms das hauptprogramm unterbrechen und nach min. 33ms kommt schon der nächste impuls ... ich seh schon es wird eng mit der rechenzeit XD ... oder ich mache es über ein flag und prüfe das signal im hauptprogramm zyklisch mit

damaltor
19.12.2007, 16:23
hm ich sehe das problem nicht. warte auf eine high-flanke, dann startest du den counter. da dieser im hintergrund läuft, brauchst du dich um nichts zu kümmern und dein programm kann normalen aufgaben folgen. wenn der pin wieder low wird, wird der counter gestoppt. wenn das programm es dann zulässt und nichts anderes zu tun hat, kann der counter ausgelesen und der wert bearbeitet werden.

dazu muss das hauptprogramm eigentlich gar nicht unterbrochen werden.

Ceos
19.12.2007, 16:35
dann muss ich eben im hauptprogramm zyklisch den pegel messen und den counter anhalten wenn low iss ^_^

damaltor
19.12.2007, 19:30
oder du lässt den interrupt auf die stegende flanke reagieren, startest den counter und stellst in der interruptroutine den interrupt so ein dass er bei einer fallenden flanke wieder zündet. und beim zweiten ausführen wird dann der counter weider gestoppt.

Ceos
19.12.2007, 23:50
fallende flanke geht doch net Q_Q wegen der diode und die will ich net opfern Q_Q

damaltor
20.12.2007, 02:41
ja dann musst du wohl mit der einschränkung leben dass du per hand kontrollieren musst wie sich das verändert...