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