PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : GICR Problem



ChRiZ
05.07.2006, 18:07
Hallo Zusammen!

Ich will einen ADXL Beschleunigungssensor auslesen.
Damit die steigenden Flanken des PWM Signals vom ADXL sauber in mein Programm kommen, will ich eine ISR schreiben.

Der Compiler WINAVR (gcc, 3.4.6) mit AVR Studio 4 will den Befehl "GICR" aber nicht kennen, es kommt immer die Fehlermeldung:
../ADSXLR2.c:40: error: `GICR' undeclared (first use in this function)

Könnt Ihr mir weiterhelfen?

Vielen vielen Dank!!


#include <avr/signal.h>
#include <avr/interrupt.h>

#include <stdio.h>
#include <avr/io.h>

//#define SIG_INTERRUPT0 _VECTOR(1)


SIGNAL(SIG_INTERRUPT0) // signal handler for external interrupt
{
PORTD|=(1<<PD0);

return;
}


int main (void){

DDRD = 0b00000011; //PD0 1 Eingang, Rest Ausgang
PORTD = 0b00001100;
DDRC = 0b00110000;

GICR = (1 << INT0) | (1 << INT1);
MCUCR = 0x03; // INT0 reagiert auf steigende Flanke


sei(); // enable interrupts
for(;;){} // loop "forewer", wait for signal
return 0;
}

uwegw
05.07.2006, 18:14
Welcher AVR-Typ?
Probier mal GIMSK aus. Das ist das enttsprechende Register bei älteren AVRs.
Bei Winavr 3.4.5 ist in den Includefiles beim Mega32 folgendes definiert:
#define GIMSK _SFR_IO8(0x3B)
#define GICR GIMSK

Der neue Name wird also einfach auf den alten umgebogen, der dann auf die richtige Adresse des Register verweist.

ChRiZ
05.07.2006, 18:49
Juhhu ;)
Vielen Dank!

mit GIMSK funktionierts ;)
PS: ich verwende einen Atmega8

ChRiZ
05.07.2006, 19:36
Ich wahr etwas voreilig.. ;)
Der compiler meldet keine Fehler mehr, doch wird die ISR nicht aufgerufen :(

noch eine Idee?

ich habe leider kein KO, und kann das PWM Signal nicht überprüfen...


#include <avr/signal.h>
#include <avr/interrupt.h>

#include <stdio.h>
#include <avr/io.h>

#define GIMSK _SFR_IO8(0x3B)
#define GICR GIMSK

int PulsL;


SIGNAL(SIG_INTERRUPT1) // signal handler for external interrupt
{
PORTC|=(1<<PC5); //LED anschalten
}

int main (void){

// DDRD = 0b11110011; //PD2,3 Eingang, Rest Ausgang

DDRC = 0xff;
DDRD &= ~(1<<PD2);
PORTD |= (1<<PD2);

// PORTD = 0b00001100;
MCUCR |= (1<<ISC01) | (1<<ISC00); // INT0 reagiert auf steigende Flanke

//GICR = (1 << INT0) | (1 << INT1);
GICR |= (1<<INT1); // Enable external Interrupt 1

sei(); // enable interrupts

for(;;){} // loop "forewer", wait for signal
}

uwegw
05.07.2006, 20:26
Du konfigurierst INT0, willst aber ein Signal auf INT1 auswerten???

ChRiZ
05.07.2006, 20:30
meinst du wegen dieser Zeile:
MCUCR |= (1<<ISC01) | (1<<ISC00); // INT0 reagiert auf steigende Flanke

wie kann ich die auf INT1 umschreiben?

uwegw
05.07.2006, 20:45
Ins Datenblatt gucken und lesen, dass es statt ISC00 und ISC01 dann ISC10 und ISC11 sind...

ChRiZ
05.07.2006, 20:56
Vielen Dank für die Korrektur!
Leider funktioniert die ISR aber noch imme rnicht... ;(

Wenn ich den PIN PD3 Direkt abfrage, leuchtet die LED, der Interrupt müsste allso min. 1X ausgelöst werden... (ganz am schluss)

Habt ihr noch weitere Ideen?



#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/io.h>

#define GIMSK _SFR_IO8(0x3B)
#define GICR GIMSK

SIGNAL(SIG_INTERRUPT1) // signal handler for external interrupt
{
PORTC|=(1<<PC5); //LED anschalten
}

int main (void){

DDRC = 0xff;

DDRD &= ~(1<<PD3);
PORTD |= (1<<PD3);

MCUCR |= (1<<ISC10) | (1<<ISC11); // INT0 reagiert auf steigende Flanke

GICR |= (1<<INT1); // Enable external Interrupt 1

sei(); // enable interrupts

for(;;){
//if ((PIND & (1<<PD3)) > 0) PORTC|=(1<<PC5); //LED anschalten
} // loop "forewer", wait for signal
}

uwegw
05.07.2006, 21:12
Mit
PORTD |= (1<<PD3);
schaltest du den internen Pullup auf dem Interrupteingang ein. Wenn der Sensor den Pin nicht im Ruhezustand auf Masse zieht, ist der Pin damit immer high, und es tritt keinerlei Flanke auf, die erkannt werden könnte.

ChRiZ
05.07.2006, 21:21
hatte ich auch schon Probiert
DDRD &= ~(1<<PD3);
PORTD =0;

funktioniert leider auch nicht :(
vielen Dank trozdem ;)

ChRiZ
05.07.2006, 22:23
hat keiner mehr eine Idee?
wäre um hilfe sehr erfreut ;)

SprinterSB
06.07.2006, 09:27
IMHO verwendest du die falschen Makros (wie etwa INT1)


// INT0 on raising edge
// clear pending INT0
// enable INT0 interrupt
MCUCR |= (1 << ISC01) | (1 << ISC00);
GIFR = (1 << INTF0);
GICR |= (1 << INT0);

Das Flag zurücksetzen brauchst du wohl nicht.
Wenn GICR nicht gefunden wird, dann stimmt was mit deiner Umgebung nicht. Es muss auch gehen, wenn du es nicht selber definierst!

Bist du sicher, daß du alles richtig konfiguriert hast?

Gibt mal auf Konsole in deinem Verzeichnis ein.


avr-gcc -mmcu=atmega8 -E -dM datei.c | grep GICR

ChRiZ
06.07.2006, 17:16
in der Konsole erscheint:
C:\ATMEGA8\ADXL\ADSXLR2>avr-gcc -mmcu=atmega8 -E -dM adsxlr2.c | grep GICR
#define GICR _SFR_IO8(0x3B)

wenn ich den Befehl GIFR Benutze kommt beim compilieren:
../ADSXLR2.c:36: error: `GIFR' undeclared (first use in this function)

