Forum: Mikrocontroller und Digitale Elektronik Problem mit Interrupt Flankeneinstellung ATmega2560


von Andreas K. (totem)


Lesenswert?

Hallo Forum,

nachdem ich vor ein paar Tagen als Neueinsteiger hier so gut unterstützt 
worden bin, wollte ich Euch ein weiteres (für Euch triviales) Problem 
schildern.
Ich verwende ein STK600 mit ATmega2560 und AVR Studio5.
In meinem Projekt soll später eine Drehzahlbestimmung eines rotierenden 
Teils durch "Durchbrechen" einer Lichtschranke durchgeführt werden (Also 
Durchbrüche pro Zeiteinheit). Dafür möchte ich 2 Interruptroutinen 
laufen lassen.
Als Newbie funktioniert immerhin das Interrupt schon, jedoch scheitere 
ich derzeit an der Justierung der Flankenauslösung. Derzeit wird die 
Lichtschranke noch durch einen Taster am Board ersetzt.
Sowohl beim Drücken des Tasters als auch beim Loslassen wird der 
Interrupt ausgelöst, zu sehen an den LED. Zwar ist weder SW- noch 
HW-seitig entprellt, aber das sollte doch nicht der Auslöser sein, oder? 
Ich denke, dass an meinen EICRA-Befehlen was nicht stimmt.

Kann mir jemand helfen?

Hier mein Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
5
#ifndef F_CPU
6
  F_CPU = 16000000UL;
7
#endif
8
9
uint8_t intPortB;
10
uint16_t intCounter;
11
volatile double intTimer;
12
13
ISR(PCINT0_vect)
14
{
15
    intCounter++;
16
    PORTC = intCounter;
17
  
18
    //_delay_ms(3000);
19
}  
20
21
int main(void)
22
{
23
    intTimer = 5;
24
25
    DDRC = (1<<DDC0) | (1<<DDC1) | (1<<DDC2) | (1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6) | (1<<DDC7);
26
    DDRB &= ~(1<<DDB0) | (1<<DDB1) | (1<<DDB2) | (1<<DDB3) | (1<<DDB4) | (1<<DDB5) | (1<<DDB6) | (1<<DDB7);
27
    PORTC = 0b11111100; //Initialisierung: Alles auf High --> LED aus
28
    DDRD = 0x00;
29
  
30
  
31
   PCICR |= (1 << PCIE0);  //Enable Pin Change Interrupt Pin (0 = PinD0)
32
   PCMSK0 |= (1 << PCINT0);//Enable Pin Change Interrupt handling
33
   EICRA |= (1 << ISC01);  //Definiere Art der Flankenbehandlung für Pin Change Interrupt
34
   EICRA |= (1 << ISC00);  //Definiere Art der Flankenbehandlung für Pin Change Interrupt
35
  
36
    while(1)
37
    {
38
    
39
  sei();
40
    
41
    }
42
}

By the way: Weiß jemand on the fly, warum die delay-Befehle so 
hundsmiserabel arbeiten? Eingestellt 1000ms --> 1200 ms; 10000 ms --> 
4500 ms. Das stimmt doch hinten und vorne nicht...

von spess53 (Gast)


Lesenswert?

Hi

Du bringst Pinchange-Interrupts und Externe Interrupts durcheinander.

>EICRA |= (1 << ISC01);
>EICRA |= (1 << ISC00);

EICRA hat nichts mit den Pinchange-Interrupts zu tun. PC-Interrupts 
reagieren generell auf jede Flanke. Die auslösende Flanke must du selbst 
ermitteln.

MfG Spess

von Peter D. (peda)


Lesenswert?

Andreas König schrieb:
> Sowohl beim Drücken des Tasters als auch beim Loslassen wird der
> Interrupt ausgelöst, zu sehen an den LED.

Ist doch schön, wenn die Software genau das macht, was man programmiert 
hat.

http://de.wikipedia.org/wiki/Prellen


Peter

von Andreas K. (totem)


Lesenswert?

@Spess: Danke für den Hinweis! Das hatte ich glatt übersehen...

@Peter: Danke auch Dir ;)

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.