Forum: Mikrocontroller und Digitale Elektronik MSP430G2553 Drehgeber auswerten


von Mathias Z. (matziz198)


Lesenswert?

Hallo,

ich möchte mit dem genannten µC einen Drehgeber auswerten. Ich habe den 
Code hier aus dem Forum Titel 
http://www.mikrocontroller.net/articles/Drehgeber#Beispielcode_in_C 
verwendet und, soweit mir möglich, angepasst.

Ergebniss: geht noch nicht.

Zum programmieren wird das LaunchPad und IAR Kickstart verwendet.
Könnt ihr bitte über den Code schauen was ich falsch mache?
1
#include "io430.h"
2
#include "intrinsics.h"
3
 
4
/* ------------------------------------------------------------------------------------------------
5
 *                                               Types
6
 * ------------------------------------------------------------------------------------------------
7
*/
8
9
typedef signed   int    int8;
10
typedef unsigned int    uint8;
11
12
typedef signed   short  int16;
13
typedef unsigned short  uint16;
14
15
typedef signed   long   int32;
16
typedef unsigned long   uint32;
17
18
//----------------------------------------------------------------------------------------------
19
20
#define PHASE_A   P1IN_4          // P1.4 als Eingang Encoder A
21
#define PHASE_B   P1IN_5          // P1.5 als Eingang Encoder B
22
23
#define LEDS      P1OUT           // Ausgänge des Ports ansteuern (LEDs against VCC)
24
 
25
 
26
volatile int8 enc_delta;          // -128 ... 127
27
static int8 last;
28
29
 
30
void encode_init( void )
31
{
32
  int8 new;
33
 
34
  new = 0;
35
  if( PHASE_A )
36
    new = 3;
37
  if( PHASE_B )
38
    new ^= 1;                   // convert gray to binary
39
  last = new;                   // power on state
40
  enc_delta = 0;
41
}
42
43
  
44
#pragma vector=TIMER0_A0_VECTOR             // 1ms for manual movement
45
__interrupt void Timer_A (void)
46
{
47
  int8 new, diff;
48
 
49
  new = 0;
50
  if( PHASE_A )
51
    new = 3;
52
  if( PHASE_B )
53
    new ^= 1;                           // convert gray to binary
54
  diff = last - new;                    // difference last - new
55
  if( diff & 1 ){                       // bit 0 = value (1)
56
    last = new;                         // store new as next last
57
    enc_delta += (diff & 2) - 1;        // bit 1 = direction (+/-)
58
  }
59
  CCR0 += 64536;                        // Add Offset to CCR0
60
}
61
 
62
 
63
int8 encode_read1( void )         // read single step encoders
64
{
65
  int8 val;
66
 
67
  __disable_interrupt();
68
  val = enc_delta;
69
  enc_delta = 0;
70
  __enable_interrupt();
71
  return val;                   // counts since last call
72
}
73
74
 
75
int main( void )
76
{
77
  WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer to prevent time out reset
78
    
79
  BCSCTL1 = CALBC1_1MHZ;                  // 1 MHz clock
80
  DCOCTL = CALDCO_1MHZ;
81
  
82
  CCTL0 = CCIE;                           // CCR0 interrupt enabled
83
  CCR0 = 64536;
84
  TACTL = TASSEL_2 + MC_2;                // SMCLK, contmode
85
  
86
  P1SEL = 0x00;                           // Port 1 als GPIO nutzen
87
  P1REN |= (BIT4 + BIT5);                 // P1.4 und P1.5 Pullups aktivieren
88
  P1DIR |= (BIT0 + BIT6);                 // P1.0 und P1.6 LEDs
89
    
90
91
  int32 val = 0;
92
 
93
  encode_init();
94
  __enable_interrupt();
95
 
96
  for(;;){
97
    val += encode_read1();                // read a single step encoder
98
    LEDS = val;
99
  }
100
}

Danke!

von Jörg S. (joerg-s)


Lesenswert?

Mathias Z. schrieb:
> Ergebniss: geht noch nicht.
Was genau geht nicht?


> #define PHASE_A   P1IN_4          // P1.4 als Eingang Encoder A
> #define PHASE_B   P1IN_5          // P1.5 als Eingang Encoder B
Wo ist P1IN_4/5 definiert?

von Mathias Z. (matziz198)


Lesenswert?

Wenn ich den Code richtig verstanden habe sollten die LEDs die Zustände 
des Drehgebers annehmen. Sie bleiben jedoch immer aus.

P1IN_4/5 sind in der io430g2553.h definiert. Diese wird über die io430.h 
eingebunden.

von Jörg S. (joerg-s)


Lesenswert?

Zählt er denn überhaupt? Oder ist encode_read1(); immer 0?

>P1REN |= (BIT4 + BIT5);    // P1.4 und P1.5 Pullups aktivieren
Der Pull-Up ist aber erst da, wenn du auch PxOUT auf 1 stellst.

von Mathias Z. (matziz198)


Lesenswert?

Ja, beim debug ist encode_read1() immer 0. Also stimmt was mit dem 
Eingang nicht. Angeschlossen habe ich den Encoder (ALPS STEC12E 24/24) 
so:

