main.c


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
    }