PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : schwankende Flanken erkennen



mitch2055
11.01.2006, 18:45
Hallo,

ich möchte gerne auf eine Flankenänderung an einem
PIN reagieren. Ich möchte allerdings ungerne im
Hauptprogramm immerhin wieder den Status des PINs
abfragen. Ich habe gelesen, dass sich das auch mit
Interrupts realisieren lässt?
Ich verwende einen ATmega8 und programmiere mit AVR Studio.

mein bisheriger Code ist folgender:



#include <avr/io.h>
#include <stdint.h>
#include <avr/delay.h>


int main(void)
{

DDRC = 0xff;

for(;;)
{
PORTC = 0x01;
_delay_ms(3000);
PORTC = 0x02;
_delay_ms(3000);
PORTC = 0x04;
_delay_ms(3000);
PORTC = 0x08;
_delay_ms(3000);
PORTC = 0x10;
_delay_ms(3000);
PORTC = 0x20;
_delay_ms(3000);
}
}


jetzt will ich währenddessen noch gerne auf ein eingehendes Signal reagieren können... Hilfe.. :)

Gruß
M.Voigt

uwegw
11.01.2006, 19:16
Du kannst zwar mit nem externen Signal ein Interrupt auslösen, aber nur an zwei dafür vorgesehenen Pins des Mega8. (D2 und D3)

Tutorial:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts

mitch2055
11.01.2006, 19:54
danke schonmal, aber kannst du mir auch sagen, wie ich das code-technisch umsetze?:



SIGNAL (INT0)
{
i=0;
}


SIGNAL (INT1)
{
i=1;
}


funktioniert schonmal nicht..

../testcode.c:9: error: parse error before numeric constant

mitch2055
11.01.2006, 20:18
ich habe 5V Spannung direkt an den Eingang gelegt,
ohne Wiederstand. Ist das schlimm? Dafür ist doch der interne
Widerstand gedacht oder nicht? Weil ich momentan gar kein Signal
eingelesen bekomme, nichtmal per PIND...

uwegw
11.01.2006, 21:21
5V ist kein Probelm, solange der Pin dabei nicht als Ausgang konfiguriert ist und auf low gesetzt wurde... mit dem internen Widerstand meist du wahrscheinlich den Pull-up. Der hat keinerlei Schutzfunktion, sondern er kann den Pin auf ein definiertes Potential bringen, wenn an Eingang nichts angeschlossen ist. wenn dein Signal zb von einer Taste Kommt, die den Pin beim Drücken auf Masse zieht, und ungedrückt "hängt der Pin in der Luft", solltest du ihn aktivieren.

zum code: du musst natürlich den richtigen Namen für den Interrupt verwenden. SIG_INTERRUPT0 statt INT0.
(siehe zweite Tabelle im Abschnitt SIGNAL des Tutorials)

Außerdem müssten noch die richtigen Einstellungen in GIMSK und MCUCR erfolgen, damit die Interrupts auch aktiv sind...


PS: schau mal bei http://jump.to/fleury rein, Unter "AVR Software" findest du eine Sammlung von kleinen Beispielprogrammen, auch was für externe Interrupts...

Wie lange programmierst du eigentlich schon in AVR-GCC?

mitch2055
11.01.2006, 21:37
hallo, erstmal vielen Dank für die Antwort.

Ich habe die Einstellungen vorgenommen, aber
es ändert sich nichts..

Wie gesagt: 5V Spannung liegen mit Schalter direkt an den Eingängen.
Bei folgendem Code


#include <avr/io.h>
#include <stdint.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

volatile uint8_t i=0;
uint8_t bPortD;

SIGNAL(SIG_INTERRUPT0)
{
i=1;
}

SIGNAL(SIG_INTERRUPT1)
{
i=1;
}

int main(void)
{
DDRD = 0x00;
DDRC = 0xff;

sei();

GIMSK = 0xC0;
MCUCR = 0xC;

for(;;)
{
if(i==0)
{
PORTC = 0x01;
_delay_ms(3000);
PORTC = 0x02;
_delay_ms(3000);
PORTC = 0x04;
_delay_ms(3000);
PORTC = 0x08;
_delay_ms(3000);
PORTC = 0x10;
_delay_ms(3000);
PORTC = 0x20;
_delay_ms(3000);
PORTC = 0x10;
_delay_ms(3000);
PORTC = 0x08;
_delay_ms(3000);
PORTC = 0x04;
_delay_ms(3000);
PORTC = 0x02;
_delay_ms(3000);

i=0;

}
}
cli();
}


kannst du mir vielleicht nochmal helfen?..

danke schonmal

uwegw
11.01.2006, 21:50
Wenn du mit den Tastern 5V draufgibst, müsstst du externe Pull-downs anschließen, damit der Eingang sicher auf low liegt, wenn der Taster nicht gedrückt ist. Ansonsten kann es dir passieren, dass der AVR den Pin njcit als low erkennt, daher gibts auch kein Flanke zu erkennen...
Also entweder je eine Widerstand vom Pin nach Masse, oder nach MAsse schalten und Pullups an...

mit deinem MCUCR = 0xC; stellst du nur INT1 ein (auf Auslösung bei Wechsel low->high).
Etwas übersichtlicher wird das ganze, wenn du
GIMSK |= ((1<<INT0) | (1<<INT1));
MCUCR |= ((1<<ISC01) | (1<<ISC11));
vrwendest (ist die Einstellung für beide INTs, allerdings für Auslösung auf high->low)
Pullups gibts mit
PORTD |= ((1<<PD2) | (1<<PD3));

(Bei mir funktioniert diese Einstellung einwandfrei... obwohl ich erst seit wenigen Tagen in C programmiere)