[ATmega32] Drehgeber Drehrichtung

OP #4471186
Lesenswert?

Hey,

ich will mit einem Drehgeber, der zwei phasenverschobene Rechecksignale 
ausgibt die Drehrichtung erkennen.
Ich habe leider nur einen externen Interrupt zur Verfügung und würde 
mich mit einer "Sparmaßnahme" zurfrieden geben und immer nur wie in 
diesem tut Drehgeber unter 4.1 bei einer steigenden Flanke von A den 
Pin von Phase B auslesen und somit die Drehrichtung rausfinden.
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <stdio.h>
4
#include <avr/interrupt.h>
5

6
volatile unsigned long counter256 = 0;
7
ISR( TIMER0_OVF_vect ){       // Overflow Interrupt Vector Timer0
8
    counter256++;
9
}
10

11
volatile uint8_t flagUmdrehung3 = 0;
12
volatile unsigned int counterUmdrehung3 = 0;
13
volatile int flagRichtung = 0;
14
ISR(INT1_vect){
15
    //Externer Interrupt 2
16
    counterUmdrehung3++; //Eine Umdrehung wurde registriert
17
    flagUmdrehung3 = 1;
18
    counterAtExtIsr = counter256;
19
    counter256 = 0;
20
    //Phase B überprüfen
21
    if ( PINA & (1<<PINA7) ) {
22
       flagRichtung = 1;
23
    } else {
24
        flagRichtung = 0;  
25
    }
26
}
27

28
int main(void){
29
    TCCR1B |= (1<<CS12);
30
    TCCR1A |= (1<<WGM10);
31
    TCCR1B |= (1<<WGM12);
32
    TCCR1A |= (1<<COM1A1) | (1<<COM1B1);
33
    DDRD |= (1<<PD4) | (1<< PD5);
34
    DDRD &= ~(1<<3); //PD3 als Eingang
35
    PORTD|= (1<<3); //Pullup aktivieren
36
    GICR|=(1<<INT1); //INT1 enable im General Interupt Control Register
37
    MCUCR|=(1<<ISC11)|(1<<ISC10); //Steigende Flanke löst aus INT1
38
    //MOTOR = 255;
39
    TIMSK |= (1<<TOIE0);
40
    TCCR0 = (1<<CS00);
41
    int myCounter = 0;
42
    int flagMyRichtung = 0;
43
    DDRA  &= ~(1<<PA7);  // Pin PA7 als Eingang hier liegt Phase B an
44
    PORTA |= (1<<PA7);  //Pullup aktivieren
45
    sei();
46
    while(1){
47
        if (flagUmdrehung3 == 1){
48
             flagUmdrehung3 = 0;
49
             cli();
50
             myCounter = counterAtExtIsr;
51
             flagMyRichtung = flagRichtung;
52
             sei();
53
             printf("%d\n",flagMyRichtung);
54
         }
55
    }
56
}

flagMyRichtung soll also je nach Drehrichtung entweder 1 oder 0 
ausgeben. Blöderweise gibt mein µc immer 1 aus für flagMyRichtung. Ist 
meine Abfrage nach Phase B falsch? So dass nie der else Teil eintreffen 
kann?
OP #4471580
Lesenswert?

Wolfgang schrieb:
> Vergiss das mit dem Interrupt und lies deine beiden Signale einfach in
> einem fest Zeittakt ein.
>
> Das Thema wurde hier schon oft genug diskutiert.

Okay, werde ich so machen. Nachdem ich das tut zum x-ten mal gelesen 
habe ist das glaube ich auch nicht mehr unmöglich für mich. Könnt ihr 
mir noch bestätigen, dass:
1
    if ( PINA & (1<<PINA7) ) {
2
       flagRichtung = 1;
3
    } else {
4
        flagRichtung = 0;  
5
    }

auf jeden Fall korrekt ausliest ob PA7 high oder low ist? Sollte meiner 
Meinung nach richtig sein.
Mit einem Multimeter konnte ich übrigens feststellen, dass sich die 
Spannung an einem Ausgang von meinem Sensor nicht verändert hat sondern 
konst auf ~5V bleibt, an dem anderen Ausgang funktionierte alles. Mit 
dem µc konnte ich auch keine Flankenwechsel über Interrupts feststellen 
an dem Ausgang, also gehe ich davon aus, dass mein Sensor defekt ist.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren