1 z 7
Artykuł pochodzi ze strony XYZ HOBBY ROBOT (xyz.isgreat.org)
Kurs AVR-GCC Dekoder protokołu RC5
3.06.11 ABXYZ
Artykuł jest dodatkiem poszerzającym tematykę publikowanego na
tej stronie kursu AVR-GCC
Pilot na podczerwień to tani i prosty sposób na bezprzewodowe
sterowanie urządzeniami z bliskiej odległości. W tym artykule
opisałem jak wykonać odbiornik współpracujący ze standardowym
pilotem RC5. Funkcję dekodera protokołu RC5 będzie oczywiście
pełnił mikrokontroler- napiszemy taki programik w języku C.
Odbiornik mo\na wykorzystać do budowy ró\nych urządzeń
sterowanych pilotem.
Scalony odbiornik podczerwieni SFH5110-36
Obok pilota RC5 i mikrokontrolera AVR ATMEGA będzie potrzebny
scalony odbiornik podczerwieni SFH5110-36, układ ten jest łatwo
dostępny i kosztuje ok 3zł.
Fot. 1. SFH5110-36 Scalony odbiornik/demodulator podczerwieni
Rys.1. Podłączenie układu SFH5110-36
Rysunek poni\ej wyjaśnia sposób działania układu SFH5110-36.
Odbiornik SFH5110-36 posiada trzy wyprowadzenia: 1-wyjście
cyfrowe, 2-masa, 3-zasilanie(5V) . Normalnie na wyjściu odbiornika
SFH5110-36 jest wysoki stan napięcia, gdy odbiornik zostanie
oświetlony pilotem, na wyjściu pojawi się stan niski. Pilot świeci
diodami IR impulsowo, z częstotliwością ok 36kHz, gdy\ odbiornik
SFH5110-36 reaguje tylko na oświetlenie impulsowe o
częstotliwości 36kHz, eliminuje to wpływ zakłóceń z innych zródeł
światła.
2 z 7
Rys. 2. Zasada działania i sposób u\ycia odbiornika podczerwieni SFH5110-36.
Scalony odbiornik podczerwieni podobny do SFH5110-36 mo\na
wyciągnąć ze zu\ytego TV lub innego sprzętu. Przed wylutowaniem
trzeba tylko rozeznać do których wyprowadzeń przyłączone jest
zasilanie, a które jest wyjściem danych.
Pilot RC5
Chocia\ w ka\dym porządnym domu znajdzie się kilka pilotów na
podczerwień, to jest całkiem prawdopodobne, \e \aden nie działa
zgodnie z protokołem Philips RC5. Ale to \aden problem.
Nowiutkiego pilota RC5 kupisz na allegro w cenie ok 5..7zł. Ja
posłu\ę tu się pilotem od starego telewizora, fotka poni\ej, pilot ten
ma w środku układ scalony SAA3010P.
Fot. 2. Klasyczny pilot, pozostał mi po wymianie starego TV, w środku ma układ scalony
SAA3010P
Protokół zdalnego sterowania RC5
Wciśnięcie przycisku w pilocie RC5 skutkuje wysłaniem ramki
danych, która składa się z czternastu bitów danych. Najpierw idą
dwa bity startowe, oba zawsze mają wartości 1. Następny jest bit
kontrolny toggle, bit ten zmienia swoją wartość na przeciwną, za
ka\dym razem, kiedy naciśnięty jest któryś przycisk w pilocie.
Kolejne pięć bitów sys5..sys0 to adres systemu (urządzenia), dla TV
adres ma wartość 0. Pozostałe sześć bitów cmd4..cmd0, zawierają
numer przycisku.
3 z 7
Rys.3. Ramka danych protokołu sterowania RC5 składa się z 14 bitów.
W protokole RC5 wykorzystuje się kodowanie bitów Manchaster. Bit
o wartości 1 kodowany jest jako przejście poziomu sygnału z
niskiego na wysoki, a bit o wartości 0, jako przejście z poziomu
wysokiego na niski. W obu przypadkach zmiana poziomu sygnału
następuje w połowie czasu trwania bitu. Czas trwania ka\dego bitu
wynosi ok 1.8 milisekundy.
Rys.4. Kodowanie bitów Manchester
Pilot RC5 przesyła kolejne ramki danych w odstępie czasu nie
mniejszym ni\ okres trwania 50 bitów.
Rys.5. Odstęp pomiędzy kolejnymi ramkami danych równa się czasowi trwania 50 bitów.
Przykładowy program dekodera RC5
Program będzie dekodował komendy pilota RC5 i prezentował wynik
na siedmiu diodach LED. Sześć diod poka\e numer przycisku, a
siódma - toggle bit. Toggle bit zmienia swój stan przy ka\dym
wciśnięciu przycisku. Siedem diod LED przyłączyłem do portu D
AVRa, a odbiornik podczerwieni SFH5110-36 do PB0.
W programie wykorzystano przerwanie wywoływane przepełnieniem
timera0 - "Timer0 Overflow". Timer0 skonfigurowany jest tak, \e
przerwania występują co 32 mikrosekundy. Z ka\dym wystąpieniem
przerwania inkrementowana jest globalna zmienna "timerL", a co
256 wystąpień przerwania, inkrementowana jest globalna zmienna
"timerH". Zmienne "timerL" i "timerH" tworzą zegary, które
u\yjemy w programie do mierzenia czasu trwania impulsów i do
wymierzania odcinków czasu.
Wykrywaniem i dekodowaniem komend rc5 zajmuje siÄ™ funkcja
"detect". Funkcja "detect" uruchamiana jest w głównej pętli
programu, zwraca 12-bitowy kod komendy RC5, albo wartość -1,
jeśli w okresie 131ms nie wykryje komendy lub wystąpi błąd.
4 z 7
Na początku funkcji "detect" program odczytuje w pętli stań wejścia
uC, do którego podłączono odbiornik podczerwieni SFH5110-36,
oczekujÄ…c okresu ciszy trwajÄ…cego co najmniej 3.5ms - cisza to stan
wysoki napięcia na wyjściu SFH5110-36. Przypominam, \e
normalnie na wyjściu odbiornika SFH5110-36 jest wysoki stan
napięcia, a gdy odbiornik oświetlany jest pilotem, to na wyjściu
pojawia się stan niski. Jeśli w ciągu 131ms nie wystąpił okres ciszy
trwający 3.5ms, to funkcja kończy działanie zwracając kod -1,
oznaczający brak komendy. Następnie program oczekuje
opadającego zbocza sygnału w połowie pierwszego bitu startowego
Po wykryciu bitu startowego mierzony jest czas trwania niskiego
poziomu sygnału. Jeśli nie wykryto pierwszego bitu startowego w
okresie 131ms, albo mierzony czas trwania poziomu niskie sygnału
w pierwszym bicie startowym okazał się dłu\szy ni\ 1.1ms, to
funkcja kończy działanie zwracając kod oznaczający brak komendy.
Dalej program oczekuje opadającego zbocza w środku drugiego bitu
startowego. Funkcja wykorzystuje opadajÄ…ce lub rosnÄ…ce zbocze
sygnału w połowie ka\dego bitu do synchronizacji. Odczyt wartości
kolejnego bitu ramki dokonuje siÄ™ po okresie 3/4 czasu trwania bitu
od momentu wykrycia zbocza w środku poprzedniego bitu.
Odczytana wartość bitu zachowywana jest w zmiennej. Dalej, jeśli
odczytano wartość bitu 1, to program oczekuje wystąpienia zbocza
opadającego w środku bitu, a jeśli odczytano wartość bitu 0, zbocza
narastającego. W momencie wykrycia krawędzi w środku bitu
następuje wyzerowanie timera i cała akcja jest powtarzana dla
kolejnego bitu. Jeśli program nie wykryje odpowiedniego zbocza w
okresie 5/4 czasu trwania bitu od momentu poprzedniej
synchronizacji, to funkcja kończy działanie z błędem.
Rys. 6. Próbkujemy po 3/4 czasu trwania bitu od momentu wykrycia zbocza sygnału w
połowie poprzedniego bitu.
A oto nasz programik, całość w jednym pliku.
//---------------------------------------------------------------
// Plik "main.c"
//
// KURS AVR-GCC (abxyz.bplaced.net)
//
// Dekoder RC5
//
// (schemat i opis działania w artykule)
// testowanie na atmega8 (8MHz)
//---------------------------------------------------------------
#include
#include
#include
5 z 7
// Odbiornik podczerwieni SFH5110 przyłączona do portu PB0
#define RC5_IN (PINB & (1<<0))
//
typedef unsigned char u8;
;
;
;
typedef unsigned int uint;
;
;
;
// Zmienne globalne pełnią rolę programowych zegarów
// napędzanych przerwaniem TIMER0_OVF
volatile u8 timerL;
;
;
;
volatile u8 timerH;
;
;
;
//---------------------------------------------------------------
// Funkcja konfiguruje i uruchamia Timer0
// oraz włącza przerwanie od przepełnienia timera,
// przerwanie powinno występować co 32us.
//---------------------------------------------------------------
void init_rc5()
()
()
()
{
{
{
{
//atmega8
TCCR0 = (1<= ( << );
= ( << );
= ( << );
TIMSK = (1<= ( << );
= ( << );
= ( << );
/*
//atmega88
TCCR0B = (1< TIMSK0 = (1<*/
// Zezwala na przerwania
sei();
();
();
();
}
}
}
}
//---------------------------------------------------------------
// Procedura obsługi przerwania Timer0 Overflow"
//---------------------------------------------------------------
ISR(TIMER0_OVF_vect)
( )
( )
( )
{
{
{
{
volatile static u8 inttemp;
;
;
;
// zmienna timerL zwiększa się co 32us
timerL++;
++;
++;
++;
// zmienna timerH zwiększa się co 8.192ms (32us*256)
inttemp++;
++;
++;
++;
if(!inttemp ) timerH++;
(! ) ++;
(! ) ++;
(! ) ++;
}
}
}
}
//---------------------------------------------------------------
// Funkcja wykrywa i dekoduje komendÄ™ pilota RC5
//---------------------------------------------------------------
uint detect()
()
()
()
{
{
{
{
u8 temp;
;
;
;
u8 ref1;
;
;
;
u8 ref2;
;
;
;
u8 bitcnt;
;
;
;
uint command;
;
;
;
timerH = 0;
= ;
= ;
= ;
timerL = 0;
= ;
= ;
= ;
// Czeka na okres ciszy na linii wejścia uC trwający 3.5ms
// Jeśli nie wykryje takiego okresu ciszy w ciągu 131ms,
// to kończy działanie funkcji z błędem
while( timerL<110)
( < )
( < )
( < )
{
{
{
{
if(timerH>=16) return command = -1;
( >= ) = - ;
( >= ) = - ;
( >= ) = - ;
if(!RC5_IN) timerL = 0;
(! ) = ;
(! ) = ;
(! ) = ;
}
}
}
}
// Czeka na pierwszy bit startowy.
// Jeśli nie wykryje bitu startowego w ciągu 131ms,
// to kończy działanie funkcji z błędem
while(RC5_IN)
( )
( )
( )
if(timerH>=16) return command = -1 ;
( >= ) = - ;
( >= ) = - ;
( >= ) = - ;
// Pomiar czasu trwani niskiego poziom syganłu
// w pierwszym bicie startowym.
// Jeśli nie wykryje rosnącego zbocza sygnału w ciągu
6 z 7
// 1ms, to kończy działanie funkcji z błędem
timerL = 0;
= ;
= ;
= ;
while(!RC5_IN)
(! )
(! )
(! )
if(timerL>34) return command = -1;
( > ) = - ;
( > ) = - ;
( > ) = - ;
//
temp = timerL;
= ;
= ;
= ;
timerL = 0;
= ;
= ;
= ;
// ref1 - oblicza 3/4 czasu trwania bitu
ref1 =temp+(temp>>1);
= +( >> );
= +( >> );
= +( >> );
// ref2 - oblicza 5/4 czasu trwania bitu
ref2 =(temp<<1)+(temp>>1);
=( << )+( >> );
=( << )+( >> );
=( < < )+( >> );
// Oczekuje na zbocze opadające sygnału w środku drugiego
// bitu startowego.
// Jeśli nie wykryje zbocza w ciągu 3/4 czasu trwania
// bitu, to kończy działanie funkcji z błędem
while(RC5_IN)
( )
( )
( )
if(timerL > ref1) return command = -1;
( > ) = - ;
( > ) = - ;
( > ) = - ;
// W momencie wykrycia zbocza sygnału, synchronizuje
// zmieną timerL dla próbkowania bitu toggle
timerL = 0;
= ;
= ;
= ;
// Odczytuje dekoduje pozostałe 12 bitów polecenia rc5
for(bitcnt=0, command = 0; bitcnt <12; bitcnt++)
( = , = ; < ; ++)
( = , = ; < ; ++)
( = , = ; < ; ++)
{
{
{
{
// Czeka 3/4 czasu trwania bitu od momentu wykrycia
// zbocza sygnału w połowie poprzedniego bitu
while(timerL < ref1) {};
( < ) {};
( < ) {};
( < ) {};
// Próbkuje - odczytuje port we uC
if(!RC5_IN)
(! )
(! )
(! )
{
{
{
{
// Jeśli odczytano 0, zapamiętuje w zmiennej
// "command" bit o wartości 0
command <<= 1 ;
<<= ;
<<= ;
<<= ;
// Oczekuje na zbocze rosnące sygnału w środku bitu.
// Jeśli nie wykryje zbocza w ciągu 5/4 czasu trwania
// bitu, to kończy działanie funkcji z błędem
while(!RC5_IN)
(! )
(! )
(! )
if(timerL > ref2) return command = -1;
( > ) = - ;
( > ) = - ;
( > ) = - ;
}
}
}
}
else
{
{
{
{
// Jeśli odczytano 1, zapamiętuje w zmiennej
// "command" bit o wartości 1
command = (command <<1 ) | 0x01;
= ( << ) | ;
= ( << ) | ;
= ( << ) | ;
// Oczekuje na zbocze opadające sygnału w środku bitu.
// Jeśli nie wykryje zbocza w ciągu 5/4 czasu trwania
// bitu, to kończy działanie funkcji z błędem
while(RC5_IN)
( )
( )
( )
if(timerL > ref2) return command = -1;
( > ) = - ;
( > ) = - ;
( > ) = - ;
}
}
}
}
// W momencie wykrycia zbocza sygnału, synchronizuje
// zmieną timerL dla próbkowania kolejnego bitu
timerL = 0;
= ;
= ;
= ;
}
}
}
}
// Zwraca kod polecenia rc5
// bity 0..5 numer przycisku
// bity 6..10 kod systemu(urzÄ…dzenia)
// bit 11 toggle bit
return command;
;
;
;
}
}
}
}
//---------------------------------------------------------------
// GLÓWNA FUNKCJA PROGRAMU
//---------------------------------------------------------------
int main(void)
( )
( )
( )
{
{
{
{
//
uint cmd;
;
;
;
u8 out;
;
;
;
7 z 7
// Porty PD0..PD6 wyjściami - diody LED
DDRD = 0x7f;
= ;
= ;
= ;
PORTD = 0x00;
= ;
= ;
= ;
// uruchamia Timer0 i przerwanie
init_rc5();
();
();
();
while (1)
( )
( )
( )
{
{
{
{
// Wykrywa i dekoduje polecenie pilota RC5
cmd = detect();
= ();
= ();
= ();
// Jeśli odebrano komendę
if(cmd != -1)
( != - )
( != - )
( != - )
{
{
{
{
// Na sześciu diodach LED poka\e numer polecenia rc5,
// a na siódmej LED - toggle bit
out = (cmd & (1<<11)) >> 5;
= ( & ( << )) >> ;
= ( & ( << )) >> ;
= ( & ( << )) >> ;
out |= cmd & 0x3f;
|= & ;
|= & ;
|= & ;
PORTD = (out);
= ( );
= ( );
= ( );
}
}
}
}
}
}
}
}
return 0;
;
;
;
}
}
}
}
Listing 1 Program dekodera RC5
Wa\ne! Program przeznaczony jest dla uC atmega8 taktowanego
zegarem 8MHz. W przypadku, gdy mikrokontroler ma pracować
z częstotliwością inną ni\ 8MHz, to program będzie wymagał
drobnego dopasowania. Jeśli masz z tym problem, pytaj na forum.
Katalog z plikami projektu mo\na pobrać klikając w link
dekoder_rc5.zip. Kod wynikowy programu ma wielkość 400 bajtów.
Pisząc niniejszy artykuł opierałem się na atmelowskiej nocie
aplikacyjnej AVR410 doc1473.pdf.
3.06.11 ABXYZ
Copyright © 2009-2011 ABXYZ - Wszelkie prawa zastrze\one
Wyszukiwarka
Podobne podstrony:
Kurs AVR GCC cz 5
Kurs AVR GCC, cz 3
Kurs AVR GCC Wyświetlacz LCD od Nokii310
Kurs AVR GCC cz 2
XYZ Hobby Robot Kurs AVR GCC Gamepad od PlayStation
Kurs AVR GCC cz 3
Kurs AVR GCC cz 1
Kurs AVR GCC, cz 1
Kurs AVR GCC, cz 5
Kurs AVR GCC, cz 4
Kurs AVR GCC, cz 2
Kurs AVR GCC cz 4
Using the EEPROM memory in AVR GCC
AVR GCC w Linuksie przykład instalacji ze źródeł
AVR GCC kompilator C dla mikrokontrolerów AVR, część 12
AVR GCC kompilator C dla mikrokontrolerów AVR, część 11
więcej podobnych podstron