1 | /*************************************************************************
|
2 | * *
|
3 | * Projekt: Studienarbeit 6.Semester *
|
4 | * Thema: Entwicklung eines DJ-Mischpultes mit USB-Anschluss *
|
5 | * Student: Eric Schrön *
|
6 | * Kurs: TEL05AAT *
|
7 | * Betreuer: Prof. Walter Berthold *
|
8 | * Datei: mischpult.c *
|
9 | * Editor: AVR Studio 4 *
|
10 | * Copmiler: GNU-GCC Compiler *
|
11 | * Abgabedatum: 27.03.2008 *
|
12 | * *
|
13 | * Beschreibung: Das folgende Programm wird auf den Mikrocontroller *
|
14 | * im Mischpult geladen. Das Programm ist für einen *
|
15 | * ATMEGA16 von der Firma Atmel geschrieben. *
|
16 | * Das folgende Programm sammelt alle Daten der Dreh- *
|
17 | * geber und der Schiebepotis, wertet sie aus und *
|
18 | * ordnet ihnen die entsprechende Funktion zu. Außer- *
|
19 | * dem stellt das Programm die Kommuikation mit einem *
|
20 | * PC über die USART Schnittstelle des µC her. *
|
21 | * Zunächst werden alle notwendigen Daten initiali- *
|
22 | * siert. Anschließend wird erstmalig der AD-Wandler *
|
23 | * zu Initialisierungszwecken aufgerufen. Der Ab- *
|
24 | * schluss der Wandlung wird von dem µC mit einem *
|
25 | * Interrupt signalisiert, womit eine entsprechende *
|
26 | * Interruptserviceroutine(ISR) aufgerufen wird. Dort *
|
27 | * wird zu Beginn der AD-Wandler wieder gestartet, *
|
28 | * der nur mit einem Bruchteil der Taktfrequenz, Ein- *
|
29 | * gangsdaten wandeln kann. In der Zwischenzeit werden *
|
30 | * alle nicht AD-Pins abgefragt und ausgewertet. Wenn *
|
31 | * sich bei irgendeinem Pin etwas wird dies in eine *
|
32 | * Variable geschrieben und in der dazu gehörigen *
|
33 | * Adressvariable ein Dirty-Bit gesetzt. Wenn die AD- *
|
34 | * Wandlung abgeschlossen ist, wird erneut die ISR *
|
35 | * aufgerufen. *
|
36 | * Wenn die ISR nicht aktiv ist, wird main durch- *
|
37 | * laufen. Dort wird das Speicherabbild auf gesetzte *
|
38 | * Dirty-Bits geprüft. In diesem Fall wird eine *
|
39 | * Funktion senden aufgerufen, die das Adress- und *
|
40 | * Datenbyte des jeweiligen Reglers sendet. Außerdem *
|
41 | * ist ein 200 Byte großer FIFO implementiert. *
|
42 | * *
|
43 | *************************************************************************/
|
44 |
|
45 | #include <stdint.h>
|
46 | #include <avr/io.h>
|
47 | #include <avr/interrupt.h>
|
48 | #include <variablen.h>
|
49 | //#include "funktionen.c"
|
50 |
|
51 | #define F_OSC 12000000 /* oscillator-frequency in Hz */
|
52 | #define UART_BAUD_RATE 57600
|
53 | #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16l)-1)
|
54 |
|
55 |
|
56 |
|
57 | uint8_t geber(uint8_t bits_alt1, uint8_t bits_neu);
|
58 | uint8_t taster(uint16_t wert);
|
59 | void senden(uint8_t adresse, uint16_t wert);
|
60 |
|
61 | /**************************************************
|
62 | * *
|
63 | * Initialisierung der globalen Variablen *
|
64 | * Diese werden in main() und in der ISR *
|
65 | * benötigt *
|
66 | * *
|
67 | **************************************************/
|
68 |
|
69 | //vol, pitch, fader, lpbs, rpbs sind werte vom ADC
|
70 | uint16_t lvol, lpitch, mvol, fader, rpitch, rvol, lpbs, rpbs;
|
71 | uint16_t lvol_old, lpitch_old, mvol_old, fader_old, rpitch_old, rvol_old, lpbs_old, rpbs_old;
|
72 | uint16_t lpbs_temp[10]={0,0,0,0,0,0,0,0,0,0};
|
73 | uint8_t alvol, alpitch, amvol, afader, arpitch, arvol, altaste, artaste;
|
74 | uint8_t shift, trigger=0;
|
75 |
|
76 | //Digitalwerte von den Drehgebern
|
77 | uint8_t leh, lem, lel, reh, rem, rel, ljw, rjw, hpvol, hpsel;
|
78 | uint8_t aleh, alem, alel, areh, arem, arel, aljw, arjw, ahpvol, ahpsel;
|
79 | uint8_t leh_old, lem_old, lel_old, reh_old, rem_old, rel_old, ljw_old, rjw_old, hpvol_old, hpsel_old;
|
80 | uint8_t ljw_old2, rjw_old2;
|
81 | //Zähler zur ADC-Kanal auswahl
|
82 | uint8_t zaehler, k;
|
83 |
|
84 | int main(void)
|
85 | {
|
86 |
|
87 |
|
88 | /**************************************************
|
89 | * *
|
90 | * Initialisierung der Variablen für den FIFO *
|
91 | * *
|
92 | **************************************************/
|
93 |
|
94 | //daten[200]: FIFO für die Datenvariablen
|
95 | //adresse[200]: FIFO für die Adressvariablen
|
96 | //i: Zählvariable für den schreibenden Zugriff auf das FIFO
|
97 | //j: Zählvariable für den lesenden Zugriff auf das FIFO
|
98 | //imax: maximal mögliche Anzahl schreibender Einträge im nächsten Zyklus
|
99 | //jmax: maximal mögliche Anzahl lesender Einträge
|
100 | //zaehler: Zählvariable für die Auswahl des Analogeinganges
|
101 |
|
102 | uint8_t i, j, imax, jmax, adresse[200];
|
103 | uint16_t daten[200];
|
104 | i = 0;
|
105 | j = 0;
|
106 | imax = 200;
|
107 | jmax = 200;
|
108 | zaehler = 0;
|
109 |
|
110 | /*********************************************************
|
111 | * *
|
112 | * Initialisierung der Variablen für die Reglerdaten *
|
113 | * entsprechend den Bezeichnungen der Bauteile *
|
114 | * *
|
115 | *********************************************************/
|
116 |
|
117 | leh = 128;
|
118 | lem = 128;
|
119 | lel = 128;
|
120 | reh = 128;
|
121 | rem = 128;
|
122 | rel = 128;
|
123 | ljw = 128;
|
124 | rjw = 128;
|
125 | hpsel = 128;
|
126 | hpvol = 128;
|
127 |
|
128 | leh_old = 0xFF;
|
129 | lem_old = 0xFF;
|
130 | lel_old = 0xFF;
|
131 | reh_old = 0xFF;
|
132 | rem_old = 0xFF;
|
133 | rel_old = 0xFF;
|
134 | ljw_old = 0xFF;
|
135 | rjw_old = 0xFF;
|
136 | hpvol_old = 0xFF;
|
137 | hpsel_old = 0xFF;
|
138 | ljw_old2 = 0xFF;
|
139 | rjw_old2 = 0xFF;
|
140 |
|
141 | lvol = 0;
|
142 | lpitch = 0;
|
143 | mvol = 0;
|
144 | fader = 0;
|
145 | rpitch = 0;
|
146 | rvol = 0;
|
147 | lpbs = 0;
|
148 | rpbs = 0;
|
149 |
|
150 | lvol_old = 0xFFFF;
|
151 | lpitch_old = 0xFFFF;
|
152 | mvol_old = 0xFFFF;
|
153 | fader_old = 0xFFFF;
|
154 | rpitch_old = 0xFFFF;
|
155 | rvol_old = 0xFFFF;
|
156 | lpbs_old = 0xFFFF;
|
157 | rpbs_old = 0xFFFF;
|
158 |
|
159 |
|
160 | /***************************************************************
|
161 | * *
|
162 | * Initialisierung der Adressvariablen für die Reglerdaten *
|
163 | * *
|
164 | ***************************************************************/
|
165 |
|
166 | alvol = 0x10;
|
167 | alpitch = 0x18;
|
168 | amvol = 0x20;
|
169 | afader = 0x28;
|
170 | arpitch = 0x30;
|
171 | arvol = 0x38;
|
172 | aleh = 0x40;
|
173 | alem = 0x48;
|
174 | alel = 0x50;
|
175 | ahpvol = 0x58;
|
176 | areh = 0x60;
|
177 | arem = 0x68;
|
178 | arel = 0x70;
|
179 | aljw = 0x78;
|
180 | arjw = 0x80;
|
181 | ahpsel = 0x88;
|
182 | altaste = 0x90;
|
183 | artaste = 0x98;
|
184 |
|
185 | /*********************************************************
|
186 | * *
|
187 | * Initialisierung der Ports des µC *
|
188 | * PORTx für die Aktivierung der Pull-Up Widerstände *
|
189 | * DDRx für die Angabe der Datenrichtung (I/O) *
|
190 | * *
|
191 | *********************************************************/
|
192 |
|
193 | //PORTx: Einstellung für die Pull-Up Widerstände
|
194 | //DDRx: Einstellung für die Datenrichtung (I/O)
|
195 |
|
196 | PORTA = 0x00;
|
197 | DDRA = 0x00;
|
198 | PORTB = 0x3F;
|
199 | DDRB = 0xC0;
|
200 | PORTC = 0xFF;
|
201 | DDRC = 0x00;
|
202 | PORTD = 0xFC;
|
203 | DDRD = 0x02;
|
204 |
|
205 | /***********************************************************************
|
206 | * *
|
207 | * Initialisierung der Variablen für den USART und des AD-Wandlers *
|
208 | * *
|
209 | ***********************************************************************/
|
210 |
|
211 | //UBRR: Register zur Einstellung der Baudrate
|
212 | //RXEN: Aktivierung des µC zum Empfangen von Daten
|
213 | //TXEN: Aktivierung des µC zum Senden von Daten
|
214 | //URSEL: Schreibzugriff auf UCSRC Register
|
215 | //USBS: Anzahl der Stoppbits, hier 1
|
216 | //UCSZ0: Anzahl der Datenbits, hier 8
|
217 |
|
218 | UBRRH = (uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_OSC)>>8);
|
219 | UBRRL = (uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_OSC);
|
220 |
|
221 |
|
222 | // Enable receiver and transmitter; enable RX interrupt
|
223 | UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
|
224 |
|
225 | //asynchronous 8N1
|
226 | UCSRC = (1 << URSEL) | (3 << UCSZ0);
|
227 |
|
228 |
|
229 | //ADEN: Aktivierung des AD-Wandlers
|
230 | //ADPS0-2: Teilungsfaktor für AD-Takt, hier 64
|
231 | //ADIE: Aktivierung des AD-Wandler Interrupts
|
232 | //ADMUX: Auswahl des AD-Input Pins
|
233 |
|
234 | ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
|
235 | ADCSRA |= (1<<ADIE);
|
236 | ADMUX = 0x20;
|
237 |
|
238 | /**********************************************************************
|
239 | * *
|
240 | * Aktivieren des Global Interrupt Enable Flags im Statusregister *
|
241 | * Starten des AD-Wandler für die Initialisierung *
|
242 | * *
|
243 | **********************************************************************/
|
244 |
|
245 | sei(); //Aktivierung des Global Interrupt Enable Flags im Statusregister (SREG)
|
246 |
|
247 | ADCSRA |= (1<<ADSC); //Aktivierung des AD-Wandlers
|
248 | while(!(ADCSRA & 0x10)) //Warten auf Beendigung der AD-Wandlung
|
249 | {
|
250 |
|
251 | }
|
252 |
|
253 | /**************************************************************************
|
254 | * *
|
255 | * Beginn der Endlosschleife zur Abfrage der Dirty-Bits *
|
256 | * 1) Prüfen ob noch genügend Platz im FIFO ist (30 Werte mindestens) *
|
257 | * - "i" ist die Zählvariable der schreibenden Einträge im FIFO *
|
258 | * - "imax" ist die Maximalanzahl von schreibbaren Einträgen *
|
259 | * 2) Prüfen ob im jeweiligen Adressbyte das Dirty-Bit gesetzt ist *
|
260 | * - Maskierung mit 0x04 und gleichzeitigen Prüfen aus "TRUE" *
|
261 | * 3) Wenn "FALSE" ist wird das nächste Adressbyte geprüft *
|
262 | * 4) Wenn "TRUE" ist, dann werden der Interrupt deaktiviert, *
|
263 | * Adress- und Datenbyte in den FIFO geschrieben, das Dirty-Bit *
|
264 | * gelöscht, der Interrupt aktiviert und "i" inkrementiert. *
|
265 | * *
|
266 | **************************************************************************/
|
267 |
|
268 | while(1) //Endlosschleife
|
269 | {
|
270 | if((i+30)<imax) //Überprüfung ob genügend Speicherplatz im FIFO vorhanden ist
|
271 | {
|
272 | if(alvol & 0x04) ///Überprüfung, ob das Dirty-Bit gesetzt ist
|
273 | {
|
274 | cli(); //Löschen des Global Interrupt Enable Flags im Statusregister
|
275 | alvol &= ~0x04; //Löschen des Dirty-Bits
|
276 | adresse[i] = alvol; //Speichern der Adressvariablen im FIFO
|
277 | daten[i] = (lvol >> 6); //Speicherung der Datenvariablen im FIFO
|
278 | sei(); //Setzen des Global Interrupt Enable Flags im Statusregister
|
279 | i++; //Inkrementierung des Indizes für den schreibenden Zugriff auf das FIFO
|
280 | }
|
281 | if(alpitch & 0x04)
|
282 | {
|
283 | cli();
|
284 | alpitch &= ~0x04;
|
285 | adresse[i] = alpitch;
|
286 | daten[i] = (lpitch >> 6);
|
287 | sei();
|
288 | i++;
|
289 | }
|
290 | if(amvol & 0x04)
|
291 | {
|
292 | cli();
|
293 | amvol &= ~0x04;
|
294 | adresse[i] = amvol;
|
295 | daten[i] = (mvol >> 6);
|
296 | sei();
|
297 | i++;
|
298 | }
|
299 | if(afader & 0x04)
|
300 | {
|
301 | cli();
|
302 | afader &= ~0x04;
|
303 | adresse[i] = afader;
|
304 | daten[i] = (fader >> 6);
|
305 | sei();
|
306 | i++;
|
307 | }
|
308 | if(arpitch & 0x04)
|
309 | {
|
310 | cli();
|
311 | arpitch &= ~0x04;
|
312 | adresse[i] = arpitch;
|
313 | daten[i] = (rpitch >> 6);
|
314 | sei();
|
315 | i++;
|
316 | }
|
317 | if(arvol & 0x04)
|
318 | {
|
319 | cli();
|
320 | arvol &= ~0x04;
|
321 | adresse[i] = arvol;
|
322 | daten[i] = (rvol >> 6);
|
323 | sei();
|
324 | i++;
|
325 | }
|
326 | if(aleh & 0x04)
|
327 | {
|
328 | cli();
|
329 | aleh &= ~0x04;
|
330 | adresse[i] = aleh;
|
331 | daten[i] = leh;
|
332 | sei();
|
333 | i++;
|
334 | }
|
335 | if(alem & 0x04)
|
336 | {
|
337 | cli();
|
338 | alem &= ~0x04;
|
339 | adresse[i] = alem;
|
340 | daten[i] = lem;
|
341 | sei();
|
342 | i++;
|
343 | }
|
344 | if(alel & 0x04)
|
345 | {
|
346 | cli();
|
347 | alel &= ~0x04;
|
348 | adresse[i] = alel;
|
349 | daten[i] = lel;
|
350 | sei();
|
351 | i++;
|
352 | }
|
353 | if(ahpvol & 0x04)
|
354 | {
|
355 | cli();
|
356 | ahpvol &= ~0x04;
|
357 | adresse[i] = ahpvol;
|
358 | daten[i] = hpvol;
|
359 | sei();
|
360 | i++;
|
361 | }
|
362 | if(areh & 0x04)
|
363 | {
|
364 | cli();
|
365 | areh &= ~0x04;
|
366 | adresse[i] = areh;
|
367 | daten[i] = reh;
|
368 | sei();
|
369 | i++;
|
370 | }
|
371 | if(arem & 0x04)
|
372 | {
|
373 | cli();
|
374 | arem &= ~0x04;
|
375 | adresse[i] = arem;
|
376 | daten[i] = rem;
|
377 | sei();
|
378 | i++;
|
379 | }
|
380 | if(arel & 0x04)
|
381 | {
|
382 | cli();
|
383 | arel &= ~0x04;
|
384 | adresse[i] = arel;
|
385 | daten[i] = rel;
|
386 | sei();
|
387 | i++;
|
388 | }
|
389 | if(aljw & 0x04)
|
390 | {
|
391 | cli();
|
392 | aljw &= ~0x04;
|
393 | adresse[i] = aljw;
|
394 | daten[i] = ljw;
|
395 | sei();
|
396 | i++;
|
397 | }
|
398 | if(arjw & 0x04)
|
399 | {
|
400 | cli();
|
401 | arjw &= ~0x04;
|
402 | adresse[i] = arjw;
|
403 | daten[i] = rjw;
|
404 | sei();
|
405 | i++;
|
406 | }
|
407 | if(ahpsel & 0x04)
|
408 | {
|
409 | cli();
|
410 | ahpsel &= ~0x04;
|
411 | adresse[i] = ahpsel;
|
412 | daten[i] = hpsel;
|
413 | sei();
|
414 | i++;
|
415 | }
|
416 | if(altaste & 0x04)
|
417 | {
|
418 | cli();
|
419 | altaste &= ~0x04;
|
420 | adresse[i] = altaste;
|
421 | daten[i] = lpbs;
|
422 | sei();
|
423 | i++;
|
424 | }
|
425 | if(artaste & 0x04)
|
426 | {
|
427 | cli();
|
428 | artaste &= ~0x04;
|
429 | adresse[i] = artaste;
|
430 | daten[i] = rpbs;
|
431 | sei();
|
432 | i++;
|
433 | }
|
434 | }
|
435 |
|
436 | /***********************************************************************************
|
437 | * *
|
438 | * 5) Wenn mehr geschriebene als gelesene Daten im FIFO sind, *
|
439 | * wird die Funktion "senden" aufgerufen und "j" inkrementiert *
|
440 | * - "j" ist die Zählvariable der lesenden Einträge im FIFO *
|
441 | * - "jmax" ist die Maximalanzahl der zu lesenden Einträgen *
|
442 | * 6) Wenn "i" größer als 170 wird, werden "imax", "jmax", und "i" neu gesetzt *
|
443 | * 7) Wenn "j" die Maximalanzahl erreicht, wird j zurückgesetzt *
|
444 | * Ende der Endlosschleife *
|
445 | * *
|
446 | ***********************************************************************************/
|
447 |
|
448 | if(i!=j) //Überprüfung ob Indizes für schreibenden und lesenden Zugriff gleich ist, Index für schreibenden Zugriff ist immer voreilend
|
449 | {
|
450 | if(UCSRA & 0x20) //Überprüfung ob das Senden-Register leer ist
|
451 | {
|
452 | senden(adresse[j], daten[j]); //Aufruf der Funktion senden
|
453 | j++; //Inkrementierung des Indizes für den lesenden Zugriff
|
454 | if(imax<=(i+30)) imax++; //Überprüfung, ob noch Platz im FIFO für zu speichernde Werte ist
|
455 | }
|
456 | }
|
457 |
|
458 | if(i>170) //Überprüfung, ob FIFO beim nächsten Durchlauf überlaufen könnte
|
459 | {
|
460 | imax = j; //Festlegung der maximal zu schreibenden Einträge
|
461 | jmax = i; //Festlegung der maximal zu lesenden Einträge
|
462 | i = 0; //Reset des Indizes der schreibenden Einträge
|
463 | }
|
464 |
|
465 | if(j==jmax) j = 0; //Wenn die maximal zu lesende Anzahl der lesenden Einträge erreicht ist, wird Index für die lesenden Einträge resetet
|
466 |
|
467 | }
|
468 |
|
469 | return 0;
|
470 | }
|
471 |
|
472 | /***********************************************************************************
|
473 | * *
|
474 | * Beginn der ISR, die aufgerufen wird, wenn die AD-Wandlung abgeschlossen ist *
|
475 | * *
|
476 | ***********************************************************************************/
|
477 |
|
478 | ISR(_VECTOR(14))
|
479 | {
|
480 |
|
481 | /******************************************************************************************
|
482 | * *
|
483 | * Auswahl der zu vergleichenden Reglervariablen mit dem ADC-Register, *
|
484 | * das mit dem Ergfebnis der vorherigen Wandlung belegt ist *
|
485 | * 1) Wenn Ungleichheit besteht wird die Datenvariable mit dem ADCH Register belegt, *
|
486 | * und das Dirty-Bit gesetzt. Bei xPBS wird eine extra Funktion aufgerufen. *
|
487 | * 2) Wenn Gleichheit besteht, wird die Funktion fortgeführt *
|
488 | * 3) Wenn "zaehler" einmal alle AD-Pins durchlaufen hat, wird er auf "0" gesetzt *
|
489 | * *
|
490 | ******************************************************************************************/
|
491 |
|
492 | switch(zaehler) //Auswahl des AD-Einganges
|
493 | {
|
494 | case 0: if((lvol != ADC) && (lvol_old != ADC))
|
495 | {
|
496 | lvol_old=lvol;
|
497 | lvol = ADC;
|
498 | alvol |= 0x04;
|
499 | };
|
500 | break;
|
501 | case 1: if((lpitch != ADC) && (lpitch_old != ADC)) //bei Auswahl Vergleich, ob sich Datenvariable geändert hat
|
502 | {
|
503 | lpitch_old = lpitch;
|
504 | lpitch = ADC; //Speichern der neuen Datenvariablen
|
505 | alpitch |= 0x04; //setzen des Dirty-Bits
|
506 | };
|
507 | break;
|
508 | case 2: /*{
|
509 | if((lpbs != ADC) && (lpbs_old!=ACD))
|
510 | {
|
511 | trigger=1;
|
512 | }
|
513 | for(shift=8;shift>=0;shift--)
|
514 | {
|
515 | lpbs_temp[(shift+1)]=lpbs_temp[shift];
|
516 | }
|
517 | lpbs_temp[9]=lpbs_temp[8];
|
518 | lpbs_temp[8]=lpbs_temp[7];
|
519 | lpbs_temp[7]=lpbs_temp[6];
|
520 | lpbs_temp[6]=lpbs_temp[5];
|
521 | lpbs_temp[5]=lpbs_temp[4];
|
522 | lpbs_temp[4]=lpbs_temp[3];
|
523 | lpbs_temp[3]=lpbs_temp[2];
|
524 | lpbs_temp[2]=lpbs_temp[1];
|
525 | lpbs_temp[1]=lpbs_temp[0];
|
526 | lpbs_temp[0]=ADC;
|
527 |
|
528 | if((lpbs_temp[0] == lpbs_temp[1]) && trigger==1)
|
529 | {
|
530 | lpbs_old=lpbs;
|
531 | lpbs=ADC;
|
532 | altaste |= 0x04;
|
533 | trigger=0;
|
534 | }
|
535 | };*/
|
536 | break;
|
537 | case 3: if((mvol != ADC) && (mvol_old != ADC))
|
538 | {
|
539 | mvol_old = mvol;
|
540 | mvol = ADC;
|
541 | amvol |= 0x04;
|
542 | };
|
543 | break;
|
544 | case 4: if((fader != ADC) && (fader_old != ADC))
|
545 | {
|
546 | fader_old=fader;
|
547 | fader = ADC;
|
548 | afader |= 0x04;
|
549 |
|
550 | };
|
551 | break;
|
552 | case 5: /*if(rpbs != ADC)
|
553 | {
|
554 | rpbs = ADC;
|
555 | artaste |= 0x04;
|
556 | };
|
557 | break;*/
|
558 | case 6: if((rpitch != ADC) &&(rpitch_old != ADC))
|
559 | {
|
560 | rpitch_old = rpitch;
|
561 | rpitch = ADC;
|
562 | arpitch |= 0x04;
|
563 | };
|
564 | break;
|
565 | case 7: if((rvol != ADC) && (rvol_old != ADC))
|
566 | {
|
567 | rvol_old = rvol;
|
568 | rvol = ADC;
|
569 | arvol |= 0x04;
|
570 | };
|
571 | break;
|
572 | }
|
573 |
|
574 | zaehler++; //Inkrmentierung zur Auswahl des nächsten Analogeingangs
|
575 | if(zaehler==8) zaehler = 0; //Wenn alle Analogeingänge abgefragt wurden, wird der Zähler zurückgesetzt
|
576 |
|
577 | ADMUX = 0x20 | zaehler; //Setzen des Auswahlregisters für den Analogeingang
|
578 | ADCSRA |= (1<<ADSC); //Aktivieren des AD-Wandlers
|
579 |
|
580 | /*******************************************************************************
|
581 | * *
|
582 | * Vergleichen aller nicht AD-Variablen mit den jeweiligen Pinzuständen *
|
583 | * 1) Belegen von "k" mit den Variablenzuständen *
|
584 | * 2) Vergleichen von "k" mit den Datenvariablen *
|
585 | * 3) Wenn "FALSE", dann werden die restlichen Werte verglichen *
|
586 | * 4) Wenn "TRUE", dann wird die Funktion zur Berechnung der Geberwerte *
|
587 | * aufgerufen, das Dirty-Bit gesetzt und die Vergleichsvariable belegt. *
|
588 | * *
|
589 | *******************************************************************************/
|
590 |
|
591 | k = PINB & 0x03; //Belegung einer Variable mit den entsprechenden Pins
|
592 | if(k!=leh_old) //Überprüfung, ob sich die Bitkombination geändert hat
|
593 | {
|
594 | leh = geber(k, leh_old); //Aufrufen der Funktion "geber" zur Berechnung des absoluten Wertes
|
595 | aleh |= 0x04; //setzen des Dirty-Bits
|
596 | leh_old=k;
|
597 | }
|
598 |
|
599 | k = (PINB & 0x0C) >> 2;
|
600 | if(k!=lem_old)
|
601 | {
|
602 | lem = geber(k, lem_old);
|
603 | alem |= 0x04;
|
604 | lem_old=k;
|
605 | }
|
606 |
|
607 | k = (PINB & 0x30) >> 4;
|
608 | if(k!=lel_old)
|
609 | {
|
610 | lel = geber(k, lel_old);
|
611 | alel |= 0x04;
|
612 | lel_old=k;
|
613 | }
|
614 |
|
615 | k = PINC & 0x03;
|
616 | if(k!=hpvol_old)
|
617 | {
|
618 | hpvol = geber(k, hpvol_old);
|
619 | ahpvol |= 0x04;
|
620 | hpvol_old=k;
|
621 | }
|
622 |
|
623 | k = (PINC & 0x0C) >> 2;
|
624 | if(k!=reh_old)
|
625 | {
|
626 | reh = geber(k, reh_old);
|
627 | areh |= 0x04;
|
628 | reh_old=k;
|
629 | }
|
630 |
|
631 | k = (PINC & 0x30) >> 4;
|
632 | if(k!=rem_old)
|
633 | {
|
634 | rem = geber(k, rem_old);
|
635 | arem |= 0x04;
|
636 | rem_old=k;
|
637 | }
|
638 |
|
639 | k = (PINC & 0xC0) >> 6;
|
640 | if(k!=rel_old)
|
641 | {
|
642 | rel = geber(k, rel_old);
|
643 | arel |= 0x04;
|
644 | rel_old=k;
|
645 | }
|
646 |
|
647 | k = (PIND & 0x0C) >> 2;
|
648 | if((k!=ljw_old) && (k!=ljw_old2))
|
649 | {
|
650 | ljw = geber(k, ljw_old);
|
651 | aljw |= 0x04;
|
652 |
|
653 | ljw_old=k;
|
654 | }
|
655 | ljw_old2=ljw_old;
|
656 | k = (PIND & 0x30) >> 4;
|
657 | if((k!=rjw_old) && (k!=rjw_old))
|
658 | {
|
659 | rjw = geber(k, rjw_old2);
|
660 | arjw |= 0x04;
|
661 |
|
662 | rjw_old=k;
|
663 | }
|
664 | rjw_old2=rjw_old;
|
665 | k = (PIND & 0xC0) >> 6;
|
666 | if(k!=hpsel_old)
|
667 | {
|
668 | hpsel = geber(k, hpsel_old);
|
669 | if(hpsel==1)
|
670 | {
|
671 | PINB |=0x80;
|
672 | PINB &=0xBF;
|
673 | }
|
674 | if(hpsel==3)
|
675 | {
|
676 | PINB |=0x40;
|
677 | PINB &=0x7F;
|
678 | }
|
679 | ahpsel |= 0x04;
|
680 | hpsel_old=k;
|
681 | }
|
682 | }
|
683 |
|
684 | /**********************************************************************************
|
685 | * * *
|
686 | * Die ISR wird aufgerufen, sobald ein Zeichen über die USART-Schnittstelle *
|
687 | * empfangen wurde. Das empfangene Zeichen steht dann im USART-Datenregister. *
|
688 | * Empfangen werden Anforderungen zur Datenübertragung. Es ist möglich vom PC *
|
689 | * aus alle oder nur einzelne Werte neu anzufordern. Eine Neuanforderung *
|
690 | * ist nur für die Werte der Schieberegler sinnvoll, da die Drehgeber und *
|
691 | * die Taster im Normalzustand 0 sind. Das Senden wird ausgelöst durch setzen *
|
692 | * des jeweiligen Dirty-Bits. *
|
693 | * *
|
694 | *********************************************************************************/
|
695 | ISR(_VECTOR(11))
|
696 | {
|
697 | int8_t wert;
|
698 |
|
699 | wert=UDR;
|
700 |
|
701 | if (wert==0x99) //Alle Werte neu senden. Sendeanforderung durch Setzten des Dirty-Bits
|
702 | {
|
703 | alvol |= 0x04;
|
704 | alpitch |= 0x04;
|
705 | amvol |= 0x04;
|
706 | afader |= 0x04;
|
707 | arpitch |= 0x04;
|
708 | arvol |= 0x04;
|
709 | }
|
710 | else
|
711 | {
|
712 | switch (wert)
|
713 | {
|
714 | case 0x10:
|
715 | {
|
716 | alvol |= 0x04;
|
717 | break;
|
718 | }
|
719 | case 0x18:
|
720 | {
|
721 | alpitch |= 0x04;
|
722 | break;
|
723 | }
|
724 | case 0x20:
|
725 | {
|
726 | amvol |= 0x04;
|
727 | break;
|
728 | }
|
729 | case 0x28:
|
730 | {
|
731 | afader |= 0x04;
|
732 | break;
|
733 | }
|
734 | case 0x30:
|
735 | {
|
736 | arpitch |= 0x04;
|
737 | break;
|
738 | }
|
739 | case 0x38:
|
740 | {
|
741 | arvol |= 0x04;
|
742 | break;
|
743 | }
|
744 | }
|
745 | }
|
746 | }
|
747 |
|
748 |
|
749 | /**********************************************************************************
|
750 | * *
|
751 | * Der Funktion "geber" wird die Ausgabe der Drehgeber übergeben *
|
752 | * Je nach Bitkombination wird die Drehrichtung bestimmt und ein Wert *
|
753 | * zurückgegeben. Dieser Wert basiert auf dem Drehsinn eines "normalen" *
|
754 | * Drehreglers in der HiFi-Technik (links=- und rechts=+). *
|
755 | * * *
|
756 | *********************************************************************************/
|
757 | uint8_t geber(uint8_t bits_alt, uint8_t bits_neu) //Übergabe der alten und neuen Bitkombination, Datenvariable
|
758 | {
|
759 | uint8_t wert;
|
760 |
|
761 | switch(bits_alt)
|
762 | {
|
763 | case 0x00:
|
764 | {
|
765 | if(bits_neu==0x01) //Linksdrehung
|
766 | wert=1;
|
767 | else if(bits_neu==0x02) //Rechtsdrehung
|
768 | wert=3;
|
769 | else
|
770 | wert=2; //Keine Drehung
|
771 | break;
|
772 | }
|
773 |
|
774 | case 0x01:
|
775 | {
|
776 | if(bits_neu==0x03) //Linksdrehung
|
777 | wert=1;
|
778 | else if(bits_neu==0x00) //Rechtsdrehung
|
779 | wert=3;
|
780 | else
|
781 | wert=2; //Keine Drehung
|
782 | break;
|
783 | }
|
784 |
|
785 | case 0x02:
|
786 | {
|
787 | if(bits_neu==0x00) //Linksdrehung
|
788 | wert=1;
|
789 | else if(bits_neu==0x03) //Rechtsdrehung
|
790 | wert=3;
|
791 | else
|
792 | wert=2; //Keine Drehung
|
793 | break;
|
794 | }
|
795 |
|
796 | case 0x03:
|
797 | {
|
798 | if(bits_neu==0x02) //Linksdrehung
|
799 | wert=1;
|
800 | else if(bits_neu==0x01) //Rechtsdrehung
|
801 | wert=3;
|
802 | else
|
803 | wert=2; //Keine Drehung
|
804 | break;
|
805 | }
|
806 |
|
807 | default: wert=0xFF; //Nur zu Debug-Zwecken
|
808 | }
|
809 |
|
810 |
|
811 | return wert; //Rückgabe der Drehrichtung
|
812 | }
|
813 |
|
814 | /***********************************************************************************************
|
815 | * *
|
816 | * Der Funktion "taster" wird der Wert des ADC übergeben. Über ein Array, das die zu den *
|
817 | * jeweiligen Tastenkominationen gehörenden Analogwerte beinhaltet erfolgt die Auswertung *
|
818 | * Je nach Analogwert wird die Variable "taste" mit einem Wert belegt und zurückgegeben. *
|
819 | * *
|
820 | ***********************************************************************************************/
|
821 |
|
822 | uint8_t taster(uint16_t wert) //Übergabe der Datenvariable
|
823 | {
|
824 | uint16_t taste=0; //Festlegung einer Speichervariablen
|
825 | uint8_t i;
|
826 | uint16_t widerstand[32]={524,533,541,551,560,570,580,590,601,613,624,636,649,662,676,690,705,720,737,754,771,790,809,830,851,874,898,923,950,979,1009};
|
827 |
|
828 | if(wert>=512) //Folgender Block dient der Auswahl der Tasterkombination
|
829 | {
|
830 | for(i=0; i<32; i++)
|
831 | {
|
832 | if(wert <= widerstand[i])
|
833 | {
|
834 | taste=32-i;
|
835 | break;
|
836 | }
|
837 | }
|
838 | }
|
839 |
|
840 | else taste = 0x00;
|
841 |
|
842 | return taste;
|
843 | }
|
844 |
|
845 | /****************************************************************************************
|
846 | * *
|
847 | * Der Funktion "senden" wird die entsprechende Adress- und Datenvariable übergeben *
|
848 | * Unmittelbar nacheinander werden Adresse und Das High und Low-Byte der Daten- *
|
849 | * variable gesendet. Im Anschluss wird noch ein Füll-Byte übetragen, da der PC mit *
|
850 | * vier Byte besser umgehen kann. Dieses Füll-Byte zeigt zugleich auch das Ende eines *
|
851 | * Datensatzes an und kann somit zur Synchronisation verwendet werden. * *
|
852 | ****************************************************************************************/
|
853 |
|
854 | void senden (uint8_t adresse, uint16_t wert) //Übergabe der Adress- und Datenvariable
|
855 | {
|
856 | while (!( UCSRA & (1<<UDRE))); //Warten bis Daten gesendet sind
|
857 |
|
858 | UDR = adresse; //Adresse senden
|
859 |
|
860 | while (!( UCSRA & (1<<UDRE))); //Warten bis Daten gesendet sind
|
861 |
|
862 | UDR = (wert >> 8 ); //Daten HIGH senden
|
863 |
|
864 | while (!( UCSRA & (1<<UDRE))); //Warten bis Daten gesendet sind
|
865 |
|
866 | UDR = (wert & 0xFF); //Daten LOW senden
|
867 |
|
868 | while (!( UCSRA & (1<<UDRE))); //Warten bis Daten gesendet sind
|
869 |
|
870 | UDR = 'X'; //Auf 4 Byte auffüllen
|
871 | }
|