gibt es ein tutorial wie ich meine AVR Studio einrichten sollte?

SprinterSB
06.07.2006, 17:20
mit ...|grep GIFR muss ne Entsprechende Ausgabe kommen! falls nicht hast du vielleicht nen anderen Controller eingestellt?

ChRiZ
07.07.2006, 00:46
mit grep GIFER kam #define GIFR _SFR_IO8(0x3A)
das ich auch meinem Programm beigefügt habe.

Leider Funktionierts aber noch immer nicht..
Ich hab jetzt PD2 mit einem Wiederstand auf Masse gezogen.
Wenn ich jetzt mit +5Volt auf PD2 gehe, leuchtet die LED PC3 und schaltet auch wieder ab, sobald die 5V weg sind.

PD3 (INT1) ist unbeschaltet.

Die LED PC2 die vom Interrupt aktiviert werden sollte, bleibt leider immer noch dunkel wenn ich mit 5v an die pd2 oder pd3 gehe :(

hier der Aktuelle Code:

#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/io.h>
#include <avr/delay.h> /* definiert _delay_ms() ab avr-libc Version 1.2.0 */

#define GIMSK _SFR_IO8(0x3B)
#define GICR GIMSK
#define GIFR _SFR_IO8(0x3A)


SIGNAL(SIG_INTERRUPT0) // signal handler for external interrupt
{
PORTC|=(1<<PC2); //LED2 anschalte
}

SIGNAL(SIG_INTERRUPT1) // signal handler for external interrupt
{
PORTC|=(1<<PC2); //LED2 anschalte
}


int main (void){

DDRC = 0xff; //alles als Ausgang def.
PORTC =0x00; //PullUP's aus

DDRD =0x00; //alles EIngang
PORTD =0x00; //PullUp's aus

//LED's ausschalten
PORTC&=(!(1<<PC3)); PORTC&=(!(1<<PC2)); PORTC&=(!(1<<PC1)); PORTC&=(!(1<<PC0));


// INT0 on raising edge
// clear pending INT0
// enable INT0 interrupt
MCUCR |= (1 << ISC01) | (1 << ISC00) | (1 << ISC10)| (1 << ISC11);
GIFR = (1 << INTF0);
GICR |= (1 << INT0);

sei();


while(1){

if (PIND & (1<<PD2) ){
PORTC|=(1<<PC3); //LED3 anschalte
}
else{
PORTC&=(~(1<<PC3));
}
}
}


Vielen Dank für eure Antworten!

SprinterSB
07.07.2006, 09:46
-- wird diese Defines GIMSK, GICR und GIFR raus! Nochmal: Entweder sie werden gefunden, oder etwas stimmt nicht. Falls etwas nicht stimmt behebst du das nicht dadurch daß du die Defines nachhackst! Das verdeckt nur einen Fehler und verschiebt in an eine viel schwerer zu findende Stelle!
-- es muss heissen PORTC &= ~(1<<PC3) etc

Du willst die LED mit INT0 einschalten und mit INT1 wieder aus?

ChRiZ
07.07.2006, 11:39
vielen Dank für deine Antwort!
Ich will Die LED mit int0 und int1 anschalten, funktioniert aber beides nicht...

Was kann ich denn am gcc compiler ändern dass ich die defines weglassen kann?

ChRiZ
07.07.2006, 15:49
Juhhu es Funktioniert!!!
Ich habe blos das AVR Studio neu installiert und das neue Update reingeladen!!

Vielen Dank nochmals an alle die mir geholfen haben!