1 | /************************************************************************************************************
|
2 | / Name: - Motorola Code Empfänger -
|
3 | / Funktion: Mit dem Programm kann der Infrarot Code, der von Grundig und Kathrein TV Geräten verwendet wird
|
4 | decodiert werden.
|
5 |
|
6 | / Hardware: ATMEGA8 mit ext. 16MHz Quarz eine IR Empängerdiode TSOP1736 (aktiv low) am ext. Interrupteingang PD2
|
7 |
|
8 | / Software: Verwendet wird ein Interrupteingang, welcher die erste Flanke eines Paketes erkennt und der 16 bit Timer 1, welcher
|
9 | welcher im CTC Mode arbeitet. Bei jedem Compare Match wird der Pegel des Einganges abegefragt. Die neun Datenbits
|
10 | werden dann nacheinander in eine 16 Bit Variable geschoben. Nachdem die Datenbits in der Variable sind wird ge-
|
11 | prüft ob es sich um ein gültiges Datenpaket handelt oder ob es sich um eine Start-Stop bedingung handelt.
|
12 |
|
13 | / Motorola Code: Das Protokoll des Motrola Codes besteht aus min. 3 Datenpaketen. Diese haben immer die gleiche Gestalt,
|
14 | d.h. jedes Paket besteht aus einem Prebit, einem Startbit und neun Datenbits. Eine Nachricht besteht aus einem
|
15 | Startpaket, Datenpaket(en) und dem Stoppaket. Die Datenpakete werden so lange wiederholt, wie die Taste der
|
16 | Fernbedienung gedrückt wirt. Start- und Stoppaket sind identisch und haben jeweils neun Datenbits.
|
17 |
|
18 | / Autor: Andreas K.
|
19 | / Datum: 16.07.08
|
20 | **************************************************************************************************************/
|
21 |
|
22 |
|
23 | #define __STDIO_FDEVOPEN_COMPAT_12 //macht fdevopen() kopatibel zur alten Version mit 3 Argumenten
|
24 |
|
25 | #include <stdio.h> //Standartfunktionen für Ein- und Ausgabe
|
26 | #include <avr/pgmspace.h> //Strings aus dem Flashspeicher ausgeben
|
27 | #include <inttypes.h> // u.a. Definition der Formatspezifizierer
|
28 | #include <ctype.h> //Funktionen zum Testen von Zeichen
|
29 | #include <avr/interrupt.h>
|
30 | #include <stdlib.h> //Umwandlungsfuntionen
|
31 | // #include <avr/signal.h> //C-Funktionen für die Interruptverarbeitung. Es gibt aber eine neuere Version "interrupt.h" die "signal.h" ersetzen soll
|
32 | #include <string.h> //Funktionen für Zeichenketten
|
33 |
|
34 |
|
35 | #define CTC_PREBIT_STARTBIT 76 // 190
|
36 | #define CTC_ONE_DATABIT 16 // 239
|
37 | #define START_STOP 511 // Code des Start- & Stoppaketes
|
38 | #define DATENBITS 9 // Anzahl der Datenbits in einem Datenpakets
|
39 | #define MASK 0x04 // Maske um ext. Interrupteingang herauszumaskieren
|
40 | #define INT PD2 // ext. Interrupteingang
|
41 |
|
42 |
|
43 |
|
44 | #include "uart_kompakt.c"
|
45 | #include "uart_kompakt.h"
|
46 |
|
47 | //Interrupt Routinen
|
48 | SIGNAL (SIG_OUTPUT_COMPARE1A);
|
49 | SIGNAL (SIG_INTERRUPT0);
|
50 |
|
51 | void moto_code_init(void);
|
52 |
|
53 | //globale Variablen
|
54 | volatile uint16_t data_tmp = 0;
|
55 | volatile uint8_t data_complete = 0;
|
56 | volatile uint8_t bitzaehler = 0;
|
57 | volatile uint16_t data_paket = 0; //enthält den Datencode einer gedrückten Taste
|
58 |
|
59 | int main(void)
|
60 | {
|
61 |
|
62 | DDRC |= (1<<DDC5); //Testausgang
|
63 |
|
64 | sei(); //globale Interruptfreigabe
|
65 | uartInit(); //Initialisierung der UART
|
66 | moto_code_init();
|
67 |
|
68 |
|
69 | //öffnet einen Ausgabekanal für printf
|
70 | fdevopen (uart_putchar0, NULL,0); // alte Version
|
71 | // fdevopen (uart_putchar0, NULL); // neue Version
|
72 |
|
73 | uart_putstring0("Motorola Code");
|
74 |
|
75 | //Endlosschleife
|
76 | while(1)
|
77 | {
|
78 |
|
79 | if(data_complete) //wenn gültiges Datenpaket vorhanden
|
80 | {
|
81 | //PORTC ^= (1<<PC5);
|
82 | printf(" %d\t",data_paket);
|
83 |
|
84 | switch (data_paket)
|
85 | {
|
86 | case 16: //Taste "0" mache was
|
87 | break;
|
88 | case 17: //Taste "1" mache was
|
89 | break;
|
90 | case 18: //Taste "2" mache was
|
91 | break;
|
92 | case 19: //Taste "3" mache was
|
93 | break;
|
94 | case 20: //Taste "4" mache was
|
95 | break;
|
96 | case 21: //Taste "5" mache was
|
97 | break;
|
98 | case 22: //Taste "6" mache was
|
99 | break;
|
100 | case 23: //Taste "7" mache was
|
101 | break;
|
102 | case 24: //Taste "8" mache was
|
103 | break;
|
104 | case 25: //Taste "9" mache was
|
105 | PORTC ^= (1<<PC5);
|
106 | break;
|
107 | }
|
108 | data_complete = 0;
|
109 | }
|
110 | }
|
111 | return 0;
|
112 | }
|
113 |
|
114 | //************************************************************************
|
115 |
|
116 | SIGNAL (SIG_INTERRUPT0)
|
117 | {
|
118 | GICR &= ~(1<<INT0); //kein ext. int
|
119 | OCR1A = CTC_PREBIT_STARTBIT; //4.125 ms bis Match
|
120 | TCCR1B |= (1 << WGM12) |(1 << CS12) | (1 << CS10); //CTC, prescaler 1024
|
121 | TIMSK |= (1<<OCIE1A); //enable Compare Match Inteerrupt
|
122 |
|
123 | }
|
124 |
|
125 | SIGNAL (SIG_OUTPUT_COMPARE1A)
|
126 | {
|
127 | data_tmp |= (uint16_t)(((PIND & MASK)>>INT)<<(bitzaehler)); // Pegel ausmaskieren und von rechts in Variable schieben
|
128 | bitzaehler++;
|
129 | OCR1A = CTC_ONE_DATABIT; //1.0626 ms bis Match
|
130 |
|
131 | if (bitzaehler == DATENBITS) // wenn alle Datenbits da
|
132 | {
|
133 | TCCR1B = 0; //T1 stop
|
134 | bitzaehler = 0;
|
135 | if (data_tmp != START_STOP) //Start_Stop Paket?
|
136 | {
|
137 | data_complete = 1;
|
138 | data_paket = data_tmp;
|
139 | }
|
140 | data_tmp = 0;
|
141 | GICR |= (1<<INT0); // ext. int freigabe, warte auf nächstes Datenpaket
|
142 | TIMSK &= ~(1<<OCIE1A); // disable timer interrupt
|
143 | }
|
144 | }
|
145 |
|
146 | void moto_code_init(void)
|
147 | {
|
148 | DDRD &= ~(1<<DDD2); //ext. Interrupteingang
|
149 |
|
150 | //ext. Interrupt Eintellungen
|
151 | MCUCR |= (1<<ISC01); // fallende Flanke
|
152 | GICR |= (1<<INT0); // freibabe INT0
|
153 |
|
154 | }
|