Moduł do komunikacji radiowej rs12b Kornel Jakubczyk
Transkrypt
Moduł do komunikacji radiowej rs12b Kornel Jakubczyk
rf12b Moduł do komunikacji radiowej rs12b Kornel Jakubczyk Agenda Ogólnie Piny i podłączenie Wysyłanie i odbiór Przykład kodu wraz z omówieniem konfiguracji Kod z http://loee.jottit.com/ Właściwości Zintegrowany nadajnik/obiornik Komunikacja SPI Dodatkowo wymaga tylko anteny, ew zewnętrznego kryształu, mikrontrolera Może służyć do budzenia mikrontrolera przerwaniem Automatyczne poprawki częstoliwości Konfigurowalne wyjście informujące o sile sygnału (RSSI) Właściwości cd Wykrywanie niskiego poziomu baterii Wbudowany timer budzący po wykryciu nadawanego sygnału 16 bitowy bufor na odbierane dane rf12b Zasilanie zalecane 3.3V (Ponoć 5V powinno działać) Zasięg w otwartej przestrzeni conajmniej kilkadziesiąt metrów, ponoć nawet kilkaset Po starcie mikrokontrolera należy odczekać 100-200ms na start modułu? Wymaga zasilania dobrej jakości? Po wysłaniu ramki również należy nieco odczekać? Więcej w linku do forum elektroda.pl Zauważmy podłączenie Przykład podłączenia Piny 1 SDI wejście danych SPI (do MOSI) 2 SCK wejście zegar SPI 3 nSEL (do SlaveSelect) SPI (aktywne przy niskim poziomie) 4 SDO wyjście SPI 5 nIRQ wyprowadzenie przerwania (aktywne przy niskim poziomie) Piny cd 6 nFFS wejście uruchamia podawanie zawartości fifo na pinie SDO (w stanie niskim) 7 FFIT przerwanie pełnego FIFO (aktywne w stanie wysokim) 8 CLK wyjście zegara dla mikrokontrolera 9 zewnętrzne napięcie referncyjne 10 nRES reset 16 VDI wyjście sygnalizujące odbiór poprawnych danych Potencjalne źródła przerwania Gotowość do odbioru następnego bajtu rejestru nadawania FIFO otrzymało odpowiednią ilość bitów Power-on reset (POR) Przepełnienie FIFO / underrun rejestru nadawania Wake-up timer timeout (WKUP) Impuls na nINT (EXT) Napięcie zasilania poniżej zaprogramowanej wartości (LBD) Komunikacja Polecenia do nadajnika wysyłane są przez SPI. Bity na wejściu SDI są czytane przy rosnącym zboczu zegara SCK, gdy pin nSEL (SS) jest w stanie niskim. Rozróżniane jest 17 poleceń, większość 16 bitowych Kiedy stan nSEL jest wysoki, aktywny jest interfejs szeregowy. MSB wysyłane są pierwsze Power On Reset (POR) resetuje wszystkie ustawienia Tryby pracy ”szeregowy” generowany jest sysgnał zegara dla danych, a innym pinie generowane (lub chyba odbierane) są same dane (odpowiednio na pinach 7 i 6) (nie będziemy omawiać) Z użyciem rejestru danych, wymaga włączenia bitu el i podłączenia pinu DATA do wysokiego poziomu napięcia Odbiór z użyciem FIFO 16 bitów wypełnianych, kiedy wykryte są prawidłowe dane, co może sygnalizować pin VDI Znów dwa tryby: Za pomocą przerwania – można skonfigurować je po odebraniu wskazanej liczby bitów, po otrzymaniu przerwania należy sprawdzić status i odczytać zawartość FIFO poleceniami SPI Za pomocą odpytywania – należy ustawić przerwanie po odebraniu 1 bitu, również można użyć poleceniami SPI do odczytu Polling read mode Rekomendwany rozmiar pakietów Preambuła Synchron word (id sieci) CRC minimum 4 - 8 bitów (1010b lub 0101b) D4h (ustawialne) 4bity do 1 bajt zalecane 8 -12 bit (np. AAh lub 55h) 2DD4h (cześć D4 jest ustawialna) 2 bajty Nadawanie z użyciem rejestru 2 rejestry 8 bitowe, wykorzystywane naprzemian Inicjowane na AAh co odpowiada preambule Należy włączyć bit el, jego wyzerowanie czyści rejestry Pin SDO sygnalizuje gotowość do odebrania bajtu Przykład w przykładzie Wykres Odczyt statusu Jedyna komenda zaczynająca się od zera (więc wystarczy samo zero) Po jego odebraniu kolejne bity są taktowane na pin SDO Komenda odczytu czyści bity Obrazek Ciekawsze bity Powód przerwania, w tym pierwszy bit to FFIT, być może wystarczy więc odczytać tylko go, ignorując resztę co może upraszcza program Wykrycie odpowiednio silnego sygnału OFFS – znak i wartość o które należy zmienić aktualną częstotliwość w celu dostowania do nadajnika Przykład Przykładowy kod z noty jest wadliwy, trzeba zmienić przynajmniej konfigurację odbiornika Rozważymy więc inny może lepszy na początek Autor twierdzi, że działa Szczegóły poleceń SPI w nocie katalogowej Link do przykładu na końcu Programowe SPI int writeCmd(unsigned int cmd) { recv = 0; LO(SCK); LO(CS); for(i=0; i<16; i++) { if(cmd&0x8000) HI(SDI); else LO(SDI); HI(SCK); recv<<=1; if( PINB&(1<<SDO) ) { recv|=0x0001; } LO(SCK); cmd<<=1; } HI(CS); return recv; } Konfiguracja nadajnika Configuration Setting Command writeCmd(0x80E7); //EL,EF,868band,12.0pF Bit 7 el wewnętrzny rejestr Bit 8 ef włącza FIFO 5-4 wybór częstotliwości 3-0 Crystal Load Capacitance Power Management ● writeCmd(0x8239); //!er,!ebb,ET,ES,EX,!eb, !ew,DC Bity do ustawienia Er odbiornik Ebb układ od czestotliwości nośnej odbiornika Et ogólnie elementy nadajnika Es synthesizer włączany też przez et Ex oscylator Ew Wakeup Timer, eb low battery DC – wyłącza zegar dla mikrokontrolera Kontrola częstotliwości writeCmd(0xA640); //frequency select Parametr F – bity 11-0 Powinien być między 96 i 3903 f0 = 10 * C1 * (C2 + F/4000) [Mhz] Gdzie dla 868 Mhz C1=2 i C2=43 Czyli z grubsza 860.48 do 879.51 Data Rate Command writeCmd(0xC647); //4.8kbps Konfiurowalne od 600 bps do 115.2 kbps Bit 7 cs 6-0 parametr R BitRate = 10000 / 29 / (R+1) / (1+cs*7) [kbps] Dotyczy chyba tylko odbiornika? Receiver Control Command writeCmd(0x94A0); //VDI,FAST,134kHz,0dBm,-103dBm Bit 10 – funkcja pinu 16 1-VDI 0-wejście przerwania 9-8 tryb i czas odpowiedzi układu rozpoznawania danych patrz nota 7-5 Receiver baseband bandwidth 4-3 wzmocnienie sygnału (LNA) 2-0 poziom wykrywania dobrego sygnału RSSI Filtrowanie danych i clock recovery Tryb cyfrowy – próbkuje z częstotliwością 29 razy bit rate. W tym trybie dostępny jest układ CR który podaje zegar wg danych, używany do wypełniania FIFO Tryb slow a Tryb fast – pierwszy daje wyższą odporność na szumy, ale wymaga dokładniej taktowanych danych tryb, dłuższej preambuły Tryb automatyczny, który przełącza między tymi dwoma Data Filter Command writeCmd(0xC2AC); //AL,!ml,DIG,DQD4 7 AL tryb automatyczny clock recovery – tu zaczyna w trybie fast i przechodzi do slow 6 ml wybór między slow a fast 0 - slow 4 typ filtru dancyh tu cyfrowy (tylko ten działa z FIFO) patrz nota 2-0 DQD poziom wykrywania dobrych dancyh FIFO and Reset Mode Command writeCmd(0xCA81); //FIFO8,SYNC,!ff,DR 7-4 ilość bitów w FIFO generująca przerwanie 3 sp ilość bajtów synchronizacji (1 lub 2) tu 2 2 ff pozwala resetować FIFO 1 ff wypełniaj FIFO po odebraniu bajtów synchronizacji 0 DR wyłącza wysoką czułość układu na zakłucenia zasilania resetu Synchron pattern Command writeCmd(0xCED4); //SYNC=2DD4 7-0 programowalny bajt synchronizacji (cześć D4) 10.Auto. Freq. Control writeCmd(0xC483); //@PWR,NO RSTRIC,!st,! fi,OE,EN 7-6 konfiguracja AFC kiedy dokonuje pomiaru patrz nota 5-4 limit na wartość offsetu częstotliwości tu brak 2 Fi – tryb wysokiej dokładności 1 OE włącza rejestr na offset 0 EN włącza całość TX Configuration Control Command writeCmd(0x9850); //!mp,90kHz,MAX OUT fout = f0 + (-1)SIGN * (M + 1) * (15 kHz) Gdzie f0 było wcześniej M bity 7-4 Bit 8 mp zmienia SIGN na przeciwny 2-0 moc wyjściowa nadajnika PLL Setting Command writeCmd(0xCC17); //!OB1, !OB0, LPX, Iddy, CDDIT, CBW0 6-5konfiguracja sygn. zegara dla mikrontorlera I inne patrz nota Wake-Up Timer Command writeCmd(0xE000); //NOT USED Pozwala ustawić czas tego zegara Low Duty-Cycle Command writeCmd(0xC800); //NOT USED Pozwala oszczędzać energię zamiast generować przerwanie zega, co określony tam czas sprawdza czy nie jest nadawany sygnał Wymaga kilkukrotnego nadania pakietu przez nadawcę tak aby odbiornik mógł odebrać całość I koniec inicjalizacji Low Battery Detector and Microcontroller Clock Divider Command writeCmd(0xC040); //1.66MHz,2.2V 7-5 dzielnik częstotliwości dla mikrokntrolera 3-0 V próg niskiego napięcia = 2.2 + V * 0.1 [V] Wysyłanie void rfSend(unsigned char data){ while(WAIT_NIRQ_LOW()); writeCmd(0xB800 + data); } Transmitter Register Write Command Bity 7-0 bajt do zapisania w rejestrze Jak wysłać kilka bajtów I main Odrobina spania przy starcie while(1){ LED_ON(); writeCmd(0x0000); // status read ponoć nie działa bez tego 3x rfSend(0xAA); // PREAMBLE rfSend(0x2D); rfSend(0xD4); // SYNC for(i=0; i<16; i++) { 3x rfSend(0x30+i); } rfSend(0xAA); // DUMMY BYTES LED_OFF(); for(i=0; i<10000; i++) // some not very for(j=0; j<123; j++); // sophisticated delay } Odbiornik Inicjalizacja już była różnica tylko writeCmd(0x8299); //er,!ebb,ET,ES,EX,!eb,! ew,DC Czyli włączamy odbiornik Odbiór będzie we wspomnianym już trybie poll Odbieranie unsigned char rfRecv() { unsigned int data; while(1) { data = writeCmd(0x0000); // odczytaj status if ( (data&0x8000) ) { // czekamy na dane data = writeCmd(0xB000); //odczyt return (data&0x00FF); } } Reciver FIFO Read Komenda 0xB000 można odczytać (do??) 8 bitów FIFO reset FIFO and Reset Mode Command void FIFOReset() { writeCmd(0xCA81); writeCmd(0xCA83); } I składając razem int main(void) { unsigned char data, i; LED_ON(); portInit(); rfInit(); FIFOReset(); while(1) { for (i=0; i<16; i++) { data = rfRecv() // tu mamy odbiór } FIFOReset(); } Koniec Teraz czy zadziała? Źródła Nota http://www.hoperf.com/rf_fsk/rf12b.htm http://www.elektroda.pl/rtvforum/topic890223-30.htm Przykład http://loee.jottit.com/rfm12b_and_avr_-_quick_start