1 | //#include <avr/io.h>
|
2 | //#include <avr/interrupt.h>
|
3 |
|
4 | //ATmega2560
|
5 |
|
6 | /***********************/
|
7 | /******* Defines *******/
|
8 | /***********************/
|
9 | /* allgemeine Definitionen */
|
10 | #define XTAL 16e6 // 16MHz
|
11 |
|
12 | /* Interruptsteuerung */
|
13 | #define ENAB_GLOBAL_INT asm("sei") // Set I-Bit in SREG
|
14 | #define DISAB_GLOBAL_INT asm("cli") // Reset I-Bit in SREG
|
15 |
|
16 | /* Pin- und Portdefinitionen */
|
17 | /********************************* Arduino-LED (Testpunkt) *********************************************************************************/
|
18 | #define LED_ARD_DDR DDRB |= (1<<DDB7); PORTB &= ~(1<<PORTB7) // Port B, Bit 7 => LED Arduino-Board (Atmel -> LED) -> OUTPUT, OFF //
|
19 | #define LED_ARD_ON PORTB |= (1<<PORTB7) // LED Arduino-Board ein //
|
20 | #define LED_ARD_OFF PORTB &= ~(1<<PORTB7) // LED Arduino-Arduino aus //
|
21 | #define LED_ARD_TOGGLE PINB |= (1<<PINB7) // LED Arduino-Arduino toggel //
|
22 | /*******************************************************************************************************************************************/
|
23 |
|
24 | /********************************* LEDs (Port C) ************************************************************************************************************************/
|
25 | #define LEDS_DDR DDRC |= (1<<DDC7) | (1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0); // Port B, LEDS (Atmel -> LEDS) -> OUTPUT //
|
26 | #define LEDS PORTC // LEDs an Vcc //
|
27 | /********************************* LEDs (Port C) ************************************************************************************************************************/
|
28 |
|
29 | /********************************* Drehgeber (Port K) ********************************************************************************/
|
30 | //#define ENC_CHA_DDR DDRK &= ~(1<<DDK2);PORTK &= ~(1<<PORTK2) // Port K, Bit 2 => CW (Atmel <- Encoder) -> INPUT, TRISTATE //
|
31 | //#define ENC_CHA PINK & (1<<PINK2) // Drehgerber Kanal A //
|
32 | //
|
33 | //#define ENC_CHB_DDR DDRK &= ~(1<<DDK1);PORTK &= ~(1<<PORTK1) // Port K, Bit 1 => CCW (Atmel <- Encoder) -> INPUT, TRISTATE //
|
34 | //#define ENC_CHB PINK & (1<<PINK1) // Drehgerber Kanal B //
|
35 | //
|
36 | //#define ENC_TASTER_DDR DDRK &= ~(1<<DDK0);PORTK &= ~(1<<PORTK0) // Port K, Bit 0 => Taster (Atmel <- Encoder) -> INPUT, TRISTATE //
|
37 | //#define ENC_TASTER PINK & (1<<PINK0) // Drehgeber Taster //
|
38 | /*************************************************************************************************************************************/
|
39 |
|
40 | /********************************* Drehgeber (Port B) ********************************************************************************/
|
41 | #define ENC_CHA_DDR DDRB &= ~(1<<DDB6);PORTB &= ~(1<<PORTK6) // Port K, Bit 2 => CW (Atmel <- Encoder) -> INPUT, TRISTATE //
|
42 | #define ENC_CHA PINB & (1<<PINK6) // Drehgerber Kanal A //
|
43 | //
|
44 | #define ENC_CHB_DDR DDRB &= ~(1<<DDB5);PORTB &= ~(1<<PORTK5) // Port K, Bit 1 => CCW (Atmel <- Encoder) -> INPUT, TRISTATE //
|
45 | #define ENC_CHB PINB & (1<<PINK5) // Drehgerber Kanal B //
|
46 | //
|
47 | #define ENC_TASTER_DDR DDRB &= ~(1<<DDB4);PORTB &= ~(1<<PORTK4) // Port K, Bit 0 => Taster (Atmel <- Encoder) -> INPUT, TRISTATE //
|
48 | #define ENC_TASTER PINB & (1<<PINK4) // Drehgeber Taster //
|
49 | /*************************************************************************************************************************************/
|
50 |
|
51 | /*************************/
|
52 | /******* Variables *******/
|
53 | /*************************/
|
54 | volatile int8_t gsc_enc_delta; // -128 ... 127
|
55 | static int8_t gsc_enc_code_old;
|
56 |
|
57 | volatile int32_t gsl_enc_count;
|
58 | volatile uint8_t guc_enc_pushbutton;
|
59 |
|
60 |
|
61 | /*************************/
|
62 | /******* Functions *******/
|
63 | /*************************/
|
64 | void v_test_init (void);
|
65 | void v_encode_init (void);
|
66 | int8_t sc_encode_read1 (void);
|
67 | int8_t sc_encode_read2 (void);
|
68 | int8_t sc_encode_read4 (void);
|
69 | int8_t sc_encode_pushbutton (void);
|
70 |
|
71 | /******************************************************************************/
|
72 | /*****| Name: test_init |*****/
|
73 | /*****| Funktion: Definiert den Controllerpin, an den die Arduino- |*****/
|
74 | /*****| LED angeschlossen ist als Ausgang und schaltet |*****/
|
75 | /*****| diese aus. LED_ARD wird als Testpin zum Debugging |*****/
|
76 | /*****| benutzt. |*****/
|
77 | /*****| Übergabewerte: keiner |*****/
|
78 | /*****| Rückgabewert: keiner |*****/
|
79 | /******************************************************************************/
|
80 | void v_test_init (void)
|
81 | {
|
82 | LED_ARD_DDR;
|
83 | }
|
84 |
|
85 | void v_encode_init (void)
|
86 | {
|
87 | int8_t sc_enc_code; // Variable fuer den Code den der Drehgeber liefert
|
88 |
|
89 | ENC_TASTER_DDR; // Konfiguration Portpins...
|
90 | ENC_CHA_DDR;
|
91 | ENC_CHB_DDR;
|
92 |
|
93 | sc_enc_code = 0; // Variable fuer den Code mit 0 initialisieren
|
94 |
|
95 | if (ENC_CHA) // High an Channel A?
|
96 | sc_enc_code = 3; //
|
97 |
|
98 | if (ENC_CHB) // High an Channel B?
|
99 | sc_enc_code ^= 1; //
|
100 |
|
101 | gsc_enc_code_old = sc_enc_code; // Neuen Code merken
|
102 |
|
103 | gsc_enc_delta = 0;
|
104 |
|
105 | TCCR0A = (1<<WGM01); // CTC
|
106 | TCCR0B = (1<<CS01) | (1<<CS00); // CTC, prescaler 64
|
107 |
|
108 | OCR0A = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5); // 1ms
|
109 | TIMSK0 |= 1<<OCIE0A;
|
110 | }
|
111 |
|
112 | int8_t sc_encode_read1 (void) // read single step encoders
|
113 | {
|
114 | int8_t val;
|
115 |
|
116 | cli();
|
117 | val = gsc_enc_delta;
|
118 | gsc_enc_delta = 0;
|
119 | sei();
|
120 | return val; // counts since last call
|
121 | }
|
122 |
|
123 | int8_t sc_encode_read2 (void) // read two step encoders
|
124 | {
|
125 | int8_t val;
|
126 |
|
127 | cli();
|
128 | val = gsc_enc_delta;
|
129 | gsc_enc_delta = val & 1;
|
130 | sei();
|
131 | return val >> 1;
|
132 | }
|
133 |
|
134 | int8_t sc_encode_read4 (void) // read four step encoders
|
135 | {
|
136 | int8_t val;
|
137 |
|
138 | cli();
|
139 | val = gsc_enc_delta;
|
140 | gsc_enc_delta = val & 3;
|
141 | sei();
|
142 | return val >> 2;
|
143 | }
|
144 |
|
145 | int8_t sc_encode_pushbutton (void) // read four step encoders pushbutton
|
146 | {
|
147 | static uint8_t uc_state;
|
148 | int8_t sc_return_val = 0;
|
149 |
|
150 | if (uc_state == 0 && !(ENC_TASTER)) //Taster wird gedrueckt (steigende Flanke)
|
151 | {
|
152 | uc_state = 1;
|
153 | sc_return_val = 1;
|
154 | Serial.println (sc_return_val, DEC);
|
155 | }
|
156 | else if (uc_state == 1 && !(ENC_TASTER)) //Taster wird gehalten
|
157 | {
|
158 | uc_state = 2;
|
159 | sc_return_val = 0;
|
160 | }
|
161 | else if (uc_state == 2 && !(ENC_TASTER)) //Taster wird losgelassen (fallende Flanke)
|
162 | {
|
163 | uc_state = 3;
|
164 | sc_return_val = 0;
|
165 | }
|
166 | else if (uc_state == 3 && !(ENC_TASTER)) //Taster losgelassen
|
167 | {
|
168 | uc_state = 0;
|
169 | sc_return_val = 0;
|
170 | }
|
171 |
|
172 | return sc_return_val;
|
173 | }
|
174 |
|
175 | /*********************************/
|
176 | /******* Main ********************/
|
177 | /*********************************/
|
178 | int main (void)
|
179 | {
|
180 | int32_t sl_val = 0;
|
181 | int8_t i;
|
182 |
|
183 | LEDS_DDR;
|
184 |
|
185 | //Serial.begin (9600);
|
186 | v_test_init ();
|
187 | v_encode_init ();
|
188 |
|
189 | gsl_enc_count = 0;
|
190 | guc_enc_pushbutton = 0;
|
191 |
|
192 | //LED_ARD_TOGGLE;
|
193 | //_delay_ms (1000);
|
194 | //LED_ARD_TOGGLE;
|
195 | //_delay_ms (1000);
|
196 | //LED_ARD_TOGGLE;
|
197 | //_delay_ms (1000);
|
198 | //LED_ARD_TOGGLE;
|
199 | //_delay_ms (1000);
|
200 |
|
201 | sei ();
|
202 |
|
203 | while (1)
|
204 | {
|
205 | sl_val += sc_encode_read4 (); // read four step encoders
|
206 | LEDS = sl_val;
|
207 | //gsl_enc_count += sc_encode_read4 (); // read four step encoders
|
208 |
|
209 |
|
210 | if (guc_enc_pushbutton)
|
211 | {
|
212 | LED_ARD_TOGGLE;
|
213 | //Serial.println (guc_enc_pushbutton, DEC);
|
214 | }
|
215 | }
|
216 | }
|
217 |
|
218 | /**********************************/
|
219 | /******* Interrupt routines *******/
|
220 | /**********************************/
|
221 | ISR (TIMER0_COMPA_vect) // 1ms fuer manuelle Betätigung des Drehgebers
|
222 | {
|
223 | int8_t sc_enc_code;
|
224 | int8_t sc_diff;
|
225 |
|
226 | sc_enc_code = 0; // Variable fuer den Code mit 0 initialisieren
|
227 |
|
228 | if (ENC_CHA) // High an Channel A?
|
229 | sc_enc_code = 3; //
|
230 |
|
231 | if (ENC_CHB) // High an Channel B?
|
232 | sc_enc_code ^= 1; //
|
233 |
|
234 | sc_diff = gsc_enc_code_old - sc_enc_code; // Differenz zwischen zwei Schritten ermitteln
|
235 |
|
236 | if (sc_diff & 1) // Bit 0 hat nur den Wert 1 wenn die Differenz 1 ist
|
237 | {
|
238 | gsc_enc_code_old = sc_enc_code; // Neuen Code merken
|
239 | gsc_enc_delta += (sc_diff & 2) - 1; // Bit 1 ist die Richtung (+/-)
|
240 | }
|
241 |
|
242 | guc_enc_pushbutton = sc_encode_pushbutton ();
|
243 | }
|