0,0 → 1,173 |
// Infracervene tykadlo IRFEE01A |
// ----------------------------- |
// |
// (c)miho@mlab.cz |
// |
// 1.00 - zakladni funkcni verze |
|
// Prirazeni portu |
// --------------- |
// |
// Procesor: |
// |
// ATtiny13 @ 9.6MHz (interni RC oscilator, vypnuty preddelic 1:8) |
// |
// Porty: |
// |
// PB1 - Ir LED Anoda proti zemi (svetlo=H) |
// PB3 - Vstup od prijimace Ir signalu (tma=H) |
// PB4 - Indikacni LED a vystup (odraz=H) |
// |
// Princip funkce: |
// |
// Pomoci casovace v rezimu CTC se na vystupu PB1 generuje signal |
// o prislusnem kmitoctu (napr 34kHz). Stridavy signal se zapina |
// a vypina (vysilaji se jednotky a nuly) a na prijimacim portu |
// se testuje, zda pri vysilani signalu je signal prijat a zda bez |
// vysilani signalu signal prijat neni. Pokud je splnena tato podminka, |
// zvysi se citac prubezne hodnoty, jinak se naopak tento citac snizi. |
// Trvani jednoho symbolu je dano konstantnou SYMBOL_LENGTH. |
// |
// Je-li dosazeno maximalni/minimalni hodnoty prubezneho citace, |
// hodnota se dale nezvysuje/nesnizuje. Pri prekroceni (velke kladne) |
// hodnoty pro zapnuti se aktivuje vystup, pri poklesu hodnoty pod |
// spodni (mensi kladnou) mez se vystup deaktivuje. Meze jsou definovany |
// konstantami SUMA_xxx. |
// |
// Cilem tohoto opatreni je docilit odolnosti proti ruseni a zavedeni |
// hystereze tak, aby vystupni signal byl stabilni a spolehlivy. |
// |
|
#define F_CPU 9600000UL // 9.6MHz je maximální frekvence pro ATtiny |
#define IR_FREQUENCY 36000UL // Frekvece IR signalu |
#define CALIBRATION -2 // Zpresneni kalibrace na 9.6MHz 0=nekompenzovat |
|
#include <avr/io.h> |
#include <util/delay.h> |
#include <avr/interrupt.h> |
|
#define SYMBOL_LENGTH 10 // Pocet period jednoho symbolu |
#define SUMA_MAX 40 // Maximalni (a minimalni) pocet |
#define SUMA_ON 30 // Pocet pro zapnuti |
#define SUMA_OFF 0 // Pocet pro vypnuti |
|
|
// Zpracovani preruseni od dosazeni horni hranice citace |
// ----------------------------------------------------- |
// Citac cita (automaticky a opakovane) od 0 do hodnoty v registru OCR0A |
// Pri dosazeni horni meze se neguje vystupni signal na kanalu B |
// Ma-li se vysilat tma, signal na kanalu B se neotaci ale nuluje |
ISR(TIM0_COMPA_vect) |
{ |
static unsigned char SymbolLen; // Citac pulperiod symbolu |
static unsigned char SymbolState; // Stridame 0 a 1 symboly |
|
static signed char InData; // Zde se strada pocet shod od dvojice symbolu |
static signed char InSuma; // Zde se prumeruji shody |
|
// Citac pulperiod symbolu |
if(++SymbolLen>=(SYMBOL_LENGTH*2)) |
{ |
|
// Konec symbolu - zaciname citat pocet pulperiod od zacatku |
SymbolLen=0; |
|
// Cteme stav vstupu a porovnavame s ocekavanou hodnotou |
// (1 na portu znamena tmu) |
if(((PINB & 0x10)>>4) ^ (SymbolState&1) ^ 1) |
InData++; |
else |
InData--; |
|
// Symboly 0 1 vyhodnocujeme po dvojicich |
if(!SymbolState) |
{ |
// Add Result |
if (InData==2) |
{ |
InSuma++; // Byla shoda u obou symbolu, zapocteme |
} |
else |
{ |
InSuma--; // Nebyla shoda u obou symbolu, odpocteme |
} |
|
// Jdeme na dalsi dvojici symbolu |
InData=0; |
} |
|
// Osetrime prubezny soucet tak, aby nepretekl |
if(InSuma>SUMA_MAX) |
{ |
InSuma=SUMA_MAX; |
} |
if(InSuma<-SUMA_MAX) |
{ |
InSuma=-SUMA_MAX; |
} |
|
// Vyhodnoceni prubezneho souctu |
if(InSuma>SUMA_ON) |
{ |
PORTB |= 0x08; // Zapni vystup (je signal) |
} |
if(InSuma<SUMA_OFF) |
{ |
PORTB &= ~0x08; // Vypni vystup (neni signal) |
} |
|
// Dalsi symbol |
// Stridame 0 a 1 (tma a svetlo) |
if(++SymbolState>=2) |
{ |
SymbolState=0; |
} |
|
// Generujeme svetlo a tmu (nastavenim casovace) |
if(SymbolState==0) |
{ |
TCCR0A = 0x12; // Blikej (svetlo) |
} |
else |
{ |
TCCR0A = 0x22; // Tma (vystup casovace se jen nuluje) |
} |
} |
} |
|
// Hlavni program |
int main() |
{ |
// Nastaveni prostredi behu |
// ------------------------ |
|
// Kompenzace vnitrniho RC oscilatoru |
OSCCAL += CALIBRATION; |
|
// Nastav rezim casovace |
// CTC Mod |
// Toogle B |
// CLK x 1 |
TCCR0A = 0x12; |
TCCR0B = 0x01; |
|
// Set frequency |
OCR0A = (F_CPU / IR_FREQUENCY) / 2 - 1; |
//OCR0B = 0; |
|
// Nastav preruseni |
TIMSK0 = 4; // Preruseni od kompare na A (citac proti registru OCR0A) |
//TIFR0 = 0; // Priznak preruseni se nuluje automaticky (HW) |
sei(); // Povol globalni preruseni |
|
// Nastaveni vyvodu PB1 PB3 jako vystup |
DDRB |=0x02; // PB1 vystup pro IR Led |
DDRB |=0x08; // PB3 vystup pro indikacni Led |
|
// Hlavni program |
// -------------- |
// Nedela nic, vsechno se dela v obsluze preruseni |
// od casovace. |
|
for(;;); |
} |