WCM Forum

WCM Forum (http://www.wcm.at/forum/index.php)
-   Home Cockpit - Das Forum für die "Bastler" (http://www.wcm.at/forum/forumdisplay.php?f=55)
-   -   AVR-Interrupts in C (http://www.wcm.at/forum/showthread.php?t=214427)

philharmony 21.04.2007 19:04

AVR-Interrupts in C
 
Habe mich mal wieder an die Elektronik gesetzt und Promt das nächste Problem:
AVR-Studio, ATmega8535
Ich möchte ein kleines Versuchsprogramm haben, dass alle 5000Takte den PortB um einen runterzählt und bei PIND2 per Interrupt PORTB auf 0x00 setzt.
Klappt natürlich nicht, ich denke ich habe die Geschichte mit den Interrupts noch nicht 100%ig verstanden, werde aus diversen Tutorials auch nicht wirklich schlau was jetzt genau wo hin muss.
Hier mal mein Text

-----------------------------------------
#include <AVR/io.h>
#include <avr/interrupt.h>


int main (void) {

int i;

DDRB=0xff;
PORTB=0xff;

GIFR=(1<<INTF0);
MCUCR =((1<<ISC01)|(1<<ISC00));
sei();

while(1) {


while(i<5000) i++;
PORTB--;
i=0;


SIGNAL (SIG_INT0)
{
PORTB=0;
}


}

return(0);
}
-----------------------------------------

Was mach ich falsch?

Bastian 21.04.2007 20:25

Versteh ich das richtig das du Port B bei einem externen Interrupt an Pin D2 auf 0 setzen willst?

Grüße
Bastian

AlTonno 21.04.2007 20:47

Wie ist denn der INT0 extern beschalten (Taster/Pullup?) bzw. wie sind den die Pegel an dem Pin so?

Die Interrupt-Routine würde ich übrigens aus dem main rausverfrachten, villeicht mag das dein compiler so nicht...


lg

philharmony 21.04.2007 21:23

Habe es bis jetzt nur im AVRstudio simuliert.
Das Prog soll von sich aus Runterzählen(an PortB) und ihn auf Interrupt von PIND2 auf 0 setzen.
Ich verstehe den Syntax der Interrupts noch nicht so ganz.
Vllt könnte jmd meinen Text exemplarisch mal so umstellen wie es funktionieren müsste...
LG

dirkan 22.04.2007 00:12

Hallo,

// Beispiel für einen Timer Interrupt:
int cnt = 0;

int main( void )
{
TIMSK |= BV(TOIE0); // Enable timer interrupt
sei(); // Enable global interrupt flag

for (;;); // Loop forever oder mache hier irgendwas
}

// Diese Funktion wird bei overrun timer counter aufgerufen
SIGNAL (SIG_OVERFLOW0)
{
PORTB = ++cnt;
}

Das geht mit allen anderen Interrupts ähnlich.
1. Das richtige enable bit setzen
2. Die SIGNAL oder INTERRUPT Fumktion schreiben SIG_ ist für
jeden Interupt unterschiedlich deklariert.

Beachten: bei vielen Ints muss das dazugehörende Register gelesen
werden (RTFM)

Bei verwendung von INTERRUPT anstatt SIGNAL können verschachtelte Interrupts auftreten. Fang mit SIGNAL an und langsam rantasten,
dann wird das schon gehen.

Viel Erfolg

Dirk

philharmony 22.04.2007 12:34

Hi Dirk,

Zitat:

Beachten: bei vielen Ints muss das dazugehörende Register gelesen werden
Genau da fängt mein Problem an, ich werd aus dem Manual da nicht schlau.
Welche Register muss ich wie und mit welcher Syntax setzen?

GIFR=(1<<INTF0) bedeutet doch, im Global Interrupt Flag Register den INTF0 auf 1 setzen oder?



EDIT:
mit

Zitat:

#include <AVR/io.h>
#include <avr/interrupt.h>

int main (void) {

int i;

DDRB=0xff;
PORTB=0xff;

GIFR=(1<<INTF0);
GICR=(1<<INT0);
MCUCR =((1<<ISC01)|(1<<ISC00));
sei();

while(1)
{

while(i<50) i++;
PORTB--;
i=0;

}
return(0);
}


SIGNAL (SIG_INT0)
{
PORTB=0x00;
}



Geht es, würde es aber Zufallstreffer nennen, habs noch nicht wirklich verstanden...

AlTonno 22.04.2007 12:59

// EDIT:

klar, das Bit ist wichtig - "External Interrupt Request 0 Enable"... ohne dem geht natürlich gar nichts ;)


lg
Chris

philharmony 22.04.2007 13:36

Oh man, diese Controller rauben mir noch den letzten Nerv, hab grad das Gefühl, je mehr ich darüber lese und damit mache, desto weniger verstehe ich letztendlich...

Ich habe jetzt noch einen 2.Externen Interrupt drin, und jedesmal wenn der aufgerufen wird, steigt der Prozess danach wieder ganz oben im MAIN ein.
Kann ich ihn auch irgendwie dazu bringen, in der Hauptschleife zu bleiben?

dirkan 22.04.2007 13:47

Hallo,

soweit bist du garnicht weg vom Ziel. Gestatte mir noch folgende Korrekturen:

1. PORTB--; geht nicht, weil ein decrement aus lesen und schreiben
besteht. Lesen eines Portes muss immer mit PINB erfolgen.
Also:
PORTB = PINB-1;

2. Wie willst du den Erfolg deiner Programmierung kontrollieren ?
Baue ein,zwei LED ein und setze sie bei einem Event. Damit debugged es sich leichter.

Last not least: ich kann an deinem Programm keinen Sinn erkennen.
Ist das nur eine Übung, oder übersehe ich was ?

Gruss Dirk

philharmony 22.04.2007 13:56

Das is erstmal eine Übung.
Ich kann den Erfolg auf dem STK500 sehen, wo der gesamte Portb an den 8 LEDs hängt und einfach binär durchzählt.
Das Program soll wenns fertig ist, über INT1 eine "run-Variable" schalten, wenn die an ist soll er zählen und sich per INT0 resetten lassen.
PORTB-- funktioniert übrigens (Durch das DDRB hab ich ja festgelegt, dass PORTB immer den Wert von PINB annimmt), das is nich das Problem, nur diese Interrupt-Steuerung raff ich nicht, also wann und wo genau ich jetzt was wie setzen/lesen muss damits läuft...


Alle Zeitangaben in WEZ +2. Es ist jetzt 06:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag