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 | }
|