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