1 | #include "io430.h"
|
2 | #include "intrinsics.h"
|
3 |
|
4 |
|
5 | typedef signed int int8;
|
6 | typedef unsigned int uint8;
|
7 | typedef signed short int16;
|
8 | typedef unsigned short uint16;
|
9 | typedef signed long int32;
|
10 | typedef unsigned long uint32;
|
11 |
|
12 |
|
13 | #define PHASE_A (P1IN & BIT4) // P1.4 als Eingang Encoder
|
14 | #define PHASE_B (P1IN & BIT5) // P1.5 als Eingang Encoder
|
15 |
|
16 | volatile int8 enc_delta; // -128 ... 127
|
17 | static int8 last;
|
18 |
|
19 | const uint16 pwm_table[64] = {
|
20 | 0, 0, 2, 4, 8, 14, 21, 30, 41, 54,
|
21 | 69, 86, 106, 127, 151, 178, 206, 238, 271, 308,
|
22 | 347, 388, 433, 480, 530, 583, 638, 697, 758, 823,
|
23 | 890, 961, 1035, 1111, 1191, 1274, 1361, 1450, 1543, 1639,
|
24 | 1739, 1841, 1947, 2057, 2170, 2286, 2406, 2530, 2657, 2787,
|
25 | 2921, 3059, 3200, 3345, 3494, 3646, 3802, 3962, 4125, 4293,
|
26 | 4464, 4639, 4817, 5000
|
27 | };
|
28 |
|
29 | static uint8 pwm_index = 7;
|
30 |
|
31 |
|
32 | void encode_init( void )
|
33 | {
|
34 | int8 new;
|
35 |
|
36 | new = 0;
|
37 | if( PHASE_A )
|
38 | new = 3;
|
39 | if( PHASE_B )
|
40 | new ^= 1; // convert gray to binary
|
41 | last = new; // power on state
|
42 | enc_delta = 0;
|
43 | }
|
44 |
|
45 | int8 encode_read1( void ) // read single step encoders
|
46 | {
|
47 | int8 val;
|
48 |
|
49 | __disable_interrupt();
|
50 | val = enc_delta;
|
51 | enc_delta = 0;
|
52 | __enable_interrupt();
|
53 | return val; // counts since last call
|
54 | }
|
55 |
|
56 |
|
57 | // Watchdog Timer interrupt service routine used for Encoder
|
58 | #pragma vector=WDT_VECTOR
|
59 | __interrupt void watchdog_timer(void)
|
60 | {
|
61 | int8 new, diff;
|
62 |
|
63 | new = 0;
|
64 | if( PHASE_A )
|
65 | new = 3;
|
66 | if( PHASE_B )
|
67 | new ^= 1; // convert gray to binary
|
68 | diff = last - new; // difference last - new
|
69 | if( diff & 1 ){ // bit 0 = value (1)
|
70 | last = new; // store new as next last
|
71 | enc_delta += (diff & 2) - 1; // bit 1 = direction (+/-)
|
72 | }
|
73 | }
|
74 |
|
75 |
|
76 | void main( void )
|
77 | {
|
78 | WDTCTL = WDT_MDLY_0_5; // Set Watchdog Timer interval to ~0.5ms
|
79 | IE1 |= WDTIE; // Enable WDT interrupt
|
80 |
|
81 | BCSCTL1 = CALBC1_1MHZ; // 1 MHz clock
|
82 | DCOCTL = CALDCO_1MHZ;
|
83 |
|
84 | P1SEL = 0x00; // Port 1 als GPIO nutzen
|
85 | P1REN |= (BIT4 + BIT5); // P1.4 und P1.5 Resistor enabled
|
86 | P1OUT |= (BIT4 + BIT5); // P1.4 und P1.5 Pullup enabled
|
87 | P1DIR |= BIT6; // P1.6 output (green LED)
|
88 | P1SEL |= BIT6; // P1.6 = TA0.1 (timer A's output)
|
89 |
|
90 | TACTL = TASSEL_2 + MC_1; // Source Timer A from SMCLK (TASSEL_2), up mode (MC_1)
|
91 | // Up mode counts up to TACCR0
|
92 | TACCTL1 = OUTMOD_7; // OUTMOD_7 = CCR1 reset/set output when the timer counts to TACCR1
|
93 | TACCR0 = 5000; // PWM period = 1 MHz / 5000 = ~200 Hz
|
94 | TACCR1 = pwm_table[7]; // Initial CCR1 (= brightness)
|
95 |
|
96 | int8 val = 0;
|
97 |
|
98 | encode_init();
|
99 | __enable_interrupt();
|
100 |
|
101 | for(;;)
|
102 | {
|
103 | val += encode_read1();
|
104 |
|
105 | if(val > 0) // Encoder linksdrehung
|
106 | { // grün dunkler (LED1)
|
107 | if (pwm_index > 1)
|
108 | {
|
109 | pwm_index--;
|
110 | TACCR1 = pwm_table[pwm_index];
|
111 | }
|
112 | else {TACCR1 = pwm_table[0];}
|
113 | val--;
|
114 | }
|
115 |
|
116 | if(val < 0) // Encoder rechtsdrehung
|
117 | { // grün heller (LED1)
|
118 | if (pwm_index < 62)
|
119 | {
|
120 | pwm_index++;
|
121 | TACCR1 = pwm_table[pwm_index];
|
122 | }
|
123 | else {TACCR1 = pwm_table[63];}
|
124 | val--;
|
125 | }
|
126 | }
|
127 | }
|