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