Lucrand pentru proiectul meu de licenta am dat "nas in nas" cu transciever-ul bazat pe circuitul integrat NRF24L01 produs de firma NORDIC SEMICONDUCTOR. Este un device foarte ieftin, eu am cumparat 3 bucati la pretul 12 RON bucata. Deocamdata sunt faza testelor dar am considerat ca ar fi util sa impartasesc cate ceva despre aceasta jucarie. Recomand citirea posturilor anterioare privind protocolul SPI.
HERE WE GO !!
1.DETALII
TEHNICE:
- MODUL DE CONECTARE AL PINILOR SI COMENZILE SPECIFICE
Transcieverul
NRF 24L01 produs de firma NORDIC SEMICONDUCTOR foloseste pentru a
comunica cu exteriorul protocolul SPI. Din aceasta cauza pinii
descrisi in cele ce urmeaza sunt caracteristici acestui protocol.
- MOSI – master out (master=uC) slave in (transceiver)
- MISO – master in slave out
- CLK - semnalul de ceas dupa care se efectueaza transmisia
- CSN - pin utilizat ori de cate ori se comunica cu transcieverul (ACTIVE LOW)
- IRQ - interrupt request, atentioneaza ca in interiorul transcieverului s-a intamplat ceva
- CE - chip enable, se utilizeaza pentru controlul transmisiei (RX: CE=HIGH, TX: CE=LOW)
- VCC - pinul de alimentare 3.3V
- GND
Din
cele patru moduri de transmitere a informatiei prin protocolul SPI
NRF 24L01 foloseste modul "0" (CPHA=0, CPOL=0). Din acest motiv
modulul SPI din iteriorul uC trebuie setat in acest mod.
Pentru
a citii sau scrie date in registrii interni ai transcieverului se
folosesc o serie de comenzi prezentate in urmatorul tabel:
- R_REGISTER se utilizeaza pentru a citii datele din interiorul unui SFR al transcieverului. Modul de utilizare este urmatorul: in locul caracterelor "A" se introduce adresa pe care dorim sa o citim. Aceata valoare se transmite prin SPI transcieverului. In acest moment NRF-ul stie ca trebuie sa citeasca o anumita adresa. Pentru a "scoate" valoarea acesteia se mai transmite un numar de bytes egali cu latimea registrului care trebuie citit. De exemplu daca dorim sa citim un registru care are latimea de 1 byte si este localizat la adresa 01h algoritmul este urmatorul:
- CSN se face LOW;
- Se trimite prin SPI instructiunea R_REGISTER care este de forma: 0b00000001;
- Desi nu ne intereseaza este nevoie sa citim ceea ce ne trimite NRF-ul.
- Se trimite un byte oarecare ( de obicei NOP) iar ceea ce primim inapoi este chiar valoarea adresei care ne intereseaza.
- W_REGISTER se utilizeaza pentru a scrie o anumita valoare intr-un registru intern al NRF-ului. Modul de utilizare este urmatorul: in locul caracterelor "A" se introduce adresa pe care dorim sa o citim. Aceata valoare se transmite prin SPI transcieverului. In acest moment NRF-ul stie ca trebuie sa scrie la o anumita adresa. Pentru a "scrie" valoarea acesteia se mai transmite un numar de bytes egali cu latimea registrului care trebuie citit. De exemplu daca dorim sa citim un registru care are latimea de 1 byte si este localizat la adresa 03h algoritmul este urmatorul:
- CSN se face LOW;
- Se trimite prin SPI instructiunea W_REGISTER care este de forma :0b00100011;
- Desi nu ne intereseaza citim ceea ce ne trimite in aceasta faza NRF-ul;
- Trimitem pe SPI un byte care va fi scris la adresa 03h;
- Citim din nou ceea ce primim.
Inainte
de a explica R_RX_PAYLOAD si W_TX_PAYLOAD ar trebui discutat
conceptul de "payload". Payload-ul nu este altceva decat
denumirea data de producator pentru datele primite si transmise.
Atat
pe partea de transmise (TX) cat si pe cea de receptie (RX) exista
cate un registru de tip FIFO (first in first out) structurat pe cate
trei nivele. Latimea acestor nivele poate fi de la 1 la 32 bytes, in
functie de cum se seteaza payload-ul. Sa luam de exemplu RX FIFO si
sa consideram ca in modul de comunicare intre doua transceivere de
tip NRF 24L01 datele au fost setate sa aiba o latime de 5 bytes .
Emitatorul
(TX) trimte primul payload acesta este primit de catre receptor (RX)
si stocat in primul nivel al RX FIFO al acestuia. In acest moment
mai sunt libere inca doua nivele. Receptorul poate fi setat sa
citeasca primul payload sau mai poate astepata pana RX FIFO se umple
(inca doua payload-uri) si de abia dupa aceea sa citeasca succesiv
datele primite.
- R_RX_PAYLOAD se utilizaza pentru a citii datele primite. Dupa cum am vazut atunci cand transcieverul este in modul RX pinul CE este setat HIGH. Dupa ce am primit maximum 3 payload-uri (RX FIFO este plin) si minim 1, CE se setaza LOW si se trece la executarea urmatorului algoritm:
- Se trimite prin SPI 0b01100001;
- Desi nu ne intereseaza citim ce ne trimite NRF-ul;
- Se trimite un byte oarecare prin SPI NRF-ului iar ceea ce citim inapoi este de fapt byte-ul zero al payload-ului. Se continua trimiterea si citirea de bytes pana cand a fost atinsa latimea la care a fost setat payload-ul.
- W_TX_PAYLOAD se utilizeaza pentru a scrie datele in TX FIFO, adica datele care vor fi transmise. In modul TX pinul CE este setat LOW. Se executa urmatorul algoritm:
- Se trimite prin SPI 0b10100000;
- Desi nu ne intereseaza citim ceea ce ne trimite NRF-ul;
- Se incarca nivelele sau , daca se doreste, doar primul nivel al TX FIFO cu un numar de bytes egal cu latimea payload-ului. Acest lucru se face trimitand succesiv prin SPI numarul dorit de bytes avand grija sa citim in acelasi timp ceea ce ne trimite tranceiver-ul.
- Dupa ce au fost incarcate datele CE se seteaza HIGH pentru o perioda de minim 10 uS.
- FLUSH_TX si FLUSH_RX sunt folosite pentru a sterge datele existente in RX si TX FIFO.
- REUSE_TX_PL se utilizeaza pentru a transmite in mod constant aceleasi date incarcate in TX FIFO.
- NOP dupa cum ii zice si numele nu executa nimic si este folosit pentru a citii starea registrilor, de exemplu registrul STATUS.
- DESCRIEREA REGISTRILOR INTERNI
00h
. REGISTRUL CONFIG
- BIT0 – PRIM_RX seteaza modul de operare : 1 = RX , 0=TX;
- BIT1 – PWR_UP porneste sau opreste transciever-ul 1=ON, 0=OFF;
- BIT2 – CRCO modul de codare a CRC-ului 1 = 2 bytes, 0 = 1byte;
- BIT3 – EN_CRC seteaza daca CRC-ul este activ sau nu;
- BIT4 – MASK_MAX_RT seteaza daca se utilizeaza ca intrerupere depasirea numarului maxim de retransmiteri a datelor 1=se utilizeaza si se genereaza o intrerupere pe pinul IRQ, 0 = nu se utilizeaza.
- BIT5 – MASK_TX_DS seteaza daca se utilizeaza ca intrerupere trimiterea cu succes a unui pachet 1 = se genereaza o intrerupere pe pinul IRQ, 0 = nu se utilizeaza;
- BIT6 – MASK_RX_DR seteaza daca se utilizeaza ca intrerupere primirea cu succes a unui pachet 1 = se genereaza o intrerupere pe pinul IRQ, 0 = nu se utilizeaza;
- BIT7 – NU SE UTILIZEAZA
01h
. REGISTRUL EN_AA (ENHANCED SHOCKBURST)
Inainte
de a vorbi despre acest registru este necesar sa discutam putin
despre conceptul "data pipe". Sa dam urmatorul exemplu:
Sa
presupunem ca utilizam 3 transcievere (T1, T2, T3 ) astfel: Primul
dintre ele primeste datele de la celelalte doua si in functie de ceea
ce primeste trimite date celor doua transcievere inapoi.
Figura
1 : Data pipes si adresele
Cum
frecventa este fixa cum se poate afla cine a trimis primului
transciever (T1) date ? Simplu. Prin "data pipes". Fiecare
NRF24L01, in modul RX, dispune 6 astfel de "data pipes". In
functie de cum se seteaza (vom vedea mai tarziu in care registru)
payload-ul este atasat uneia dintre ele. De asemenea trebuie aleasa
si o adresa unica pentru fiecare data pipe. Privind "Figura 1"
observam ca atunci cand T1 comunica cu T2 datele sosesc la adresa A1
iar cand comunica cu T3 datele sosesc la adresa A2. Cand T1 trimite
date catre T2 adresa sa TX trebuie schimbata cu adresa de RX a data
pipe 0 a acestuia adica A1 si cu A2 cand trimite catre T2.
Revenind
la registrul de mai sus acesta are rolul de a activa "auto
acknwledgement" pentru fiecare data pipe folosita. Auto
acknwledgement inseamna autoconfirmarea primirii sau transmiterii cu
succes a datelor.
02h
. REGISTRUL EN_RXADDR
Acest
registru are rolul de a activa sau dezactiva data pipes folosite.
Revenind la exemplul de mai sus putem spune ca atunci ca deoarece T1
comunica cu alte doua transcievere atunci sunt necesare doar doua
data pipes, care se activeaza scriind "1" bitului aferent
acesteia.
03h
. REGISTRUL SETUP_AW
In
acest registru setand bitii 1:0 se fixeaza latimea adresei atat in
modul RX cat si in TX:
- '00' – nu se poate alege;
- '01' – latimea este de 3 bytes;
- '10' – latimea este de 4 bytes;
- '11' – latimea este de 5 bytes.
Este de recomandat sa se aleaga
o latime a adresei de 5 bytes deorece exista sanse mai mici de
interferenta cu alte dispozitive care functioneaza in banda de 2.4
Ghz.
04h
. REGISTRUL SETUP_RETR
Exista sansa ca nu intotdeauna
datele sa ajunga "din prima" la receptor. Acest registru
seteaza intervalul de timp la care se va face retransmisia si numarul
de retransmisii. Acesta din urma nu poate fi mai mare de 15.
05h
. REGISTRUL RF_CH
In acest registru
este setata frecventa de operare a transcieverului utilizand in acest
scop bitii 6:0. Numarul obtinut combinand acesti biti reprezinta
numarul canalului pe care opereaza transcieverul intre fiecare canal
existand un ecart de 1Mhz. Se poate deduce astfel ca exista 127 de
canale frecventa minima fiind 2.4 Ghz iar cea maxima 2.527
(2.4+0.127) Ghz.
06h
. REGISTRUL RF_SETUP
In acest registru
se seteaza puterea transmisei RF_PWR (bitii 2:1) si viteaza de
transmisie RF_DR (bitul 3).
07h
. REGISTRUL STATUS
STATUS este unul dintre cei mai
importanti registrii deoarece confera informatii despre starea
actuala a transciever-ului. Sa luam pe rand fiecare bit:
- BIT0 – TX_FULL : semnalizeaza daca mai sunt locatii libere in TX FIFO. 1 = TX FIFO este plin; 0 = mai exista locatii libere in TX FIFO
- BIT 3:1 – RX_P_NO : combinatia dintre acesti biti semnalizeaza la care din cele 6 data pipe au fost primite date. Revenind la exmplul cu cele 3 trancievere, pentru a sti de la cine a primit T1 date se verifica acesti biti. In cazul lui T2 si T3 valoarea acestor biti va fi '000' atunci cand se primeste ceva deoarece se utilizeaza numai data pipe 0
- BIT 4 – MAX_RT : flag de intrerupere atunci cand numarul maxim de retransmisii a fost atins. Ca o ciudatenie, pentru a sterge acest flag trebuie scris bitul tot cu valoarea 1 .
- BIT5 – TX_DS : flag de intrerupere care semnalizeaza daca pachetul a fost trimis cu succes. Daca AUTO_ACK este activat atunci acest bit va fi setat numai daca a fost facuta confirmarea primirii cu succes a pachetului.
- BIT6 – RX_DS : flag de intrerupere care semnalizeaza daca pachetul a fost primit cu succes.
08h
. REGISTRUL OBSERVE_TX
- BIT 3:0 – ARC_CNT : numara de cate ori au fost retransmise pachetele pentru o anumita data pipe. Daca se transmite un pachet nou numaratoarea se reseteaza.
- BIT 7:4 – PLOS_CNT : numara de cate ori a fost a fost retransmis un pachet pentru numarul maxim de retransmisii setat in registrul SETUP_RETR prin bitii 3:0 (ARC). De exemplu daca se setaeza ARC=1111 adica maximum posibil (15) si daca numarul de retransmisii a depasit aceasta valoare atunci PLOS_CNT se incrementeaza cu +1. Numarul maxim inregistrat este 15. Dupa aceasta valoare nu se mai inrcrementeza pana la reset.
Acest registru are rolul de a
ne ajuta sa ne dam seama daca calitatea semnalului este buna in zona
in care dorim sa lucram. Daca se pierd multe pachete atunci fie
distanta este prea mare fie ar trebui schimbata frecventa in
registrul RF_CH.
09h
. REGISTRUL CD (carrier detect)
Un singur bit se foloseste in
acest registru : bitul 0. Citind acest bit se poate verifica daca
cineva sau "ceva" transmite pe frecventa NRF-ului.
In registrii 0Ah
: 0Fh se seteaza adresele data pipes utilizate.
Latimea maxima a adresei
fiecarei data pipe este de 5 bytes, aceasta setandu-se in registrul
SETUP_AW. Pentru RX_ADDR_P0 si RX_ADDR_P1 aceasta adresa poate fi
orice combinatie de maxim 5 bytes. Pentru RX_ADDR_P2, RX_ADDR_P3,
RX_ADDR_P4 si RX_ADDR_P5 primii bytes sunt identici cu cei ai
RX_ADDR_P1 iar ultimul byte se incrementeaza cu +1 asa cum este
aratat in tabel.
Revenind la exemplul cu cele 3
transcievere (T1, T2, T3) in acesti registrii se vor seta urmatoarele
adrese:
- pentru T1 adresa RX_ADDR_P0 = A1 ; RX_ADDR_P1=A2;
- pentru T2 adresa RX_ADDR_P0 este A1;
- pentru T3 adresa RX_ADDR_P0 este A2,
unde A1, A2, A3 sunt adrese cu
o latime de la 1 la 5 bytes.
10h
. REGISTRUL TX_ADDR
In
acest registru este setata adresa de transmise a transciever-ului.
Latimea acesteia fiind setata in registrul SETUP_AW.
Pentru
cele trei transcievere aceasta adresa se seteaza in modul urmator:
- pentru T1 daca comunica cu T2 TX_ADDR=A1 iar daca comunica cu T3 este egala cu A2;
- pentru T2 TX_ADDR=A1;
- pentru T3 TX_ADDR=A2,
unde A1, A2, A3 sunt adrese cu
o latime de la 1 la 5 bytes.
In registrii 011h : 016h
se seteaza latimea payload-ului pentru fiecare data pipe:
Pentru a utiliza payload-ul
trebuie seatata macar o latime de 1 byte. Apeland din nou la exemplul
cu cele 3 transcievere si presupunand ca T1 schimba cu T2 date care
au latimea de 2 bytes si cu T3 de 5 bytes se pot face setarile:
- pentru T1: RX_PW_P0 = 000010, RX_PW_P1 = 000101;
- pentru T2 : RX_PW_P0 = 000010 ;
- pentru T3: RX_PW_P0 = 000101 .
17h
. REGISTRUL FIFO_STATUS
Acest registru ofera
informatiile necesare pentru aflarea starii celor doi registrii:
RX_FIFO si TX_FIFO.
Cam asta ar fi in partea de descriere a NRF 24L01. Voi incerca sa postez in cel mai scurt timp un mini algoritm de configurare.
Niciun comentariu:
Trimiteți un comentariu