Sprzętowy dekoder protokołu RC5

Transkrypt

Sprzętowy dekoder protokołu RC5
Sprzętowy dekoder RC5
1
Sprzętowy dekoder protokołu RC5
Współcześnie, w większości przypadków, dekodowanie sygnałów zdalnego sterowania
realizowane jest w sposób programowy z wykorzystaniem mikrokontrolerów. Alternatywnie, do
dekodowania poszczególnych protokołów zdalnego sterowania można zastosować rozwiązania
całkowicie sprzętowe. Dzięki zastosowaniu współcześnie bardzo dynamicznie rozwijających się układów
programowalnych i komputerowych narzędzi syntezy logicznej jest to zadanie stosunkowo
nieskomplikowane (w porównaniu z klasycznymi metodami projektowania i realizacji układów
cyfrowych z wykorzystaniem „katalogowych” układów scalonych) i tanie w realizacji.
W niniejszym opracowaniu przedstawiono sprzętowy dekoder protokołu RC5, z interfejsem
równoległym oraz szeregowym interfejsem kompatybilnym z SPI, opisany w języku Verilog i
zrealizowany z wykorzystaniem układów CPLD firmy Xilinx.
Dekodowanie protokołu RC5
W protokole RC5 do kodowania przesyłanych bitów stosowany jest kod Manchester. Czas trwania
bitu jest stały i wynosi 1.778ms. Bit o wartości logicznej 1 kodowany jest jako zmiana poziomu sygnału z
niskiego na wysoki (zbocze narastające) w połowie czasu trwania bitu. Bit o wartości logicznej 0
kodowany jest jako zmiana poziomu sygnału z wysokiego na niski (zbocze opadające) również w
połowie czasu trwania bitu. Inaczej można też powiedzieć, że jedynka logiczna kodowana jest jako
kolejno: przerwa o czasie trwania równym połowie czasu trwania bitu, czyli 889µs i impulsu o
identycznym czasie trwania. Podobnie zero logiczne kodowane jest jako kolejno: impuls o długości
889µs (połowa czasu trwania bitu) oraz przerwa o takim samym czasie trwania.
1
1
1
0
0
1
0
1
1
0
0
1
1
0
S1
S2
T
A4
A3
A2
A1
A0
C5
C4
C3
C2
C1
C0
Rys. 2. Ramka danych protokołu RC5.
Na rys. 2 przedstawiono przykładową ramkę danych protokołu RC5. Pierwsze dwa przesyłane
bity S1 i S2 to bity startowe, których wartość logiczna zawsze równa jest 1. Kolejnym, trzecim
przesyłanym bitem jest bit T informujący o przytrzymaniu klawisza w pilocie zdalnego sterowania. Bit
ten zmienia swoją wartość na przeciwną, za każdym razem, kiedy naciskany jest klawisz w pilocie
(wysyłane jest polecenie). W przypadku, kiedy klawisz w pilocie przytrzymany zostanie dłużej, kolejno
wysyłane są identyczne ramki danych w odpowiednich odstępach czasowych – bit T nie jest wówczas
cyklicznie negowany i ma cały czas stałą wartość. Kolejne przesyłane bity A4...A0 to bity adresu
urządzenia RC5. Ostatnie 6 bitów ramki danych C0...C5 stanowią bity kodu polecenia.
Ponieważ protokół RC5 wykorzystuje kodowanie Manchester, dlatego też do jego dekodowania
można zastosować metody identyczne jak dla tego kodu. Dekodowanie kodu Manchester realizowane jest
bądź z użyciem układów czasowych, bądź automatu synchronicznego.
Na rys. 3 przestawiono ideę dekodowania protokołu RC5 z wykorzystaniem układu czasowego.
Układ różniczkujący wytwarza impulsy przy każdej zmianie sygnału wejściowego. Impulsy te wyzwalają
monowibrator (generator monostabilny), który generuje impulsy o szerokości równej 3/4 czasu trwania
bitu w protokole RC5 (ok. 1.3ms). Jeżeli następny impuls wyzwalający (następne zbocze) pojawi się
wówczas, gdy monowibrator nie zakończył jeszcze generowania impulsu, to powtórne wyzwolenie mo-
Sprzętowy dekoder RC5
2
nowibratora nie nastąpi. Zanegowane impulsy monowibratora stanowią sygnał zegarowy taktujący przerzutnik D, na którego wyjściu Q występują wartości zdekodowanych bitów.
D
układ
różniczkujący
A
B
SET
Q
C
monowibrator
CLR
Q
wy
zegar
1
0
1
1
0
0
A
B
C
3/4T
wy
T
Rys. 3. Ilustracja idei dekodowania protokołu RC5 z wykorzystaniem układu czasowego
sp
START, 1
S0
S1
sg, 1
lg, 1
lp, 0
sg
S2
S3
sp, 0
Rys. 4. Graf automatu dekodowania protokołu RC5
Na rys. 4 przedstawiono graf automatu (inaczej graf przejść i wyjść dla modelu automatu
Mealy’ego), wykorzystywanego do dekodowania protokołu RC5. Etykiety opisujące łuki oznaczają
odpowiednio rodzaj zdarzenia, oraz po przecinku wartość logiczną zdekodowanego bitu. Zdarzenia
opisane są następującymi symbolami:
sp – krótki impuls,
sg – krótka przerwa,
lp – długi impuls,
lg – długa przerwa.
Zdarzenia te sklasyfikowane są w sposób podany w tabeli (czas podany w mikrosekundach).
zdarzenie
sp
sg
lp
lg
ideał
889
889
1778
1778
min
444
444
1334
1334
max
1333
1333
2222
2222
Automat rozpoczyna swoje działanie od stanu S0, przy czym wejście do tego stanu powodowane
jest pojawieniem się zbocza narastającego dekodowanego sygnału i jednocześnie oznacza, że odebrany
został pierwszy bit o wartości logicznej 1. Następnie dekodowanych jest pozostałych 13 bitów (odebranie
kolejno 14 bitów stanowi warunek zatrzymania automatu). Każde inne występujące zdarzenie, nie
opisane grafem z rys. 4, traktowane jest jako błąd, powodujący przerwanie działania automatu
Sprzętowy dekoder RC5
3
Sprzętowy dekoder RC5 wykorzystujący układ czasowy
Na rys. 5 przedstawiony został bardziej szczegółowy schemat implementacji dekodera protokołu
RC5 wykorzystującego układ czasowy.
1MHz
REJESTR PRZESUWNY
LICZNIK 11bit
A0..A4
C0..C5
T
S0
INTERFEJS
SPI
DET 0
IN
DETEKTOR
1/0
0/1
LICZNIK 3bit
STEROWANIE
SCK
CS
RDY
Rys. 5. Schemat blokowy dekodera RC5 z wykorzystaniem układu czasowego
Dekoder składa się tutaj z:
• detektora zboczy wykrywającego zmiany poziomu sygnału z 1 na 0 oraz z 0 na 1,
• 3 – bitowego licznika zliczającego ilość pojawiających się zboczy sygnału wejściowego w momencie
gdy odmierzany jest czas przez licznik 11 – bitowy,
• 11 – bitowego licznika z wpisem równoległym liczącego wstecz, służącego do odmierzania czasu
3/4T (T – czas trwania bitu w protokole RC5),
• detektora (komparatora) wykrywającego stan osiągnięcia przez licznik wartości 0,
• 14 – bitowego rejestru przesuwnego zapamiętującego w odpowiednich chwilach czasu
(wyznaczonych przez układ sterowania i licznik 11 – bitowy) stan wejścia dekodera (wyjścia
odbiornika podczerwieni),
• układu sterowania.
Opcjonalnie dekoder może być wyposażony w interfejs kompatybilny z SPI, służący do szeregowej
wymiany danych np. z mikrokontrolerem.
Układ sterowanie realizuje następujące funkcje:
• Na podstawie informacji z detektora zboczy steruje pracą licznika 11 – bitowego: w momencie
wystąpienia zbocza do tego licznika ładowana jest wartość stałej czasowej odpowiadająca 3/4T. Jeżeli
pojawi się kolejne zbocze sygnału wejściowego w momencie, gdy licznik nie zakończy jeszcze
odmierzania czasu 3/4T od momentu wystąpienia poprzedniego zbocza (licznik nie osiągnie jeszcze
stanu 0), wówczas powtórne załadowanie stałej czasowej do licznika nie nastąpi.
• Sprawdza ilość występujących zboczy sygnału wejściowego (za pośrednictwem licznika 3 –
bitowego), w czasie gdy licznik 11 – bitowy odmierza czas 3/4T. Wystąpienie w tym czasie więcej
niż jednego zbocza sygnału wejściowego układ sterowania interpretuje jako błąd (dekodowany
protokół nie jest protokołem RC5) i wznawia proces dekodowania od początku (zerowana jest
zawartość rejestru przesuwnego).
• Na podstawie informacji z detektora osiągnięcia przez licznik 11 – bitowy wartości 0, kieruje pracą
rejestru przesuwnego wyznaczając moment próbkowania stanu sygnału wejściowego.
• Jeżeli od momentu ostatniego zakończenia odmierzania czasu 3/4T upłynął czas dłuższy niż 3/4T
układ sterowania interpretuje taką sytuację jako błąd (normalnie w protokole RC5 następne zbocze
powinno pojawić się po czasie 1/4T) i proces dekodowania rozpoczynany jest od początku. W celu
wyznaczenia momentu przekroczenia czasu oczekiwania na zbocze układ sterujący odpowiednio
steruje pracą licznika 11 – bitowego: licznik automatycznie ładowany jest wartością stałej czasowej
3/4T, w momencie gdy osiągnie stan 0 (czyli, gdy ukończy odmierzanie poprzedniej wartości 3/4T).
Sprzętowy dekoder RC5
•
4
Określa moment zakończenia dekodowania ramki protokołu RC5 ustawiając na pewien czas (3/4T)
wyjście RDY. Aby określić moment zakończenia dekodowania (odebranie wszystkich 14 – stu bitów)
układ sterowania analizuje stan najstarszego bitu (najbardziej znaczącego) wyjścia w rejestrze przesuwnym. Jeżeli bit ten ma wartość 1, wówczas oznacza to zakończenie procesu dekodowania.
W celu implementacji sprzętowej tak zdefiniowanego dekodera RC5, z zastosowaniem narzędzi EDA
i języków HDL najlepiej posłużyć się opisem mieszanym: strukturalno – behawioralnym. Strukturę
dekodera określa sposób połączenia poszczególnych bloków funkcjonalnych, podczas gdy działanie tych
bloków można opisać behawioralnie.
Podstawową jednostką projektową w języku Verilog jest tzw. moduł. Może więc on zawierać opis
behawioralny działania poszczególnych bloków z rys. 5. Jednak w przedstawionym na listingu 1 kodzie
specyfikującym działanie dekodera RC5 wygodniej było zintegrować bloki: detektora zboczy, licznika 3
– bitowego, detektora osiągnięcia przez licznik 11 – bitowy stanu zerowego, rejestru przesuwnego oraz
układu sterowania – w module głównym dekodera. Osobny moduł zawiera jedynie definicję działania
bloku licznika 11 bitowego.
W przedstawionym kodzie, celem zmniejszenia niezbędnych do implementacji zasobów sprzętowych
układu programowalnego, zredukowano do 2 liczbę bitów licznika zliczającego ilość pojawiających się
zboczy sygnału wejściowego w czasie gdy odmierzany jest czas 3/4T (co jednak wiąże się ze
zmniejszeniem skuteczności wykrywania opisanych sytuacji, ale w praktyce okazało się zupełnie
wystarczające).
Listing 1. Dekoder kodu RC5 opisany w języku Verilog, wykorzystujący układ czasowy.
module rc5decoder(clk,in,rdy,rc5code);
// deklaracja portów we/wy
input clk,in;
output rdy;
output [13:0] rc5code;
//deklaracja zmiennych
reg [13:0] rc5code;
reg rc5ready,in1,load,start,to,onair;
reg [13:0] rc5temp;
wire [10:0] qcntr;
reg [1:0] ecnt;
cntr c1(.clk(clk),.load(load),.d(11'd1333),.q(qcntr));
//konkretyzacja (utworzenie instancji) modułu licznika
//(licznik zdefiniowany jest w oddzielnym module)
//poniżej opis behawioralny działania dekodera
always @(posedge clk)
begin
in1<=in;
//zapamiętanie stanu wejścia w poprzednim takcie zegara
if((in1&~in)||(~in1&in))
begin
// jeżeli zbocze 0/1 lub 1/0 sygnału wejściowego
// (realizacja detektora zboczy)
if(~start)
begin
// jeżeli nie rozpoczęto jeszcze dekodowania // ustaw odpowiednie wartości początkowe
start=1'b1; onair=0;
rc5temp=14'd1; ecnt=0;
end
else ecnt=ecnt+1;
//inkrementuj wartość licznika błędu
if(~onair)
begin
// jeżeli wystąpiło zbocze na wejściu
// i nie trwa odmierzania czasu 3/4T
load=1'b1; //załaduj licznik stałą 3/4T
onair=1'b1;
Sprzętowy dekoder RC5
5
end
to=0;
end
else
load=0;
if(ecnt==2'b11)
begin
// jeżeli zbyt dużo zboczy – rozpocznij dekodowanie od początku
start=0; to=0;
end
if(qcntr==11'd0)
begin
//licznik osiągnął stan 0
onair=0; ecnt=0;
if(~to)
begin
to=1'b1;
//jeżeli to=1, licznik odmierza czas oczekiwania na następne zbocze
if(start)
rc5temp={rc5temp[12:0],in};
//realizacja rejestru przesuwnego
end
else
begin
// jeżeli przekroczono czas oczekiwania na zbocze
start=0; to=0; rc5ready=0;
end
end
if(rc5temp[13]==1'b1)
begin
// jeżeli odebrano już 14 bitów – koniec dekodowania
rc5code=rc5temp; rc5ready=1; start=0;
end
end
assign rdy=rc5ready;
endmodule
// definicja działania licznika 11-bitowego
module cntr(clk,load,d,q);
input clk,load;
input [10:0] d;
output [10:0] q;
reg [10:0] tmp;
always @(posedge clk)
begin
if(load) tmp=d;
else
if(tmp==11'd0) tmp=d;
else tmp=tmp-1;
// jeżeli licznik osiągnął 0 – ładuj automatycznie stałą
// czasową d, w przeciwnym przypadku dekrementuj zawartość licznika
end
assign q=tmp;
endmodule
Tak zdefiniowany wirtualny komponent dekodera RC5 może być postrzegany jako pewna „czarna
skrzynka” z następującymi sygnałami wejściowymi i wyjściowymi:
• clk – zegarowy sygnał taktujący (musi być 1MHz),
• in – wejście dekodera, które powinno być połączone z wyjściem odbiornika podczerwieni (aktywny
poziom niski – nie trzeba więc negować sygnału z odbiornika),
Sprzętowy dekoder RC5
•
•
6
rdy – wyjście informujące o pomyślnym zakończeniu dekodowania protokołu (na tym wyjściu pojawia się impuls o czasie trwania ok. 3ms)
rc5code – 14-sto bitowe wyjście danych zdekodowanych (stan poszczególnych bitów w odebranej
ramce danych protokołu RC5)
Sprzętowy dekoder RC5 wykorzystujący automat sekwencyjny
W przypadku implementacji sprzętowej dekodera z wykorzystaniem automatu sekwencyjnego
odpowiedni schemat blokowy układu dekodera może wyglądać tak jak pokazano na rys. 6.
AUTOMAT
SEKWENCYJNY
REJESTR PRZESUWNY
A0..A4
C0..C5
T
S0
SP
SG
LP
LG
INTERFEJS
SPI
TO
SCK
CS
KOMPARATORY
STEROWANIE
1MHz
IN
DETEKTOR
1/0
0/1
RDY
LICZNIK
RST
Rys. 6. Schemat blokowy dekodera RC5 z wykorzystaniem automatu sekwencyjnego
Dekodera składa się tutaj z:
detektora zboczy (1/0 lub 0/1) zerującego licznik (wystąpienie zbocza sygnału wejściowego
powoduje wyzerowanie licznika),
• licznika 11 – bitowego odmierzającego czas z rozdzielczością 1us (przy taktowaniu 1MHz),
• zespołu komparatorów, który określa wystąpienie odpowiednich zdarzeń dla automatu
sekwencyjnego (krótki impuls – SP, długi impuls – LP, krótka przerwa – SG, długa przerwa – LG,
przekroczenie czasu oczekiwania na zbocze – TO),
• automatu sekwencyjnego, działającego według grafu z rys. 3.16, będącego zasadniczą częścią
dekodera,
• rejestru przesuwnego, zapamiętującego kolejne odebrane bity ramki protokołu RC5, wyznaczone
przez automat sekwencyjny,
• prostego układu sterująco – nadzorującego, odpowiedzialnego m. in. za wyznaczania końca transmisji
ramki danych RC5.
Kod źródłowy implementacji dekodera z wykorzystaniem automatu sekwencyjnego przedstawiono na
listingu 2.
•
Listing 2. Dekoder RC5 opisany w języku Verilog, wykorzystujący automat sekwencyjny
module rc5decoder_II(clk,in,rdy,rc5code);
input clk,in;
output rdy;
output [13:0] rc5code;
wire short_pulse,long_pulse,short_gap,long_gap;
reg[3:0] state;
wire time_out;
reg [13:0] rc5temp;
reg rc5ready;
reg [13:0] rc5code;
timer t1(.clk(clk),.in(~in),
.lp(long_pulse),.sp(short_pulse),
.lg(long_gap),.sg(short_gap),.to(time_out));
Sprzętowy dekoder RC5
//Konkretyzacja modułu timera (licznik wraz z komparatorami)
//Poniżej realizacja automatu
always@(posedge clk)
begin
if(time_out)
begin
// jeżeli przekroczono czas oczekiwania na zbocze // automat wraca do stanu początkowego
state=4'd0; rc5ready=0;
end
else
begin
case(state)
4'd0:
begin
rc5temp=0;
if(~in) state=4'd1;
else state=4'd0;
// jeżeli zmiana poziomu wejścia na niski –
// przejdź do stanu 1, w przeciwnym przypadku pozostań w 0
end
4'd1:
begin
rc5temp={rc5temp[12:0],1'b1};
//wpisanie jedynki do rejestru przesuwnego
//(pierwszy bit startu ramki RC5)
state=4'd2; //przejdź do stanu 2 czyli S0
end
4'd2:
begin
//stan S0 automatu (rys. 3.16)
if(short_pulse&&long_pulse) state=4'd0;
//jeżeli inne zdarzenie niż krótki impuls lub długi impuls
//wróć do stanu 0
else
if(short_pulse&&!long_pulse) state=4'd3; //S1
//jeżeli krótki impuls przejdź do stanu 3 (S1)
else
if(long_pulse&&!short_pulse) state=4'd4;
// jeżeli długi impuls przejdź do stanu pośredniego 4
else state=4'd2;
// w przeciwnym przypadku pozostań w bieżącym stanie 2
end
4'd3:
begin
//stan S1
if(short_gap&&long_gap) state=4'd0;
//jeżeli zdarzenie inne niż spodziewane – następny stan 0
else
if(short_gap&&!long_gap) state=4'd5;
//jeżeli krótka przerwa wróć do stanu S0
else state=4'd3;
end
4'd4:
begin
// odebrano bit o wartości 0
rc5temp={rc5temp[12:0],1'b0};
//wpisanie 0 do rejstru przesuwnego
state=4'd6; //przejdź do stanu S2
end
4'd5:
begin
7
Sprzętowy dekoder RC5
// odebrano bit o wartości 1
rc5temp={rc5temp[12:0],1'b1};
wpisanie 1 do rejestru przesuwnego
state=4'd2; //przejdź do stanu S0
end
4'd6:
begin
//stan S2
if(short_gap&&long_gap) state=4'd0;
//jeżeli zdarzenie inne niż spodziewane – następny stan 0
else
if(long_gap&&!short_gap) state=4'd5;
//jeżeli długa przerwa przejdź do stanu pośredniego 5
else
if(short_gap&&!long_gap) state=4'd7;
//jeżeli krótka przerwa przejdź do stanu S3
else state=4'd6;
end
4'd7:
begin
//stan S3
if(short_pulse&&long_pulse) state=4'd0;
//jeżeli zdarzenie inne niż spodziewane – następny stan 0
else
if(short_pulse&&!long_pulse) state=4'd4;
//jeżeli krótki impuls idź do stanu pośredniego 4
else state=4'd7;
end
endcase
if(rc5temp[13]==1'b1)
begin
//jeżeli bit MSB rejstru przesuwnego zapalony –
//dekodowanie zakończone
rc5code=rc5temp;
//zapamiętaj odebrane bity w rejestrze zatrzaskowym
rc5ready=1; state=4'd0;
//ustaw flage zakończenia dekodowania i przejdź do stanu 0
end
end
end
assign rdy=rc5ready;
//przepisanie flagi zakończenia dekodowania do portu wyjściowego
endmodule
//Poniżej kod modułu timera
module timer(clk,sp,lp,sg,lg,in,to);
input clk,in;
output sp,lp,sg,lg,to;
reg sp1,lp1,sg1,lg1,rst,in1,to;
wire [11:0] time1;
wire [4:0] tm;
cntr c1(.clk(clk),.q(time1),.rst(rst));
//konkretyzacja modułu licznika
assign tm={time1[11],time1[10],time1[9],time1[8]};
//zmienna tm zawiera 4 najbardziej znaczące bity licznika
assign
assign
assign
assign
sp=sp1;
lp=lp1;
sg=sg1;
lg=lg1;
//poniżej opis behawioralny działania układu licznik - komparatory
always @(posedge clk)
begin
8
Sprzętowy dekoder RC5
if(time1>12'd2300)
to=1;
else to=0;
//jeżeli oczekiwanie na zbocze dłużej niż 2.3ms – ustaw flagę to
in1<=in; //przypisanie nie blokujące
//(zapamiętanie stanu wejścia w poprzednim takcie zegara)
if(in1&~in) //zbocze opadające na wejściu
begin
rst=1; //wyzeruj licznik (w następnym takcie)
if(tm>4'd2&&tm<4'd5) //krótki impuls
begin
sp1=1; lp1=0;
sg1=0; lg1=0;
end
else
if(tm>4'd4&&tm<4'd8) //długi impuls
begin
sp1=0; lp1=1;
sg1=0; lg1=0;
end
else
begin
//jeżeli impuls spoza przedziału - błąd
sp1=1; lp1=1;
sg1=0; lg1=0;
end
end
else
if(~in1&in) //zbocze narastające na wejściu
begin
rst=1; //zeruj licznik
if(tm>4'd2&&tm<4'd5) //krótka przerwa
begin
sg1=1; lg1=0;
sp1=0; lp1=0;
end
else
if(tm>4'd4&&tm<4'd8) //długa przerwa
begin
sg1=0; lg1=1;
sp1=0; lp1=0;
end
else
begin
//jeżeli przerwa spoza przedziału – błąd
sg1=1; lg1=1;
sp1=0; lp1=0;
end
end
else
rst=0;
end
endmodule
//Poniżej kod licznika
module cntr(clk,rst,q);
input clk,rst;
output [11:0] q;
reg [11:0] tmp;
always @(posedge clk)
begin
if (rst) tmp=0;
//synchroniczne zerowanie
else tmp=tmp+1;
//inkrementacja licznika
end
assign q=tmp;
endmodule
9
Sprzętowy dekoder RC5
10
Tak zaimplementowany, według kodu z listingu 2, wirtualny komponent dekodera RC5, z punktu
widzenia sygnałów wejścia – wyjścia zachowuje się identycznie jak opisany już poprzednio dekoder.
Wymaga jednak nieco więcej zasobów sprzętowych danego układu programowalnego (dla przykładu: w
przypadku implementacji z zastosowaniem układu Xilinx XC9572XL i narzędzi XST zawartych w
pakiecie Xilinx ISE 5.2i, dekoder ten zajmuje 63 makrokomórki, podczas gdy poprzednia wersja – 57, w
obu przypadkach dla strategii silnej optymalizacji powierzchni).
Szeregowy interfejs SPI
Budując sprzętowy dekoder RC5 z wykorzystaniem układów PLD, można wyposażyć go w
szeregowy interfejs kompatybilny z SPI. Interfejs ten może być przydatny w przypadku współpracy
dekodera z mikrokontrolerem (odciążając mikroprocesor z realizacji zadania dekodowania protokołu
RC5) lub innymi urządzeniami peryferyjnymi.
Szeregowy interfejs SPI (Serial Peripheral Interface) do transmisji danych wykorzystuje trzy
linie: CS – wybór danego urządzenia SPI (aktywny poziom niski), SCK – sygnał zegarowy, S0 – wyjście
danych. Za pośrednictwem interfejsu SPI dane przesyłane są w sposób synchroniczny. W pewnym
uproszczeniu działanie interfejsu można opisać następująco. Transmisję danych inicjuje układ nadrzędny
ustawiając linię CS układu podrzędnego w stan niski. Układ podrzędny ustawia wówczas linię wyjściową
S0 w stan odpowiadający pierwszemu transmitowanemu bitowi (bit najbardziej znaczący przesyłany jest
jako pierwszy). Stan linii S0 może być próbkowany przez układ nadrzędny podczas opadającego zbocza
sygnału zegarowego SCK. Układ podrzędny może zmieniać stan linii wyjściowej tylko wówczas, gdy
sygnał SCK generowany przez układ nadrzędny znajduje się w stanie niskim. Wygenerowanie impulsu na
linii SCK przez układ nadrzędny powoduje pojawienie się na linii S0 kolejnego transmitowanego bitu,
itd.
Na listingu 3 przedstawiono kod w języku Verilog opisujący działanie interfejsu szeregowego SPI
dla układu sprzętowego dekodera RC5.
Listing 3. Wirtualny komponent realizujący interfejs SPI dla układu podrzędnego
module spi_core(clk,data,cs,sck,s0);
input clk,cs,sck;
input [13:0] data;
output s0;
reg [15:0] sreg;
reg f1,f2;
always @(posedge clk)
begin
if(~cs)
begin
//jeżeli linia CS znajduje się w stanie niskim
if(~f1) begin f1=1; f2=0; sreg=data; end
//równoległy wpis do rejestru przesuwnego sreg
//wartości danych wejściowych – podczas opadającego
//zbocza sygnału CS
if(~sck&&f2)
begin
sreg={sreg[12:0],sreg[13]};
f2=0; //zeruj flagę f2
//rejestr przesuwny sreg przesuwany jest podczas gdy
//SCK zmieni swój stan na niski
end
if (sck&&~f2) f2=1;
//jeżeli SCK zmienił poziom na wysoki – ustaw flagę f2
end
else f1=0;
// jeśli CS=1, zeruj flagę f1
end
end
assign s0=sreg[13];
Sprzętowy dekoder RC5
11
//SO to najstarszy bit rejestru przesuwnego
endmodule
Przedstawiona na listingu 3 implementacja interfejsu szeregowego wykorzystuje rejestr
przesuwny z wpisem równoległym. Jak wykazały doświadczenia tego typu realizacja interfejsu zajmuje
relatywnie dużo zasobów sprzętowych układu programowalnego (co jest istotne w przypadku
implementacji na tanich układach programowalnych klasy CPLD, wyposażonych w dość ograniczone
zasoby logiczne). Można jednak zastosować nieco prostszą konstrukcję interfejsu, tak jak zilustrowano to
na rys. 7. Zamiast rejestru przesuwnego można wykorzystać licznik sprzężony z multiplekserem.
Wystąpienie zbocza opadającego na linii CS spowoduje wyzerowanie licznika. Wyjścia licznika
połączone są z wejściami wyboru multipleksera. Pojawienie się impulsów na wejściu zegarowym licznika
spowoduje zwiększanie wartości licznika i odpowiadające tej wartości połączenie wyjścia multipleksera z
jednym z wejść danych multipleksera. Efekt końcowy będzie identyczny jak z użyciem rejestru
przesuwnego.
MUX
DANE
SO
SEL
E
LICZNIK
SCK
RST
DETEKTOR
1/0
CS
Rys. 7. Inna realizacja interfejsu SPI
Na listingu 4 przedstawiono kod w języku Verilog opisujący alternatywną realizację interfejsu
SPI.
Listing 4. Alternatywna implementacja interfejsu SPI
module spi_core(data,clk,cs,sck,s0);
input cs,clk,sck;
input [13:0] data;
output s0;
wire [3:0] qcntr;
cntr4 c1(.sck(sck),.clk(clk),.q(qcntr),.cs(cs));
mux m1(.data(data),.sel(qcntr),.out(s0));
//definicja sposobu połączenia licznika i multipleksera
//(konkretyzacja modułów licznika i multipleksera)
endmodule
//definicja modułu licznika
module cntr4(cs,clk,sck,q);
input sck,clk,cs;
output [3:0] q;
reg [3:0] q;
reg clrcnt,f;
wire rst;
always @(posedge clk)
begin
if(~cs&&f)
begin
f=0; clrcnt=1;
Sprzętowy dekoder RC5
12
end
else clrcnt=0;
//sygnał zerowanie clrcnt dla licznika ustawiany
//w momencie wystąpienia zbocza opadającego na CS
if(cs&&~f) f=1;
end
assign rst=~clrcnt; //zmiana polaryzacji
always @(negedge sck or negedge rst)
begin
if(~rst) q=4'd0;
//asynchroniczne zerowanie licznika
else
q=q+1;
//inkrementacja licznika
end
endmodule
//opis behawioralny modułu multipleksera
module mux(data,sel,out);
input [13:0] data;
input [3:0] sel;
output out;
reg out;
always @(sel or data)
begin
case (sel)
4'd0: out=data[13];
4'd1: out=data[12];
4'd2: out=data[11];
4'd3: out=data[10];
4'd4: out=data[9];
4'd5: out=data[8];
4'd6: out=data[7];
4'd7: out=data[6];
4'd8: out=data[5];
4'd9: out=data[4];
4'd10: out=data[3];
4'd11: out=data[2];
4'd12: out=data[1];
4'd13: out=data[0];
4'd14: out=0;
4'd15: out=0;
endcase
end
endmodule
CS
SCK
SO
S1
S2
T
A4
A3
A2
A1
A0
C5
C4
C3
C2
C1
C0
S1
S2
Rys. 8. Ilustracja działania interfejsu SPI
Na rys. 8 przedstawiono ilustrację sposobu działania interfejsu SPI zrealizowanego według opisu
z listingu 3. Ilość bitów interfejsu dostosowana jest do długości ramki protokołu RC5 i wynosi 14 bitów.
Dlatego też w przypadku, gdy na linii SCK interfejsu wystąpi więcej niż 14 impulsów, wówczas dane
pojawiają się na wyjściu „od początku” (czyli po najmniej znaczącym bicie kodu polecenia RC5 pojawia
się pierwszy bit startu, itd.).
Sprzętowy dekoder RC5
13
Działanie interfejsu SPI z listingu 4 jest analogiczne, przy czym po 14 bitach ramki danych RC5,
w przypadku dalszego taktowania linii SCK, pojawiając się dwa bity, których wartość zawsze jest równa
0 i dopiero wówczas kolejne bity ramki RC5 transmitowana jest od początku.
Dane z interfejsu SPI mogą być odczytywane w dowolnej chwili z szybkością wyznaczoną przez
układ nadrzędny (mikrokontroler). Jednak w przypadku interfejsu z listingu 3 maksymalna częstotliwość
impulsów na wejściu SCK musi być mniejsza niż częstotliwość taktowania na wejściu zegarowym (clk)
interfejsu. W przypadku implementacji interfejsu według listingu 4, częstotliwość impulsów na linii SCK
może być znacznie większa niż częstotliwość taktowania na wejściu clk (licznik, będący głównym
elementem interfejsu, taktowany jest bezpośrednio impulsami z linii SCK, podczas gdy pomocniczy
sygnał taktujący clk wykorzystywany jest tylko do wykrywania opadającego zbocza sygnału na linii CS).
Listing 5. Funkcja odczytu danych z interfejsu SPI, napisana w języku C dla mikrokontrolera
unsigned int spi_rx(void)
{
char j, b;
unsigned int w;
w=0;
CS=0;
SCK=0;
for (j=0;j<14;j++)
{
SCK=1;
w<<=1; b=SO; w|=b;
SCK=0;
}
CS=1;
return w;
}
Na listingu 5 przedstawiono dodatkowo kod źródłowy funkcji w języku C, napisanej dla
mikrokontrolera, dzięki której można odczytać dane z przedstawionego powyżej interfejsu SPI. Funkcja
zwraca pełne 14 bitów ramki danych RC5.
Przykładowa aplikacja
Wykorzystując opisane powyżej wirtualne komponenty dekoderów RC5 oraz interfejsu SPI
można zbudować rzeczywisty, sprzętowy dekoder protokołu RC5. Na rys. 9 przedstawiono przykładowy
schemat ideowy takiego układu, a na rys. 10 widok płytki drukowanej.
U2
LM317L
JP1
3
Vcc
3.3V
Vin
Vout
C1
100n
2
JTAG
JP2
C2
100n
R1
240
Vcc
5
4
3
2
1
Adj
2
1
1
39
40
41
42
43
44
1
2
R3
820
4
U3
VCC
3
OUT
GND
3
JP3
GEN 2MHz
2
R4
120
U4
OUT
1
2
C3
3
220n
18
19
20
21
22
23
I/O/MC1-17
I/O/MC2-17
I/O/MC4-2
I/O/MC4-5
I/O/MC4-8
I/O/MC4-9
I/O/MC4-11
I/O/MC4-14
I/O/MC3-2
I/O/MC3-5
I/O/MC3-8
I/O/MC3-9
I/O/MC3-11
I/O/MC3-14
14
16
28
27
25
17
4
GND
VS
5
4
3
2
1
JP5
U1
I/O/MC2-2
I/O/MC2-5
I/O/MC2-6
I/O/MC2-8
I/O/GSR/MC2-9
I/O/GTS2/MC2-11
I/O/GTS1/MC2-14
I/O/MC2-15
I/O/MC3-15
I/O/MC3-17
I/O/MC4-17
I/O/MC4-15
GND
GND
GND
RDY
CS
SCK
SO
GND
I/O/MC1-2
I/O/MC1-5
I/O/MC1-6
I/O/MC1-8
I/O/GCK1/MC1-9
I/O/GCK2/MC1-11
I/O/GCK3/MC1-14
I/O/MC1-15
VCCIO
VCCINT
VCCINT
D1 LED
TDO
TMS
TDI
TCK
390
26
35
15
24
10
9
11
R2
29
30
31
32
33
34
36
37
1
2
3
4
5
6
7
C0
C1
C2
C3
C4
C5
T
JP4
38
5
6
7
8
12
13
XC9572XL-VQ44
TSOP1736
Rys. 9. Schemat ideowy układu sprzętowego dekodera RC5
10
8
6
4
2
9
7
5
3
1
A4
A3
A2
A1
A0
Sprzętowy dekoder RC5
14
Rys. 10. Widok płytki drukowanej dekodera
Jako układ programowalny wybrano tutaj Xilinx CPLD z rodziny XC9500XL typu XC9572XL w
obudowie VQFP44. Układ zasilany jest napięciem 3.3V, ale od strony wejść akceptuje napięcia o
standardzie TTL. Jako stabilizator 3.3V zastosowano typowy stabilizator uniwersalny typu LM317 z
odpowiednio dobranymi wartościami rezystorów określającymi wartość napięcia wyjściowego. W
układzie wytwarzania przebiegu taktującego pracuje typowy, cztero końcówkowy (w metalowej
obudowie) zintegrowany generator zegara o częstotliwości 2MHz (można zastosować generator o innej
częstotliwości, ale wówczas należy odpowiednio zaprogramować dzielniki częstotliwości dla układu
dekodera RC5, który musi być taktowany z częstotliwością 1MHz). Do przetwarzania sygnałów
podczerwieni, nadawanych przez pilota zdalnego sterowania, wykorzystano zintegrowany odbiornik
podczerwieni firmy Vishay (TSOP1736).
Na listingu 6 przedstawiono kod źródłowy w języku Verilog modułu implementującego dekoder
RC5 i interfejs SPI.
Listing 6. Kompletny sprzętowy dekoder RC5 z interfejsem SPI
module top(clock,in,cs,sck,s0,rdy,ld,C,A,T);
//definicja portów we - wy
input clock,in,cs,sck;
output ld,s0,rdy,T;
output [4:0] A; // adres RC5
output [5:0] C; // kod polecenia
wire clk;
reg rc5ready;
wire [13:0] rc5code;
clock_divider cd1(.clock(clock),.clk(clk));
//konkretyzacja modułu dzielnika częstotliwości
//sygnał clk ma teraz częstotliwość 1MHz
rc5decoder dec(.clk(clk),.in(in),.rdy(rdy),.rc5code(rc5code));
//konkretyzacja opisanego wcześniej modułu dekodera
assign ld=rdy; //dioda LED połączona z sygnałem rdy
assign C={rc5code[5],rc5code[4],rc5code[3],rc5code[2],
rc5code[1],rc5code[0]};
//przypisanie do odpowiednich wyjść kodu polecenia RC5
assign A={rc5code[10],rc5code[9],rc5code[8],rc5code[7],rc5code[6]};
//przypisanie adresu urządzenia RC5
assign T=rc5code[11];
//bit informujący o przytrzymaniu klawisza w pilocie
spi_core spi1(.clk(clk),.cs(cs),.sck(sck),.s0(s0),.data(rc5code));
//konkretyzacja modułu interfejsu SPI
endmodule
//moduł dzielnika częstotliwości
module clock_divider(clock,clk);
input clock;
output clk;
reg q;
always @(posedge clock)
Sprzętowy dekoder RC5
15
begin
q=~q;
end
assign clk=q;
endmodule
Po zaimportowaniu do środowiska EDA dla układów programowalnych kodów źródłowych z
listingu 5 – modułu nadrzędnego w hierarchicznej strukturze projektu – oraz jednego z modułów
dekodera RC5 (których kody źródłowe zamieszczono na listingach 1 i 2) i modułu interfejsu SPI (listing
A.3 lub A.4), i jeszcze przypisując portom wejścia / wyjścia modułu nadrzędnego odpowiednie numery
końcówek układu PLD – kompletny projekt można poddać kompilacji. Jako środowisko EDA
wykorzystano tutaj pakiet Xilinx ISE w wersji 5.2i. W wyniku procesu kompilacji (implementacji)
otrzymuje się plik w standardowym, dla układów CPLD, formacie JEDEC, który służy do
zaprogramowania nieulotnej pamięci konfiguracji w danym układzie PLD. Zastosowany układ PLD
posiada możliwość programowania w systemie – ISP (In-System Programming), poprzez intefejs JTAG,
którego odpowiednie linie wyprowadzono na złącze JP2 płytki drukowanej. W celu zaprogramowania
układu można wykorzystać uniwersalny programator ISP opisany w Elektronice Praktycznej 1/2004 lub
też prosty programator, którego schemat można znaleźć w dokumentacji firmy Xilinx (programator ten
był opisany również w Elektronice Praktycznej 4/2001).
Po zaprogramowaniu układu PLD sprzętowy dekoder RC5 jest gotowy do pracy. Poprawne
odebranie przez dekoder ramki danych protokołu RC5 sygnalizowane jest krótkim mignięciem diody
LED. Jednocześnie na wyjściu RDY (złącze JP3) pojawia się w tym momencie stan wysoki. Na złączu
JP5 występują kolejne bity (C0..C5) kodu polecenia RC5 oraz bit T (informujący o przytrzymaniu
klawisza w pilocie), a na złączu JP4 dostępne są bity adresu urządzenia (A0..A4). Zdekodowane bity
ramki danych RC5 można również odebrać poprzez wbudowany interfejs SPI (linie CS, SCK, SO złącza
JP3).
Sprzętowy dekoder RC5 można również tak skonfigurować, by odbierał tylko ramkę danych z
określonym adresem urządzenia RC5 (podobnie jak robił to wycofany już z produkcji układ SAA3049
firmy Philips). W tym celu wystarczy nieco zmienić kod w module nadrzędnym – tak jak pokazano to na
listingu 7.
Listing 7. Kod sprzętowego dekodera RC5 akceptującego określony adres urządzenia RC5
module top(clock,in,cs,sck,s0,rdy,ld,C,A,T);
input clock,in,cs,sck;
output ld,s0,rdy,T;
input [4:0] A;
output [5:0] C;
wire [4:0] rc5addr;
reg [5:0] C;
wire clk;
reg T,ready;
wire rdy;
wire [13:0] rc5code;
clock_divider cd1(.clock(clock),.clk(clk));
rc5decoder dec(.clk(clk),.in(in),.rdy(rdy),.rc5code(rc5code));
spi_core spi1(.clk(clk),.cs(cs),.sck(sck),.s0(s0),.data(rc5code));
assign rc5addr={rc5code[10],rc5code[9],
rc5code[8],rc5code[7],rc5code[6]};
//wydzielenie adresu urządzenia
always @(posedge clk)
begin
if(rdy)
begin
if(rc5addr==A)
begin
//jeżeli zgadza się adres RC5 z adresem ustawionym
//na liniach zewnętrznych układu PLD
C={rc5code[5],rc5code[4],rc5code[3],rc5code[2],
Sprzętowy dekoder RC5
16
rc5code[1],rc5code[0]};
T=rc5code[11];
ready=1;
end
end
else ready=0;
end
assign ld=ready;
endmodule
W tym przypadku adres urządzenia RC5 odebrany z ramki danych porównywany jest z adresem
odczytanym z zewnętrznych końcówek układu dekodera (stan linii A0...A4 złącza JP3). Jeżeli oba adresy
są zgodne, wówczas ustawiane jest wyjście RDY (złącze JP3) i na krótką chwilę zapala się dioda LED.
Na wyjściach C0...C5 oraz T dostępne są wówczas odpowiednie dane. Dane odczytane za pomocą
interfejsu SPI dostępne są niezależnie od tego czy oba adres urządzeń RC5 są zgodne, czy też nie.
Na kolejnych rysunkach przedstawiono przebiegi czasowe w wybranych punktach sprzętowego
dekodera RC5 otrzymane przy pomocy analizatora stanów logicznych. Na rys. 11 pokazano przebiegi
czasowe dla układu dekodera opisanego kodem z listingu 1. Pierwszy kanał analizatora ilustruje stan
sygnału wejściowego dekodera (wyjście zintegrowanego odbiornika podczerwieni) w momencie
nadawania ramki danych RC5 z kodem polecenia równym 01h oraz adresem urządzenia 16h. Drugi kanał
przedstawia zachowanie sygnału onair (listing 1 – sygnał wyprowadzono na zewnętrzne końcówki
układu PLD). Sygnał ten odpowiada sygnałowi z wyjścia monowibratora z rys. 3. Jego opadające zbocze
wyznacza moment próbkowania sygnału wejściowego przez rejestr przesuwny (czyli stan dekodowanego
bitu). Trzeci kanał analizatora ilustruje przebieg sygnału na wejściu rdy. Poziom wysoki na tym wyjściu
oznacza pomyślne zakończenie dekodowania ramki danych RC5.
Rys. 11. Przebiegi czasowe w układzie dekodera RC5 zaimplementowanego według kodu z
listingu 1
Rys. 12. Przebiegi czasowe w układzie dekodera RC5 zaimplementowanego według kodu z
listingu 2
Rys. 12 przedstawia przebiegi czasowe w układzie sprzętowego dekodera RC5 wykorzystującego
ideę automatu sekwencyjnego (kod z listingu 2). Kanały pierwszy i ostatni analizatora stanów logicznych
ilustrują zachowanie sygnałów wejściowego in oraz wyjściowego rdy. Na pozostałych kanałach widoczne
są przebiegi sygnałów określające rodzaj zdarzenia dla automatu sekwencyjnego wykorzystywanego do
dekodowania protokołu RC5 (sygnały: lg – długa przerwa, sg – krótka przerwa, lp – długi impuls, sp –
krótki impuls).
Zbigniew Hajduk
http://zh.prz-rzeszow.pl
Sprzętowy dekoder RC5
17
UWAGA
Przedstawione powyżej wirtualne komponenty sprzętowego dekodera RC5 przeznaczone są bezpośrednio
do syntezy. W przypadku symulacji wyniki symulacji funkcjonalnej mogą nie odpowiadać rezultatom
symulacji czasowej (po syntezie).
Literatura
1. Łuba T., Rawski M, Tomaszewicz P., Zbierzchowski B., Synteza układów cyfrowych, WKŁ,
Warszawa 2003.
2. Pasierbiński J., Zbysiński P., Układy programowalne w praktyce, WKŁ, Warszawa 2002.
3. Synopsys Inc., FPGA Compiler II / FPGA Express Verilog HDL Reference Manual, 1999.
4. Xilinx Inc., Xilinx Synthesis Technology (XST) User Guide, 2002.
5. Zbysiński P., UnISProg – uniwersalny programator ISP, Elektronika Praktyczna, Nr 1, str. 21 –
25, styczeń 2004.
6. Zwoliński M., Projektowanie układów cyfrowych z wykorzystaniem języka VHDL, WKŁ,
Warszawa 2002.