Konwerter 1-Wire - SPI opisany w języku Verilog.pdf

(441 KB) Pobierz
Konwerter 1-Wire -> SPI opisany w Verilogu
Konwerter 1-Wire -> SPI opisany w języku Verilog
1
Konwerter 1-Wire -> SPI opisany
w języku Verilog
Prezentowany tutaj konwerter przeznaczony jest szczególnie do współpracy z układami
termometrów cyfrowych firmy Dallas/Maxim wyposażonymi w jednoprzewodową magistralę 1-wire.
Konwerter posiada podwójny interfejs kompatybilny z SPI, dzięki czemu dwa różne urządzenia (np.
mikrokontrolery) mogą w dowolnym momencie odczytywać wartość temperatury zmierzonej przez
termometr w sposób całkowicie od siebie niezależny. Konwerter zrealizowano w sposób sprzętowy z
wykorzystaniem układów programowalnych i o
pisano w języku Verilog.
Czasami zachodzi potrzeba niezależnego odczytu temperatury z jednego czujnika przez dwa różne
urządzenia. Odczyt temperatury może być dokonywane przez te urządzenia w dowolnej chwili, w sposób
niezależny, w tym również w pełni równolegle. W warunkach przemysłowych może to być, na przykład
sytuacja, gdy układ sterowania danym procesem (regulator) i układ monitorowania – nadzoru tego
procesu wymagają tych samych danych pomiarowych (temperatura) pochodzących z jednego czujnika.
Jeżeli stosowanym czujnikiem jest termometr cyfrowy pracujący z magistralą jednoprzewodową,
wówczas rozwiązaniem problemu niezależnego odczytu temperatury przez dwa różne układy jest opisany
tu konwe
Układ konwertera umożliwia odczyt temperatury za pomocą synchronicznego szeregowego
interfejsu SPI. Zaletą tego interfejsu jest jego niezwykle prosta obsługa programowa (za pomocą
mikrokontrolerów), nie wymagająca precyzyjnego odmierzania czasu. Dlatego też konwerter może być
również stosowany w sytuacji, gdy programowa obsługa magistrali 1-wire termometru jest ze względów
czasowych (np. bardzo intensywnego zaangażowania mikroprocesora w inne zadania) utrudniona lub
wręcz
niemożliwa.
Prezentowany tutaj projekt układu konwertera posiada też pewien aspekt dydaktyczny. Pokazuje
sposób współczesnego konstruowania sprzętu cyfrowego oparty na wykorzystaniu języków opisu sprzętu
(Verilog), komputerowych narzędzi syntezy i układów programowalnych. O ile, dla sprawnego
programisty, napisanie odpowiednich procedur obsługi magistrali jednoprzewodowej dla wybranego typu
mikrokontrolera, nawet w języku maszynowym, nie powinno zająć więcej czasu niż kilkadziesiąt minut
(nie wspominając już o możliwości wykorzystania gotowych bibliotek), o tyle zaprojektowanie i
przetestowanie analogicznie działającego sprzętu (wirtualnych komponentów) jest już procesem znacznie
bardziej skomplikowanym i zajmuje nieporównywalnie więcej
Chociaż została tu zaproponowana implementacja konwertera w układach programowalnych
firmy Xilinx z rodziny CoolRunner-II , to wirtualny komponent opisujący konwerter (kod w języku
Verilog) można wykorzystać – bez żadnych zmian – do implementacji w dowolnych innych układach
PLD. Możliwe jest również wykorzystanie, opisanych dalej, poszczególnych wirtualnych komponentów
odpowiedzialnych za obsługę magistrali jednoprzewodowej, czy też interfejsu SPI jako części składowej
pewnego większego p
czasu.
rojektu.
Magistrala 1-wire
Magistrala 1-wire, z definicji, wykorzystuje tylko pojedynczą linię danych. Każde urządzenie
(nadrzędne lub podrzędne) dołączane jest do magistrali poprzez port trójstanowy lub typu otwarty dren.
Umożliwia to danemu urządzeniu zwolnienie linii danych magistrali, podczas, gdy nie jest ono
zaangażowane w proces transmisji danych, pozwalając tym samym na użycie magistrali przez inne
układy. W czasie, gdy magistralą nie są transmitowane żadne dane, linia danych magistrali znajduje się w
stanie wysokim wymuszonym przez zewnętrzny rezystor podciągający (zazwyczaj o wartości oko
5kΩ).
Każda transakcja (proces wymiany danych) na magistrali inicjowana jest przez urządzenie nad-
rzędne ( master ) poprzez wysłanie do urządzeń podrzędnych tzw. impulsu zerującego. Układ nadrzędny
ło
wymusza poziom niski na magistrali przez czas, co najmniej 480µs, po czym zwalnia magistralę. Jeżeli
rter.
Konwerter 1-Wire -> SPI opisany w języku Verilog
2
do magistrali dołączone są jakieś urządzenia to powinny one, średnio po czasie 15...60µs od momentu
zwolnienia magistrali przez układ nadrzędny, ustawić magistralę w stan niski przez czas 60...240µs. Jest
to tzw. impuls obecności układu (układów) podrzędnego.
Transmisja poszczególnych bitów danych na magistrali 1-wire odbywa się podczas trwania
szczelin czasowych zapisu i odczytu. Czas trwania każdej szczeliny musi wynosić minimum 60µs, a czas
przedzielający dwie sąsiednie szczeliny nie może być krótszy niż 1µs. Istnieją dwa typy szczelin
czasowych zapisu: szczelina zapisu 1 (transmitowany przez układ nadrzędny bit ma wartość logiczną 1)
oraz szczelina zapisu 0 (transmitowany bit ma wartość 0). Aby wygenerować szczelinę czasową zapisu 1
układ nadrzędny wymusza poziom niski na magistrali przez czas 1...15µs, po czym zwalnia magistralę.
W przypadku szczeliny czasowej zapisu 1 układ nadrzędny wymusza poziom niski na magistrali przez
czas conajmniej 60µs (jednak nie dłużej niż 120µs). Układ podrzędny próbkuje stan magistrali w czasie
15...60µs od momentu zainicjowania transmisji szczeliny czasowej przez układ nadrzędny (ustawienia
magistrali w stan niski). Jeżeli podczas próbkowania magistrala znajduje się cały czas w stanie wysokim,
oznacza to, że odczytany bit ma wartość 1, w przeciwnym przypadku 0.
Szczelina czasowa odczytu inicjowana jest przez układ nadrzędny poprzez wymuszenie poziomu
niskiego na magistrali przez czas minimum 1µs (jednak nie dłużej niż 15µs) i zwolnienie magistrali. Po
zainicjowaniu szczeliny czasowej odczytu, układ podrzędny rozpoczyna transmisję poszczególnych
bitów. Bit o wartości 1 transmitowany jest poprzez pozostawienie magistrali w stanie wysokim, a bit o
wartości 0 – poprzez wymuszenie na magistrali stanu niskiego. Podczas przesyłania bitu o wartości 0
układ podrzędny zwalnia magistralę na końcu czasu trwania szczeliny czasowej odczytu. Dane z układu
podrzędnego mogą być odczytywane przez układ nadrzędny po czasie minimum 15µs od wystąpienia
opadającego zbocza na magistrali wyznaczającego początek szczeliny czasowej odczytu. Magistralą 1-
wire bit najmniej znaczący (LSB) transmitowany jest jako pie
rwszy.
Interfejs SPI
Drugi z wykorzystywanych w projekcie interfejsów to szeregowy interfejs SPI ( Serial Peripheral
Interface ). System wykorzystujący interfejs SPI składa się z urządzenia nadrzędnego ( master ),
zarządzającego transmisją danych i jednego lub więcej urządzeń podrzędnych ( slave ). SPI jest
czteroprzewodowym szeregowym interfejsem synchronicznym umożliwiającym w pełni dwukierunkową
transmisję danych pomiędzy urządzeniem nadrzędnym i urządzeniami podrzędnymi. Transmisja danych
przebiega z udziałem trzech linii interfejsu: szeregowego wejścia danych (MOSI), szeregowego wyjścia
danych (MISO) oraz synchronizującego sygnału taktującego (SCK), generowanego przez układ
nadrzędny. Czwarta linia interfejsu to linia CS wyboru danego u
Każda transmisja danych rozpoczyna się wraz z opadającym zboczem sygnału CS i kończy się
wraz ze zboczem narastającym. Bit najbardziej znaczący (MSB) transmitowany jest jako pierwszy.
Kolejne transmitowane bity danych przesuwane są na linię wyjściową (MISO) układu podrzędnego
podczas opadającego zbocza sygnału SCK. Układ nadrzędny próbkuje stan tej linii podczas narastającego
zbocza sygnału
W prezentowanym projekcie wykorzystywana będzie jedynie uproszczona wersja interfejsu
umożliwiająca jednokierunkową transmisję danych od układu podrzędnego (opisywanego tu konwertera)
do układu nadrzędnego (np. mikrokontrolera). Przebiegi czasowe ilustrujące taką transmisję pokazano na
rys. 1. Linie standardowo oznaczaną jako MISO ( Master Input Serial Output ) nazwano na rysunku w
uproszczeniu SO. Oznaczenie to będzie stosowane w dalszej części tekstu.
CS
kładu podrzędnego.
SCK.
0
1
2
3
4
5
6
7
8
9
10 11 12 13 14 15
SCK
SO
a7 a6 a5 a4 a3 a2 a1 a0 b7 b6 b5 b4 b3 b2 b1 b0
MSB
LSB MSB
LSB
bajt A
bajt B
Rys. 1. Jednokierunkowa transmisja danych za pomocą interfejsu SPI
Ze względu na to, że SPI jest interfejsem synchronicznym, jego obsługa programowa np. za po-
mocą mikrokontrolera jest bardzo prosta, niewymagająca precyzyjnego odmierzania czasu, jak to ma
217708093.001.png
Konwerter 1-Wire -> SPI opisany w języku Verilog
3
miejsce w przypadku obsługi magistrali jednoprzewodowej. Oczywiście odbywa się to kosztem liczby
fizycznych linii niezbędnych do realizacji transmisji danych.
Sprzętowa obsługa protokołu 1-wire
Na rys. 2 przedstawiono ogólny schemat blokowy układu konwertera 1-wire –> SPI. Można tu
wyróżnić klasyczny podział na część operacyjną – odpowiedzialną za przetwarzanie danych i część
sterującą zarządzającą pracą układu operacyjnego. W skład części operacyjnej wchodzą również dwa, nie
wyróżnione na rys. 2, bloki interfejsów SPI1 i SPI2.
VCC
MAGIST RALA
1W IRE
one_wire_read
one_wire_reset
bus_in
bus_out
one_wire_write
rx_activate
time_c<6:0>
bus_in
bu s_ o u t
crc _enable
reset_crc
da t a< 7 :0 >
timer
wire1_rst
zero
time_c<6:0>
da t a< 7 :0 >
bu s_ o u t
crc<7:0>
trx_activate
zero
time_c<6:0>
da t a< 6 :0 >
zero
done
load
done
done
zero
load
load
clk
clk
load
clk
clk
reset
reset
reset
OPERACYJNY
UKŁAD
RESET
reset data_out<31:0>
UKŁAD STERUJĄCY
LE D
SO1
data<31:0>
data<31:0>
SCK1
SCK
SCK
CS1
CS
CS
RDY1
SO2
SP I1
SP I2
SCK2
CS2
RDY2
Zadania pełnione przez układ operacyjny, dla lepszej przejrzystości, zgrupowano w czterech niezależnych
blokach funkcjonalnych. Pierwszy z nich to blok układu czasowego ( timer ) odpowiedzialny za
odmierzanie zadanych interwałów czasowych. Kolejne bloki to: blok generowania impulsu zerującego
( one_wire_reset ), blok realizujący zapis 8 bitów danych ( one_wire_write ) i blok odczytu 8 kolejnych
bitów z magistrali ( one_wire_read ). Zarówno układ sterujący, jak i poszczególne bloki układu
operacyjnego (z wyjątkiem timera) zrealizowane są jako odpowiednio zaprojektowane automaty
sekwencyjne.
Układ sterujący komunikuje się z układem operacyjnym poprzez szereg sygnałów zwanych mikrorozka-
zami (sygnały kierowane od układu sterującego do układu operacyjnego, np. sygnał żądania wysłania
impulsu zerującego na magistralę 1-wire) oraz sygnałami predykatowymi (sygnały kierowane od układu
operacyjnego do układu sterującego, np. sygnał potwierdzający wysłanie impulsu zerującego i obecność
urządzeń dołączonych do magistrali). Ponieważ wszystkie trzy modułu układu operacyjnego: blok gene-
rowania impulsu zerującego oraz bloki zapisu i odczytu danych, wymagają obecności układów precyzyj-
nie odmierzających czas, a w danej chwili może być aktywny (może przejmować kontrolę nad magistralą
1-wire) tylko jeden z wymienionych bloków (np. nie jest możliwy jednoczesny zapis i odczyt danych z
magistrali), dlatego też zastosowano jeden układ czasowy z odpowiednio sterowanymi, poprzez bramki
Rys.2. Schemat blokowy układu konwertera
CLK
clk
SO
SO
217708093.002.png 217708093.003.png
Konwerter 1-Wire -> SPI opisany w języku Verilog
4
OR, wejściem danych i wejściem wpisu równoległego. Blok, który jest w danej chwili nieaktywny zeruje
swoje wyjście danych do układu czasowego (stan tego wyjścia określa zadany czas do odmierzenia przez
układ czasowy; wyjście to w poszczególnych blokach oznaczone jest jako time_c ) oraz wyjście wpisu
równoległego (oznaczone jako load ). Wyjścia te są następnie dołączane do wejść trójstanowych bramek
OR, których wyjścia sterują wejściem danych i wejściem wpisu równoległego układu czasowego. W ten
sposób blok aktywn
u czasowego.
Podobnie zorganizowane jest sterowanie linią danych magistrali jednoprzewodowej. Wyjścia
danych magistrali bloków generowania impulsu zerującego oraz zapisu i odczytu danych, oznaczone
bus_out , połączone są z wejściami bramki NAND, której wyjście steruje bramką tranzystora MOSFET
bezpośrednio dołączonego do linii danych magistrali 1-wire. Blok w danej chwili nieaktywny utrzymuje
swoje wyjście bus_out w stanie wysokim. Wystąpienie stanu niskiego na jednym z wyjść bus_out ,
spowoduje pojawienie się stanu wysokiego na wyjściu bramki N
w
y może bezkolizyjnie z innymi blokami wpisać odpowiednią stałą czasową (dane) do
kładu
AND i załączenie tranzystora MOSFET
ymus
zającego poziom niski na magistrali jednoprzewodowej.
W dalszej części zostaną omówione poszczególne bloki układu operacyjnego oraz układ sterujący.
P
odana zostanie również implementacja tych bloków, opisana w języku Verilog (wirtualne komponenty).
kładu czasowego
Układ czasowy (timer) jest w rzeczywistości licznikiem z wpisem równoległym, liczącym wstecz.
W przypadku prezentowanej implementacji, timer musi być taktowany sygnałem o częstotliwości 1MHz.
Zegar ten jest następnie dzielony przez 5, w wyniku czego licznik odmierza czas z rozdzielczością 5µs,
co jest wartością zupełnie wystarczającą do celów obsługi magistrali 1-wire. Timer posiada 7-bitowe
wejście danych, którego stan przepisywany jest do licznika w momencie wystąpienia narastającego
zbocza na wejściu load wpisu równoległeg
niem przez jeden okres zegara (1µs) wyjścia zero .
Opis b
o. Osiągnięcie przez licznik stanu 0 sygnalizowane jest
ustawie
ehawioralny w języku Verilog (wirtualny komponent) modułu układu czasowego pokazano
n
a listingu 1.
L
isting 1. Wirtualny komponent układu czasowego
module timer(data,
tów
load,zero
,clk);
//deklaracje por
ata;
we/wy
input [6:0] d
input load,clk;
output zero;
reg zero,mload,z
r;
1;
reg[6:0] cnt
eg [2:0] div
r
wire cntr0;
;
a
//cntr0=0, gdy wszystki
ssign cntr0=|cntr;
e bity cntr wyzerowane
always @(posedg
begin
mload<=load;
miętanie stanu wejścia wpisu load
e clk)
//zapa
if(load&&~mload) //gdy narastające zbocze na load
begin
cntr=d
o<=1
ata; //wpis równoległy
zer
end else
begin
'b0; div=1'b0; z1<=1'b0;
div=div+
if(div==3
begin
;
1;
'd5) //dzielnik przez 5
div=0
if(cntr0) cntr=cntr-1; //licznik liczy wst
else
(!z1) begin zero<=1'b1; z1<=1'b1; end
ecz
if
//u
end
end
stawienie wyjścia zero, gdy licznik wyzerowany
i
f(z1) zero<=1'b0;
Blok u
Konwerter 1-Wire -> SPI opisany w języku Verilog
5
//wyzer
end
owanie wyjścia zero (w następnym takcie)
e
ndmodule
Blok generowania sygnału zerującego
Blok ten aktywowany jest w momencie, gdy układ sterujący ustawi w stan wysoki wejście
wire1_rst bloku. Na listingu 2 pokazano opis w języku Verilog automatu sekwencyjnego realizującego
funkcję bloku generowania impulsu zerującego.
Automat znajduje się w stanie początkowym 0 (zapis w języku Verilog n bitowej liczby w kodzie
dziesiętnym to n’dw , gdzie d jest symbolem oznaczającym podstawę dziesiętną, a w jest wartością liczby,
np. 4’d10 oznacza liczbę 10 zapisaną na 4 bitach) do momentu, gdy wystąpi stan wysoki na wejściu
wire1_rst . Wówczas stanem następnym jest stan 1. W tym stanie na 7-bitowym wyjściu time_c bloku
pojawia się odpowiednia wartość stałej czasowej dla układu czasowego, ustawiane jest wyjście load
wpisu równoległego do timera oraz ustawiany jest poziom wysoki na wyjściu bus_out (czyli na magistrali
1-wire zostanie wymuszony poziom niski). Automat pozostanie w stanie 1 aż do momentu zakończenia
odmierzania czasu przez timer, czyli do momentu, gdy na wejściu zero bloku pojawi się stan wysoki.
Wówczas automat przejdzie do stanu 2, w którym zeruje wyjście wpisu równoległego load , zwalnia
magistralę (wyjście bus_out w stanie niskim) i przechodzi do stanu 3. Po zwolnieniu magistrali, w
kolejnych stanach, automat odczekuje jeszcze pewien czas (co realizowane jest poprzez komunikację z
układem czasowym, w sposób analogiczny jak opisano to wyżej) i próbkuje stan magistrali. Jeżeli
urządzenie dołączone do magistrali, sygnalizując swoją obecność, ustawi magistralę w stan niski,
wówczas po odczekaniu dodatkowego czasu, automat ustawia wyjście done bloku, informując układ
sterujący o pomyślnie zakończonej procedurze zerowania i wraca do stanu początkowego. W przypadku,
gdy w czasie próbkowania na magistrali będzie utrzymywany poziom wysoki, wówczas automat po
ąc wyjścia done .
Listing 2. Wirtualny komponent bloku generowania sygnału zerującego
module one_wire_reset(reset
rst,
,clk,time_c,
load,wire1_rst,zero,done,bus_out,bus_in);
input clk,reset,wire1_
output done,bus_out,load;
output [6:0] time_
reg done,wire1
reg [2:0] state;
reg [6:0] tc;
zero,bus_in;
c;
_out,ld;
always @(posedge clk or nege
begin
if(~reset) state=0; else
begin
case (state)
dge reset)
3'd0: begin // Stan początkowy
'b1; done=1'b0; ld=1'
wire1_out=1
if(wire1_rs
end
3'd1: begin
tc=7'd120; wire1_out=0; ld=1'b1;
3'd2;
b0; tc=7'd0;
t==1'b1) state=3'd1;
if(zero) state=
//poziom niski na magistrali 1-wire p
end
3'd2: begin
ld=1'b0; wire1_o
//zwolnienie magis
rzez 600us
ut=1; state=3'd3;
tali
end
3'd3: begin
tc=7'd18; ld=1'b1;
if(zero) state=3'd
//odczekanie 90us
4;
end
3'd4: begin
ld=1'b0; //próbkowanie stanu magistali
0) state=3'd5; // impuls obecności OK
odczekaniu pewnego czasu również powraca do stanu początkowego, jednak nie ustawiaj
if(bus_in==1'b
217708093.004.png
Zgłoś jeśli naruszono regulamin