Forum: Mikrocontroller und Digitale Elektronik Interrupt ATMEGA8


von Ronald E. (ronald_1)


Lesenswert?

Hallo zusammen,

ich versuche über PortD Pin 2 und 3 ein externes Interrupt 
herbeizufüheren (4,7KOhm Pull-Down). Leider hab ich noch nie was mit 
Interrupts gemacht, und kriegs auch irgentwie nicht hin. Mein Versuch:
1
//External Interrupt Request 0
2
#define INT0_vect                       _VECTOR(1)
3
#define SIG_INTERRUPT0                  _VECTOR(1)
4
5
ISR(INT0_vect)       // veraltet: SIGNAL(SIG_INTERRUPT0) 
6
{
7
   //Ausgabe "Test an LCD"
8
}

Ist dies die richtige Vorgehensweise? Ich bitte um Hilfe.

MfG Ronald

von Karl H. (kbuchegg)


Lesenswert?

Ronald E. schrieb:

>
1
> //External Interrupt Request 0
2
> #define INT0_vect                       _VECTOR(1)
3
> #define SIG_INTERRUPT0                  _VECTOR(1)
4
> 
5
> ISR(INT0_vect)       // veraltet: SIGNAL(SIG_INTERRUPT0)
6
> {
7
>    //Ausgabe "Test an LCD"
8
> }
9
>
>
> Ist dies die richtige Vorgehensweise? Ich bitte um Hilfe.

Nein.
Du definierst die Vektoren nicht selbst, sondern überlässt das dem
1
#include <avr/io.h>
2
#include <avr/interrupt.h>

diese #include machen dann schon die richtigen #define für deinen 
Prozessor, so dass du
1
ISR(INT0_vect)
2
{
3
  // mach was
4
}

machen kannst.
Eine Ausgabe auf ein LCD sollte allerdings ausser für schnelle 
testzwecke tabu sein. Das dauert einfach zu lange und steht der 
Forderung, dass eine ISR möglichst schnell abgearbeitet werden soll im 
Wege.

von Ronald E. (ronald_1)


Lesenswert?

Ach so, danke!
Die Ausgabe am LCD ist tatsächlich nur zum Testen, obs funktioniert.
Leider funktionierts nicht.
1
ISR(INT0_vect)       // SIGNAL(SIG_INTERRUPT0) 
2
{
3
        lcd_clear();
4
    lcd_setcursor(0,1);
5
    lcd_string("Test");
6
  _delay_ms(5000);
7
}

Die Interrupts habe ich global aktiviert (mit sei(); ). Das Display 
funktioniert (habs getestet). Mach ich nochwas falsch?

MfG Ronald

von Karl H. (kbuchegg)


Lesenswert?

Die Pins sind auf Eingang gestellt?

Zeig doch der Einfachheit alles her, dann braucht man nicht raten

von Ronald E. (ronald_1)


Angehängte Dateien:

Lesenswert?

Anbei der Code. Gleichzeitig muss ich anmerken, dass ich noch nicht so 
erfahren bin. Das Display hängt an Port B, der Temperaturfühler an Port 
C. Port D ist also frei (bis auf den externen Interrupt).

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Also ohne in deinen angehängten Quelltext geschaut zu haben, ist delay 
in einer ISR eigentlich immer Schrott und einer von 5000 mit Sicherheit.

von Karl H. (kbuchegg)


Lesenswert?