Anschluss A an P1.4
Anschluss B an P1.5
Anschluss C an Masse

von Mathias Z. (matziz198)


Lesenswert?

Die Pullups für P1.4 und P1.5 habe ich nun aktiviert:
1
P1REN |= (BIT4 + BIT5);                 // P1.4 und P1.5 Resistor enabled
2
P1OUT |= (BIT4 + BIT5);                 // P1.4 und P1.5 Pullup enabled

LEDs leuchten nicht.

von Jörg S. (joerg-s)


Lesenswert?

>Ja, beim debug ist encode_read1() immer 0.
Dann schau doch mal ob sich die Eingänge (P1.4 / P1.5) beim drehen 
ändern.

von Mathias Z. (matziz198)


Lesenswert?

Ich habe mit einem simplen Programm die Ports getestet. Das geht auch.

Kann es sein das dass Problem bei den defines liegt? Wie definiere ich 
einen einzigen Pin richtig? In der io430g2553.h sind die einzelnen 
input/output Pins mit P1IN_0 und P1OUT_0 definiert. Kann ich die direkt 
verwenden?

von Mathias Z. (matziz198)


Lesenswert?

Funktioniert jetzt. Linksdrehen leuchtet rot, rechtsdrehen leuchtet 
grün.
Abtastrate: ca. 500Hz


Portierung des Drehgeber- Inkrementaldrehgeber- Drehencoder-Codes von 
Peter Dannegger auf die MSP430 Plattform:
1
#include "io430.h"
2
#include "intrinsics.h"
3
 
4
// target: MSP430G2553 (Launch Pad)
5
//------------------------------------------------------------------------
6
7
/* ------------------------------------------------------------------------------------------------
8
 *                                               Types
9
 * ------------------------------------------------------------------------------------------------
10
*/
11
12
typedef signed   int    int8;
13
typedef unsigned int    uint8;
14
15
typedef signed   short  int16;
16
typedef unsigned short  uint16;
17
18
typedef signed   long   int32;
19
typedef unsigned long   uint32;
20
21
//----------------------------------------------------------------------------------------------
22
23
#define PHASE_A   (P1IN & BIT4)          // P1.4 als Eingang Encoder
24
#define PHASE_B   (P1IN & BIT5)          // P1.5 als Eingang Encoder
25
 
26
 
27
volatile int8 enc_delta;          // -128 ... 127
28
static int8 last;
29
30
31
void encode_init( void )
32
{
33
  int8 new;
34
 
35
  new = 0;
36
  if( PHASE_A )
37
    new = 3;
38
  if( PHASE_B )
39
    new ^= 1;                   // convert gray to binary
40
  last = new;                   // power on state
41
  enc_delta = 0;
42
}
43
44
  
45
#pragma vector=TIMER0_A0_VECTOR             // 1ms for manual movement
46
__interrupt void Timer_A (void)
47
{
48
  int8 new, diff;
49
 
50
  new = 0;
51
  if( PHASE_A )
52
    new = 3;
53
  if( PHASE_B )
54
    new ^= 1;                           // convert gray to binary
55
  diff = last - new;                    // difference last - new
56
  if( diff & 1 ){                       // bit 0 = value (1)
57
    last = new;                         // store new as next last
58
    enc_delta += (diff & 2) - 1;        // bit 1 = direction (+/-)
59
  }
60
  CCR0 += 2000;                         // Add Offset to CCR0
61
}
62
 
63
 
64
int8 encode_read1( void )               // read single step encoders
65
{
66
  int8 val;
67
 
68
  __disable_interrupt();
69
  val = enc_delta;
70
  enc_delta = 0;
71
  __enable_interrupt();
72
  return val;                           // counts since last call
73
}
74
75
76
int main( void )
77
{
78
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer to prevent time out reset
79
    
80
  BCSCTL1 = CALBC1_1MHZ;                // 1 MHz clock
81
  DCOCTL = CALDCO_1MHZ;
82
  
83
  CCTL0 = CCIE;                         // CCR0 interrupt enabled
84
  CCR0 = 2000;
85
  TACTL = TASSEL_2 + MC_2;              // SMCLK, contmode
86
87
  P1SEL = 0x00;                         // Port 1 als GPIO nutzen
88
  P1REN |= (BIT4 + BIT5);               // P1.4 und P1.5 Resistor enabled
89
  P1OUT |= (BIT4 + BIT5);               // P1.4 und P1.5 Pullup enabled
90
  P1DIR |= (BIT0 + BIT6);               // P1.0 und P1.6 LEDs
91
    
92
93
  int32 val = 0;
94
 
95
  encode_init();
96
  __enable_interrupt();
97
 
98
  for(;;)
99
  {
100
    val += encode_read1();
101
    
102
    if(val > 0)
103
      P1OUT |= 0x01;
104
    else 
105
      P1OUT &= ~ 0x01;
106
    
107
    if(val < 0)
108
      P1OUT |= 0x40;
109
    else 
110
      P1OUT &= ~ 0x40;
111
  }
112
}

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.