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