Rev 1393 Rev 1398
1 // Infracervene tykadlo IRFEE01A 1 // Infracervene tykadlo IRFEE01A
2 // ----------------------------- 2 // -----------------------------
3 // 3 //
4 // Firmware portovaný pro ATmega8 4 // Firmware portovaný pro ATmega8
5 // 5 //
6 // (c)miho@mlab.cz 6 // (c)miho@mlab.cz
7 // 7 //
8 // 1.00 - zakladni funkcni verze 8 // 1.00 - zakladni funkcni verze
9 // 1.01 - doplnena moznost s externim nastavenim parametru 9 // 1.01 - doplnena moznost s externim nastavenim parametru
10 // 1.01 ATmega8 - derivovaný firmware pro ATmega8 10 // 1.01 ATmega8 - derivovaný firmware pro ATmega8
11   11  
12 // Prirazeni portu 12 // Prirazeni portu
13 // --------------- 13 // ---------------
14 // 14 //
15 // Procesor: 15 // Procesor:
16 // 16 //
17 // ATmega8 @ 8MHz (interni RC oscilator, vypnuty preddelic 1:8) 17 // ATmega8 @ 8MHz (interni RC oscilator, vypnuty preddelic 1:8)
18 // (brown-out reset 2.7V) 18 // (brown-out reset 2.7V)
19 // HIGH 0xD9 19 // HIGH 0xD9
20 // LOW 0xD4 20 // LOW 0xD4
21 // 21 //
22 // Porty: 22 // Porty:
23 // 23 //
24 // PB3 - Ir LED Anoda proti zemi (svetlo=H) 24 // PB3 - Ir LED Anoda proti zemi (svetlo=H)
25 // PB1 - Vstup od prijimace Ir signalu (tma=H) 25 // PB1 - Vstup od prijimace Ir signalu (tma=H)
26 // PB2 - Indikacni LED a vystup (odraz=H) 26 // PB2 - Indikacni LED a vystup (odraz=H)
27 // 27 //
28 // Princip funkce: 28 // Princip funkce:
29 // 29 //
30 // Pomoci casovace 2 v rezimu CTC se na vystupu PB1 generuje signal 30 // Pomoci casovace 2 v rezimu CTC se na vystupu PB1 generuje signal
31 // o prislusnem kmitoctu (napr 34kHz). Stridavy signal se zapina 31 // o prislusnem kmitoctu (napr 34kHz). Stridavy signal se zapina
32 // a vypina (vysilaji se jednotky a nuly) a na prijimacim portu 32 // a vypina (vysilaji se jednotky a nuly) a na prijimacim portu
33 // se testuje, zda pri vysilani signalu je signal prijat a zda bez 33 // se testuje, zda pri vysilani signalu je signal prijat a zda bez
34 // vysilani signalu signal prijat neni. Pokud je splnena tato podminka, 34 // vysilani signalu signal prijat neni. Pokud je splnena tato podminka,
35 // zvysi se citac prubezne hodnoty, jinak se naopak tento citac snizi. 35 // zvysi se citac prubezne hodnoty, jinak se naopak tento citac snizi.
36 // Trvani jednoho symbolu je dano konstantnou SYMBOL_LENGTH. 36 // Trvani jednoho symbolu je dano konstantnou SYMBOL_LENGTH.
37 // 37 //
38 // Je-li dosazeno maximalni/minimalni hodnoty prubezneho citace, 38 // Je-li dosazeno maximalni/minimalni hodnoty prubezneho citace,
39 // hodnota se dale nezvysuje/nesnizuje. Pri prekroceni (velke kladne) 39 // hodnota se dale nezvysuje/nesnizuje. Pri prekroceni (velke kladne)
40 // hodnoty pro zapnuti se aktivuje vystup, pri poklesu hodnoty pod 40 // hodnoty pro zapnuti se aktivuje vystup, pri poklesu hodnoty pod
41 // spodni (mensi kladnou) mez se vystup deaktivuje. Meze jsou definovany 41 // spodni (mensi kladnou) mez se vystup deaktivuje. Meze jsou definovany
42 // konstantami SUMA_xxx. 42 // konstantami SUMA_xxx.
43 // 43 //
44 // Cilem tohoto opatreni je docilit odolnosti proti ruseni a zavedeni 44 // Cilem tohoto opatreni je docilit odolnosti proti ruseni a zavedeni
45 // hystereze tak, aby vystupni signal byl stabilni a spolehlivy. 45 // hystereze tak, aby vystupni signal byl stabilni a spolehlivy.
46 // 46 //
47   47  
48 #ifndef F_CPU 48 #ifndef F_CPU
49 #define F_CPU 8000000UL // 8MHz je maximální interní frekvence 49 #define F_CPU 8000000UL // 8MHz je maximální interní frekvence
50 #endif 50 #endif
51   51  
52 #ifndef IR_FREQUENCY 52 #ifndef IR_FREQUENCY
53 #define IR_FREQUENCY 34000UL // Frekvece IR signalu 53 #define IR_FREQUENCY 36000UL // Frekvece IR signalu
54 #endif 54 #endif
55   55  
56 #ifndef CALIBRATION 56 #ifndef CALIBRATION
57 #define CALIBRATION 0 // Zpresneni kalibrace na 9.6MHz 0=nekompenzovat 57 #define CALIBRATION 0 // Zpresneni kalibrace na 9.6MHz 0=nekompenzovat
58 #endif 58 #endif
59   59  
60 #include <avr/io.h> 60 #include <avr/io.h>
61 #include <util/delay.h> 61 #include <util/delay.h>
62 #include <avr/interrupt.h> 62 #include <avr/interrupt.h>
63   63  
64 #define SYMBOL_LENGTH 10 // Pocet period jednoho symbolu 64 #define SYMBOL_LENGTH 10 // Pocet period jednoho symbolu
65 #define SUMA_MAX 40 // Maximalni (a minimalni) pocet 65 #define SUMA_MAX 40 // Maximalni (a minimalni) pocet
66 #define SUMA_ON 30 // Pocet pro zapnuti 66 #define SUMA_ON 30 // Pocet pro zapnuti
67 #define SUMA_OFF 0 // Pocet pro vypnuti 67 #define SUMA_OFF 0 // Pocet pro vypnuti
68   68  
69   69  
70 // Zpracovani preruseni od dosazeni horni hranice citace 70 // Zpracovani preruseni od dosazeni horni hranice citace
71 // ----------------------------------------------------- 71 // -----------------------------------------------------
72 // Citac cita (automaticky a opakovane) od 0 do hodnoty v registru OCR0A 72 // Citac cita (automaticky a opakovane) od 0 do hodnoty v registru OCR0A
73 // Pri dosazeni horni meze se neguje vystupni signal na kanalu B 73 // Pri dosazeni horni meze se neguje vystupni signal na kanalu B
74 // Ma-li se vysilat tma, signal na kanalu B se neotaci ale nuluje 74 // Ma-li se vysilat tma, signal na kanalu B se neotaci ale nuluje
75 ISR(TIMER2_COMP_vect) 75 ISR(TIMER2_COMP_vect)
76 { 76 {
77 static unsigned char SymbolLen; // Citac pulperiod symbolu 77 static unsigned char SymbolLen; // Citac pulperiod symbolu
78 static unsigned char SymbolState; // Stridame 0 a 1 symboly 78 static unsigned char SymbolState; // Stridame 0 a 1 symboly
79   79  
80 static signed char InData; // Zde se strada pocet shod od dvojice symbolu 80 static signed char InData; // Zde se strada pocet shod od dvojice symbolu
81 static signed char InSuma; // Zde se prumeruji shody 81 static signed char InSuma; // Zde se prumeruji shody
82   82  
83 // Citac pulperiod symbolu 83 // Citac pulperiod symbolu
84 if(++SymbolLen>=(SYMBOL_LENGTH*2)) 84 if(++SymbolLen>=(SYMBOL_LENGTH*2-1))
85 { 85 {
86   86  
87 // Konec symbolu - zaciname citat pocet pulperiod od zacatku 87 // Konec symbolu - zaciname citat pocet pulperiod od zacatku
88 SymbolLen=0; 88 SymbolLen=0;
89   89  
90 // Cteme stav vstupu a porovnavame s ocekavanou hodnotou 90 // Cteme stav vstupu a porovnavame s ocekavanou hodnotou
91 // (1 na portu znamena tmu) 91 // (1 na portu znamena tmu)
92 if(((PINB & 0x02)>>1) ^ (SymbolState&1) ^ 1) 92 if(((PINB & 0x02)>>1) ^ (SymbolState&1) ^ 1)
93 InData++; 93 InData++;
94 else 94 else
95 InData--; 95 InData--;
96   96  
97 // Symboly 0 1 vyhodnocujeme po dvojicich 97 // Symboly 0 1 vyhodnocujeme po dvojicich
98 if(!SymbolState) 98 if(!SymbolState)
99 { 99 {
100 // Add Result 100 // Add Result
101 if (InData==2) 101 if (InData==2)
102 { 102 {
103 InSuma++; // Byla shoda u obou symbolu, zapocteme 103 InSuma++; // Byla shoda u obou symbolu, zapocteme
104 } 104 }
105 else 105 else
106 { 106 {
107 InSuma--; // Nebyla shoda u obou symbolu, odpocteme 107 InSuma--; // Nebyla shoda u obou symbolu, odpocteme
108 } 108 }
109   109  
110 // Jdeme na dalsi dvojici symbolu 110 // Jdeme na dalsi dvojici symbolu
111 InData=0; 111 InData=0;
112 } 112 }
113   113  
114 // Osetrime prubezny soucet tak, aby nepretekl 114 // Osetrime prubezny soucet tak, aby nepretekl
115 if(InSuma>SUMA_MAX) 115 if(InSuma>SUMA_MAX)
116 { 116 {
117 InSuma=SUMA_MAX; 117 InSuma=SUMA_MAX;
118 } 118 }
119 if(InSuma<-SUMA_MAX) 119 if(InSuma<-SUMA_MAX)
120 { 120 {
121 InSuma=-SUMA_MAX; 121 InSuma=-SUMA_MAX;
122 } 122 }
123   123  
124 // Vyhodnoceni prubezneho souctu 124 // Vyhodnoceni prubezneho souctu
125 if(InSuma>SUMA_ON) 125 if(InSuma>SUMA_ON)
126 { 126 {
127 PORTB |= 0x04; // Zapni vystup (je signal) 127 PORTB |= 0x04; // Zapni vystup (je signal)
128 } 128 }
129 if(InSuma<SUMA_OFF) 129 if(InSuma<SUMA_OFF)
130 { 130 {
131 PORTB &= ~0x04; // Vypni vystup (neni signal) 131 PORTB &= ~0x04; // Vypni vystup (neni signal)
132 } 132 }
133   133  
134 // Dalsi symbol 134 // Dalsi symbol
135 // Stridame 0 a 1 (tma a svetlo) 135 // Stridame 0 a 1 (tma a svetlo)
136 if(++SymbolState>=2) 136 if(++SymbolState>=2)
137 { 137 {
138 SymbolState=0; 138 SymbolState=0;
139 } 139 }
140   140  
141 // Generujeme svetlo a tmu (nastavenim casovace) 141 // Generujeme svetlo a tmu (nastavenim casovace)
142 if(SymbolState==0) 142 if(SymbolState==0)
143 { 143 {
144 TCCR2 = 0x19; // Blikej (svetlo) 144 TCCR2 = 0x19; // Blikej (svetlo)
145 } 145 }
146 else 146 else
147 { 147 {
148 TCCR2 = 0x29; // Tma (vystup casovace se jen nuluje) 148 TCCR2 = 0x29; // Tma (vystup casovace se jen nuluje)
149 } 149 }
150 } 150 }
151 } 151 }
152   152  
153 // Hlavni program 153 // Hlavni program
154 int main() 154 int main()
155 { 155 {
156 // Nastaveni prostredi behu 156 // Nastaveni prostredi behu
157 // ------------------------ 157 // ------------------------
158   158  
159 // Kompenzace vnitrniho RC oscilatoru 159 // Kompenzace vnitrniho RC oscilatoru
160 OSCCAL += CALIBRATION; 160 OSCCAL += CALIBRATION;
161   161  
162 // Nastav rezim casovace 162 // Nastav rezim casovace
163 // CTC Mod 163 // CTC Mod
164 // Toogle 164 // Toogle
165 // CLK x 1 165 // CLK x 1
166 TCCR2 = 0x19; 166 TCCR2 = 0x19;
167   167  
168 // Set frequency 168 // Set frequency
169 OCR2 = (F_CPU / IR_FREQUENCY) / 2 - 1; 169 OCR2 = (F_CPU / IR_FREQUENCY) / 2 - 1;
170 //OCR0B = 0; 170 //OCR0B = 0;
171   171  
172 // Nastav preruseni 172 // Nastav preruseni
173 TIMSK = 0x80; // Preruseni od kompare (citac proti registru OCR2) 173 TIMSK = 0x80; // Preruseni od kompare (citac proti registru OCR2)
174 //TIFR = 0; // Priznak preruseni se nuluje automaticky (HW) 174 //TIFR = 0; // Priznak preruseni se nuluje automaticky (HW)
175 sei(); // Povol globalni preruseni 175 sei(); // Povol globalni preruseni
176   176  
177 // Nastaveni vyvodu PB1 PB3 jako vystup 177 // Nastaveni vyvodu PB1 PB3 jako vystup
178 DDRB |=0x08; // PB3 vystup pro IR Led 178 DDRB |=0x08; // PB3 vystup pro IR Led
179 DDRB |=0x04; // PB2 vystup pro indikacni Led 179 DDRB |=0x04; // PB2 vystup pro indikacni Led
180   180  
181 // Hlavni program 181 // Hlavni program
182 // -------------- 182 // --------------
183 // Nedela nic, vsechno se dela v obsluze preruseni 183 // Nedela nic, vsechno se dela v obsluze preruseni
184 // od casovace. 184 // od casovace.
185   185  
186 for(;;); 186 for(;;);
187 } 187 }