Hallo Zusammen, ich versuche jetzt schon seit einigen Tagen die externen Interrupts meines ATMEGA128L-16AU im AVR STUDIO 4.18 GCC zum Laufen zu bringen. Habe gemerkt, dass die externen Interrupt nicht richtig funktionieren, denn was auch immer ich in die Register EICRA und EICRB (external interrupt control register a/b - dient der Einstellung der Aulösung - pos. Flanke, neg Flanke, GND, any log. change) reinschreibe, der µC reagierte immer auf GND-level. Und dann halt auch durchgängig - main - sleep - "GND auf INT0" - ISR - ISR - ISR - ISR -... - "GND weg von INT0" - sleep; Beim Abfragen der Bits im EICRA/B Reg bemerkte ich eine Art "Schreibschutz" - konnte die Bits nicht verändern. Habe dann mal alles wegkommentiert und nur eine Abfrage der Bits stehen lassen - Initial value beider Register (A&B) ist 00000000 - Seite 84 und 85 im Datasheet. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include <avr/io.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <avr/interrupt.h> #include "usart.h" int main(void) { usart_init(9600); usart_write("SysReady\n\r"); //EICRA = 0b00000000; // auch, wenn das einkommentiert ist das Resultat genauso //Init_Interrupt(); // da setze ich nur die Interrupts Enable z.B. EIMSK |=(1<<INT0); // hat aber auch keine Auswirkung auf da Reg. if(ISC01){usart_write("ISC01==1\n\r");} // hab´s auch mit ==1 versucht if(!ISC01){usart_write("ISC01==0\n\r");} if(ISC00){usart_write("ISC00==1\n\r");} if(!ISC00){usart_write("ISC00==0\n\r");} if(ISC11){usart_write("ISC11==1\n\r");} if(!ISC11){usart_write("ISC11==0\n\r");} if(ISC10){usart_write("ISC10==1\n\r");} if(!ISC10){usart_write("ISC10==0\n\r");} if(ISC21){usart_write("ISC21==1\n\r");} if(!ISC21){usart_write("ISC21==0\n\r");} if(ISC20){usart_write("ISC20==1\n\r");} if(!ISC20){usart_write("ISC20==0\n\r");} if(ISC31){usart_write("ISC31==1\n\r");} if(!ISC31){usart_write("ISC31==0\n\r");} if(ISC30){usart_write("ISC30==1\n\r");} if(!ISC30){usart_write("ISC30==0\n\r");} // restlicher auskommentierter Code return O; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ TERMINALAUSGABE ISC01=1 ISC00=0 ISC11=1 ISC10=1 ISC21=1 ISC20=1 ISC31=1 ISC30=1 Habe dazu nun folgende Fragen: 1. Ist es möglich, dass einfach meine Bit-Abfrage nicht stimmt? 2. Wie kann es passieren, dass bereits Werte im Register stehen? 3. Bin ich zu doof, dass Handbuch zu verstehen:-) 4. Gibt es Unterschiede (16AU,8AU,16MU etc.) zwischen verschiedenen 128igern, die so etwas verursachen könnten. Freue mich über jeden Post (auch Erziehungspost - bin µC.net Neuling) Vielen Dank! Grüße Chris
#define ISC11 3 #define ISC10 2 #define ISC01 1 Die sind immer gleich :-) Deine Abfragen müssten lauten: if(EICRA & ISC01)
Hi
>1. Ist es möglich, dass einfach meine Bit-Abfrage nicht stimmt?
Das ist keine Bitabfrage. ISC00...ISC30 entsprechen 0...7.
MfG Spess
Kleines Beispiel von einem mega128 Projekt: EICRB |= 0b11100000; // INT6 fallende, INT7 steigende Flanke EIMSK |= 0b11000000; // INT6+7 freischalten sei(); // Interrupts aktivieren
Hi
>Kleines Beispiel von einem mega128 Projekt:
Aber kein gutes.
MfG Spess
Erstmal !Danke! für die superschnellen Antworten! @Spess: kann dir nicht ganz folgen - "ISC00...ISC30 entsprechen 0...7"? Wie kann ich die Bits kontrollieren und an mein Terminal schicken, wenns so nicht geht? Steh wohl auf´m Schlauch :-) (Debuggen geht nicht) grüße
Hi >@Spess: kann dir nicht ganz folgen - "ISC00...ISC30 entsprechen 0...7"? aus der Header-Datei: /* External Interrupt Control Register A - EICRA */ #define ISC31 7 #define ISC30 6 #define ISC21 5 #define ISC20 4 #define ISC11 3 #define ISC10 2 #define ISC01 1 #define ISC00 0 >Wie kann ich denn die Bits abfragen und an an mein Terminal schicken? Fast so wie schon vorgeschlagen: >Deine Abfragen müssten lauten: >if(EICRA & ISC01) if(EICRA & (1<<ISC01)).... Hoffentlich richtig. Kann kein C. MfG Spess
Hab´s jetzt hinbekommen die Bits abzufragen /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ unsigned char regi=0; insigned int i=0, ii=0; //EICRA = EICRA | 0b10010011; for(i=1;i<129;i=i<<1,i++) { if(((EICRA & i)>>ii)==1) regi= regi|i; } usart_write("\n\rERG: 0x%x\n\r", regi); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ interessanterweise hab ich so festgestellt, dass das Register EICRA seinen letzten Wert immer behält!! - schreibe ich eine Zahl (im Beispiel 0x93) ins Register und schau es mir an steht diese Zahl auch drin. Kommentier ich das (wie oben im Code) aus und lass es dann wieder laufen steht immernoch 0x93 im Register. Durch die Bitmanipulation in meinem Fall "oder", die ich ausführe, kann ich diese Zahl dann irgendwann nicht mehr verändern, weil nur noch 1 drinstehen. Vielleicht ist es zu einfach folgendes zu sagen, sieht aber doch ganz danach aus: initial value: 00000000 <- Lüge! initial value: last setted value <- Wahrheit! Sollte es also irgendwo zu Problemen mit dem Reg kommen: immer hart null setzten und dann beschreiben! Grüße und vielen Dank für die Hilfe Chris
Servus! Inzwischen hat sich das gesamte Interruptproblem geklärt! Wie so oft, war es 3. zu doof das Datenblatt zu verstehen! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! http://www.mikrocontroller.net/articles/AVR_Checkliste#Besonderheiten_bei_ATmega128_und_seinen_Derivaten_im_64-Pin-Geh.C3.A4use !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! Der Atmega128 hat die Fuse M103C. Diese ist werksseitig gesetzt und macht aus dem 128iger einen 103er. Im "ATmega103 compability mode"(wie sich der Kruscht schimpft) kann man das Register EICRA nicht wirklich beschreiben - dass bedeutet, dass immer "0x00" drinsteht und der µC IMMER auf GND reagiert. blöd blöd... aber wiedermal was gelernt! Grüße!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.