Forum: Mikrocontroller und Digitale Elektronik Effektive PCINT ISR


von Marco U. (Gast)


Lesenswert?

Hallo zusammen!

Folgende Ausgangssituation:
Ich arbeite mit einem ATmega644 20PU, WinAVR und C.
An dem ATmega sind, über entsprechende Elektronik, mehrere Pulsgeber 
angeschlossen.
Diese senden dem ATmega jedes mal eine positive Flanke wenn ein 
Schrittmotor (Insgesamt drei an der Zahl) einen Schritt getan haben.

Ich möchte nun mittels PCINT die Anzahl der positiven Flanken (also die 
Schritte jedes Motors) zählen und eine Variable (enthält als INT Wert 
die Anzahl der Schritte die der Motor zurücklegen soll) dekrementieren.

Was ist der effektivste Weg um festzustellen welcher PIN eines Ports den 
Interrupt ausgelöst hat? Ich löse es momentan mit zwei IF-Abfragen, wäre 
ein Switch "besser"? Macht es Sinn den gesamten Inhalt des PinX 
Registers erst zwischen zu speichern und mit diesem dann zu arbeiten?

PS: Die Interrupt Behandlung in der ISR möchte ich, sofern möglich, 
nicht mittels cli(), sei() unterbrechen, da die drei Schrittmotoren 
gleichzeitig laufen und es sonst vorkommen kann das Schritte eines 
anderen Motors nicht gezählt werden.

Mein Bisheriger Code (für einen Schrittmotor):
1
/*
2
 Main code....
3
*/
4
      
5
DDRC &=~(1<<DDC3);  //Input Anschlagssensor PCINT19 -> PCINT2_vect
6
PORTC|= (1<<PORTC3);    //Pull UP -> Low Aktive  
7
DDRC &=~(1<<DDC2);  //Input Schrittzähler PCINT18 ->PCINT2     
8
PORTC|= (1<<PORTC2);  //Pull UP -> Low Aktive  
9
        
10
a_1s = para[1];    //Globale Variable für ISR setzen 
11
                        //(Soviele Schritte soll der Motor gehen)
12
13
PCMSK2 |= (1<<PCINT18)|(1<<PCINT19);  //Pins als Interrupteingang 
14
PCICR |= (1<<PCIE2);    //Interrupt Vektor PCINT2_vect aktivieren
15
16
/*
17
 weiterer Main code....
18
*/
1
//ISR Achse 1
2
3
ISR(PCINT2_vect){
4
5
//Not-Aus
6
if(!(PINC &(1<<PORTC3))){
7
a_1s = 0;  
8
}
9
10
if(!(PINC &(1<<PORTC2))){      
11
    if(a_1s <=0){
12
      //Motor Stoppen!
13
      PORTA &=~ (1<<PORTA1);  //Rechts stopp
14
      PORTA &=~ (1<<PORTA2);  //Links stopp
15
      OCR2B = 0;  //Geschwindigkeit stopp
16
      PCICR &=~ (1<<PCIE2);  
17
    }else{
18
      //Motor weiter laufen Lassen
19
                        //Anzahl der noch zurück zu legenden Schritte
20
                        //Verringern
21
      a_1s--;
22
    }
23
  }
24
25
}

Ich wäre euch für Tipps, Anregungen und (konstruktive) Kritik sehr 
dankbar. :)

Gruß
Marco

von Marco U. (Gast)


Lesenswert?

PUSH

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.