1
void main(void)
2
{
3
4
  lcd_init();
5
  int8_t puffer[7];
6
7
  //Interrupts global aktivieren
8
  sei();
9
10
  DDRD = 0x0;  
11
  
12
  while (1)

Ähm.
Und wo erlaubst du den externen Interrupt 0?

Im Mega8 gibt es viele Interrupts. Behandelt werden aber nur die, die 
explizit freigegeben werden!

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Nachdem ich deinen Quelltext gesehen habe, ist mir aufgefallen das du 
den INT0 garnicht aktiviert hast; also sind GICR und MCUCR deine 
Freunde.

Und im übrigen ist der Rückgabewert von main ein int...

von ronald_1 (Gast)


Lesenswert?

Ahh da hab ich mal was gelesen.
Das probier ich gleich mal aus.

von Ronald E. (ronald_1)


Angehängte Dateien:

Lesenswert?

Also, erstmal danke für die Hilfe! Ich habs geschafft mittels Interrupt 
etwas am Display auszugeben. Nun versuche ich zu einer Zahl 
(Temperatur_Soll) mittels Interrupt 0.5 zu addieren. Leider bekomme ich 
einige Errors. Stimmt es, dass ich mit volatile eine Variabel global 
deffinieren kann?

von Verwirrter Anfänger (Gast)


Lesenswert?

Wie willst du den auf einen Int 0.5 addieren? Ints sind immer nur 
Ganzzahlen.

Du bräuchtest also eigentlich float oder double. Allerdings würde ich 
dir zu Festkommaarithmetik raten.

Ciao,
VA

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Nein, volatile sorgt nur dafür das der Compiler an der Variablen nichts 
rumoptimiert.

Du definierst eine globale Variable indem du sie ausserhalb einer 
Funktion definierst, wie du es auch fast richtig gemacht hast, nur die 
10 dahinter ist Murks. Wenn du ihr einen Startwert geben wolltest, muss 
noch ein = dazwischen.

Temperatur_Soll = Temperatur_Soll + 0.5 funktioniert nicht, da 0.5 keine 
Ganze Zahl ist, Temperatur_Soll jedoch schon.

Und statt:
1
//Interrupt wird ausgelöst bei fallender oder steigender Flanke (INT0,INT1)  
2
GIMSK = (1 << DDB6) | (1 << DDB7);
3
4
//Interrupts INT0, INT1 reagieren auf steigende Flanken
5
MCUCR = (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3);

schreibst du besser:
1
//(INT0,INT1) Interrupt kann ausgelöst werden
2
GIMSK |= (1 << INT1) | (1 << INT0);
3
4
//Interrupts INT0, INT1 reagieren auf steigende Flanken
5
MCUCR |= (1 << ISC11) | (1 << ISC10) | (1 << ISC01) | (1 << ISC00);

Ist übersichtlicher und ändert nur was du auch ändern willst.

von Ronald E. (ronald_1)


Angehängte Dateien:

Lesenswert?

Vielen Dank nochmals für die guten Hinweise (hab gleich alles geändert).
Das mit der Kommastelle hab ich glaub ich jetzt gut gelöst. Probleme 
habe ich aber noch mit dem sprintf, da bekomme ich noch errors.

../avr_lcd.c:81: error: 'buf' undeclared (first use in this function)
../avr_lcd.c:81: error: 'Temperatur_Soll' undeclared (first use in this 
function)
../avr_lcd.c:81: error: 'Komma' undeclared (first use in this function)

Irgentwie scheint die Defintion nicht zu stimmen.

von abc (Gast)


Lesenswert?

>Irgentwie scheint die Defintion nicht zu stimmen.
Das kann man so sagen:
1
#define uint8_t Temperatur_Soll = 10
2
#define uint8_t Komma = 0
3
#define uint8_t Speicher = 0
GRÖHL! So definiert man doch keine Variablen! Nimm die #define da weg!

Das Problem mit 'buf' sehe ich gerade nicht.

von abc (Gast)


Lesenswert?

>Das Problem mit 'buf' sehe ich gerade nicht.

OK, gefunden: Der Präprozessor schießt dank deiner phantasievollen 
Deklarationen das uint8_t da weg und packt irgendwelchen Krempel an 
dessen Stelle. --> Problem.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

1
#define uint8_t Temperatur_Soll = 10
2
#define uint8_t Komma = 0
3
#define uint8_t Speicher = 0

Das #define ist jedesmal zuviel.

Und häng mal die avr_lcd.c an, sonst ist das mit dem buf nicht klar.

von abc (Gast)


Lesenswert?

>Deklarationen
Grrr, ich meinte Definitionen.

von Ronald E. (ronald_1)


Lesenswert?

Ohne die define`s sind die errors weg, und es funktioniert. Nur leider 
etwas zu schnell, da muss ich mir noch was einfallen lassen. Danke für 
eure Hilfe.

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
Noch kein Account? Hier anmelden.