Ideę działania układu przedstawiono na schemacie blokowym na rysunku 1. Optyczny czujnik odległości jest zintegrowany z nadajnikiem i odbiornikiem podczerwieni, a efektem działania tego podzespołu jest analogowe napięcie na wyjściu, którego wartość określa odległość obiektu (z dokładnością do 1 cm). Napięcie zmienia się nieliniowo, kształt krzywej konwersji pokazano na rysunku 2. Napięcie z wyjścia czujnika jest podawane na wejście przetwornika ADC zintegrowanego w układzie FPGA MAX10, następnie jest konwertowane do postaci wygodnej do wyświetlenia na wyświetlaczu LED.
Ponieważ w projekcie są wykorzystywane wyświetlacze LED, konieczne jest dołączenie do płyty bazowej zestawu Maximator ekspander (wchodzi w skład zestawu) oraz dołączenia czujnika odległości. Jak widać z rysunku 2, przy zasilaniu napięciem 3,3 V zakres napięć wyjściowych mieści się w przedziale od –0,3 V do Vdd +0,3 V, co jest korzystne, gdyż przetwornik analogowo-cyfrowy użytego układu MAX10 może mierzyć napięcia z zakresu od 0 V do 2,5 V. Sposób dołączenia czujnika odległości do Maximatora pokazano na rysunku 3.
Opis projektu
Projekt dla układu FPGA składa się z kilku plików w języku VHDL oraz pliku ADC.qsys, w którym jest konfigurowany blok przetwornika analogowo-cyfrowego. Schemat blokowy projektu z podziałem na elementy opisane za pomocą języka VHDL pokazano na rysunku 4.
Blok Distance2 jest plikiem najwyższym w hierarchii oraz zawiera wszystkie bloki niezbędne do poprawnego działania projektu. Dodatkowo, w pliku Distance2 jest zaimplementowany automat sterujący, który uruchamia czujnik oraz steruje rejestrami zawierającymi się w bloku Distance2.
Blok opisany w pliku x7seg odpowiada za obsługę wyświetlacza siedmiosegmentowego. Blok opisany w pliku Counter_26m jest licznikiem 18-bitowym, używanym do zliczania czasu ok. 26 ms, co jest maksymalnym opóźnieniem poprawnych danych na wyjściu czujnika po przejściu sygnału en w stan wysoki. Blok opisany w pliku Counter_3bit jest licznikiem, za pomocą którego jest zliczany numer próbki ładowanej do akumulatora. Akumulator składa się z rejestru 15-bitowego opisanego w pliku reg_15 oraz sumatora opisanego w pliku Adder. Rejestr 12-bitowy opisany w pliku reg_12 znajduje się na wyjściu akumulatora. Wejście rejestru podłączonego do wyjścia akumulatora, jest podłączone do 12 starszych bitów rejestru 15-bitowego, jest to wartość otrzymana w akumulatorze podzieloną przez 8. Blok opisany w pliku v_to_cm jest pamięcią typu ROM, do inicjalizacji której jest używany plik ROM8.mif.
Moduły funkcjonalne
Blok Distance2 jest głównym blokiem hierarchii. Zawiera w sobie bloki niezbędne do pracy projektu oraz implementację maszyny stanów sterującą rejestrami reg_12 oraz reg_15. Jego wejścia oraz wyjścia są opisane w tabeli 1.
Automat zaczyna cykl pracy od stanu idle, w którym się znajduje, dopóki użytkownik nie naciśnie przycisku „R” na nakładce MAXimator Expander. Po wciśnięciu przycisku automat przechodzi do stanu set_en, w którym wyjście en ustawia się w stan wysoki, co uruchamia pomiar odległości czujnikiem. Jednocześnie, ustawia się licznik zliczający w dół Counter_26m w stan początkowy (same jedynki) oraz resetuje się rejestr reg_15. Dodatkowo, w tym stanie jest resetowany licznik Counter_3bit, używany do zliczania numeru próbki ładowanej do akumulatora.
W następnym stanie wait_26ms automat zostaje do chwili aż na wyjściu licznika Counter_26m pojawią się same zera, co zachodzi po upłynięciu około 26 ms, gdy licznik jest taktowany zegarem 10 MHz. W tym stanie wejście en jest nadal utrzymywane w stanie wysokim, co jest potrzebne do poprawnej pracy czujnika.
W następnym stanie, measure, próbki są ładowane z przetwornika analogowo-cyfrowego do akumulatora. Sygnał en jest nadal utrzymywany w stanie wysokim. Próbki są zliczane za pomocą licznika Counter_3bit. Gdy wyjście response_valid przetwornika analogowo-cyfrowego jest w stanie wysokim (co oznacza, że dane na wyjściu response_data są aktualne), dane są ładowane do akumulatora oraz aktywuje się na jeden cykl zegara licznik Counter_3bit.
Po załadowaniu ośmiu próbek do akumulatora automat przechodzi do stanu load_display_reg, w którym starsze 12 bitów z rejestru reg_15 są ładowane do rejestru reg_12, co jest dzieloną przez 8 wartością przechowywaną w akumulatorze, czyli wartością średnią ośmiu zmierzonych próbek. Następnie automat wraca do stanu idle.
Wyjście rejestru reg_12 jest połączone z wejściem address bloku v_to_cm, który jest pamięcią typu ROM, zawierającą skalibrowane dane długości odpowiadających poszczególnym wartościom napięć z przetwornika analogowo-cyfrowego. Pamięć zawiera 4096 słów 8-bitowych. Dane skalibrowane przechowuje się w ten sposób, że 12-bitowa wartość napięcia, mierzona przez przetwornik analogowo-cyfrowy, jest adresem odpowiadającej jej 8-bitowej wartość długości w cm. Zawartość pamięci jest przechowywana w pliku ROM8.mif.
Wyjście q bloku v_to_cm jest podłączone do wejścia x bloku x7seg, obsługującego wyświetlacz ośmiosegmentowy, w tym konwersję wartości binarnej na kod BCD. Plik x7seg jest wzięty ze strony maximator-fpga.org.
W pliku ADC.qsys jest konfigurowany przetwornik analogowo-cyfrowy. Składa się on z dwóch bloków: bloku Modular ADC core w konfiguracji ADC control core only oraz bloku PLL. Wejściowa częstotliwość zegara bloku Modular ADC core oraz wyjściowa częstotliwość zegara bloku PLL są ustawione na 10 MHz. Częstotliwość próbkowania przetwornika jest ustawiona na 1 MHz. Porty command oraz response są wyprowadzone na zewnątrz bloku ADC.qsys. Na wejścia command_valid, command_start_ofpacket oraz command_ready bloku ADC zawsze są podawane jedynki, aby przetwornik analogowo-cyfrowy był zawsze włączony. Wejście command_channel służy do wyboru kanału przetwornika analogowo-cyfrowego oraz jest utrzymywane w stanie „01110”, co jest numerem użytego kanału (wejście ANIN1 na płytce Maximator).
Żeby skalibrować czujnik od nowa, należy uruchomić miernik odległości w trybie kalibracji. W tym celu należy zakomentować/odkomentować odpowiednie sekcję w pliku Distance2. W trybie kalibracji wyjście rejestru reg_12 jest podłączone bezpośrednio do bloku obsługi wyświetlacza x7seg, czyli na wyświetlaczu ośmiosegmentowym są wyświetlane wartości 12-bitowe zmierzonego napięcia. Należy przeprowadzić szereg pomiarów odległości oraz odpowiadających im napięć, a następnie przeprowadzić aproksymacje (np. za pomocą pliku generate_ROM.m) oraz przenieść uzyskane wartości do pliku ROM8.mif.
Aleh Halauko
Więcej informacji:
Projekt powstał w Instytucie Systemów Elektronicznych WEiTI Politechniki Warszawskiej, pod kierunkiem dra inż. Mariusza Suchenka. Kody źródłowe projektu prezentowanego w artykule są dostępne do pobrania na stronie http://www.maximator-fpga.org.