Академический Документы
Профессиональный Документы
Культура Документы
отсюда.
Довольно таки известный радио модуль. Вот решил попробовать сие изобретение человечества. Цель статьи это быстрый старт.
Скажем передача байта от одного радио модуля к другому и обратно. Пихаем байт в USART, из USART он попадает уже в SPI радио
модуля и далее в пространство. Это все. Никаких ненужных лишних подробностей, которые не касаются быстрого старта.
nRF24L01+ работает по SPI интерфейсу. Это значит что нужна какая нибудь платка с микроконтроллером, на борту которого имеется
SPI интерфейс. Такую платку можно сделать самому или нарыть готовую. Я пошел по второму пути. И нарыл вот такую…
Готовая такая платка для работы с nRF24L01+. Ничего лишнего. Описание и схема платы есть на сайте. Плата разработана на базе
любимыми многими МК Atmega8. На плате выведены ноги МК RESET, SCK, MISO, MOSI. Это значит, что в плату можно залить свою
прошивку, удалив существующую. Что я и решил сделать. Та прошивка которая есть в плате, позволяет по USART отправлять байты
другому радио модулю. Удобно однако. Это значит можно вообще не думать про сам радио модуль. Просто отправляй нужные тебе
байты, а с другой стороны принимай. Вот и все, быстро и удобно. Кому не охота разбираться с самим радио модулем само то. Но в
таком случае разобраться как работает сам радио модуль нам не светит. Поэтому будем грызть железку сами.
/*НАСТРОЙКА ПОРТОВ*/
#if 1
DDRB = 0b11101111; //если 0 значит вход
PORTB = 0b00010100; //если 1 подтяжка включена
DDRC = 0b00001110;
PORTC = 0b11110001;
DDRD = 0b10000000;
PORTD = 0b01111111;
#endif
Начнем пожалуй с интерфейса SPI. В Atmega8 для его настройки существует всего два регистра SPCR и SPSR. В регистре SPCR битом
SPE — включим интерфейс SPI. А битом MSTR — укажем что наш МК будет мастером, то есть обмен данными с радио модулем будем
всегда начинать мы (других вариантов и нету). В регистре SPSR битом SPI2X — ускорим скорость SPI до максимума. Ну это я так
сделал чисто для теста. Этого можно не делать. На этом настройка SPI закончена.
/*Настройка SPI*/
#if 1
SPCR = (0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(0<<SPR0);
/* SPIE - разрешение прерывания от SPI, 1-ON,0-OFF
SPE - вкл/выкл SPI, 1-ON,0-OFF
DORD - порядок передачи данных. 1-байт передается с младшего бита, 0->7
0-байт передается со старшего бита.7->0
MSTR - Выбор режима (Master/Slave) 1-Master, 0-Slave
CPOL - полярность тактового сигнала 0-импульсы положительной полярности
1-импульсы отрицательной полярности
CPHA - Фаза тактового сигнала 0-биты считываются по переднему фронту ноги SCK
1-биты считываются по заднему фронту ноги SCK
SPR1 - Скорость передачи
SPR0 - Скорость передачи
SPI2X SPR1 SPR0 Частота SCK
0 0 0 F_CPU/4
0 0 1 F_CPU/16
0 1 0 F_CPU/64
0 1 1 F_CPU/128
1 0 0 F_CPU/2
1 0 1 F_CPU/8
1 1 0 F_CPU/32
1 1 1 F_CPU/64
*/
SPSR = (0<<SPIF)|(0<<WCOL)|(1<<SPI2X);
/*Настройка USART*/
#if 1
uint8_t a=(PIND>>2) & 0b00000111;//это мы считали состояние нашего селектора скорости и в следующем блоке кода
//установим скорость USART.
switch (a)
{
case 0:UBRRL=3;//115200 000
break;
case 1:UBRRL=5;//76800 001
break;
case 2:UBRRL=7;//57600 010
break;
case 3:UBRRL=11;//38400 011
break;
case 4:UBRRL=15;//28800 100
break;
case 5:UBRRL=23;//19200 101
break;
case 6:UBRRL=31;//14400 110
break;
case 7:UBRRL=47;//9600 111
break;
default:UBRRL=47;
break;
}
UCSRA = (0<<RXC)|(0<<TXC)|(0<<UDRE)|(0<<FE)|(0<<DOR)|(0<<PE)|(0<<U2X)|(0<<MPCM);
/* RXC - Флаг завершения приема. Флаг устанавливается в 1 при наличии
непрочитанных данных в буфере приемника (регистр данных UDR). Сбрасывается
флаг аппаратно после опустошения буфера. Если бит RXCIE0
регистра UCSR0B установлен, то при установке флага генерируется
запрос на прерывание «прием завершен»
TXC - Флаг завершения передачи. Флаг устанавливается в 1 после передачи всех
битов посылки из сдвигового регистра передатчика при условии, что в регистр
данных UDR не было загружено новое значение. Если бит TXCIE0
регистра UCSR0B установлен, то при установке флага
генерируется прерывание «передача завершена». Флаг сбрасывается аппаратно при
выполнении подпрограммы обработки прерывания или программно, записью
в него лог. 1
UDRE - Флаг опустошения регистра данных. Данный флаг устанавливается в 1
при пустом буфере передатчика (после пересылки байта из регистра данных
UDR в сдвиговый регистр передатчика). Установленный флаг означает,
что в регистр данных можно загружать новое значение. Если бит UDRIE
регистра UCSR0B установлен, генерируется запрос на прерывание «регистр
данных пуст». Флаг сбрасывается аппаратно, при записи в регистр данных
FE - Флаг ошибки кадрирования. Флаг устанавливается в 1 при обнаружении
ошибки кадрирования, т. е. если первый стоп-бит принятой посылки равен 0.
Флаг сбрасывается при приеме стоп-бита, равного 1
DOR - Флаг переполнения. Флаг устанавливается в 1, если в момент обнаружения
нового старт-бита в сдвиговом регистре приемника находится последнее
принятое слово, а буфер приемника полон (содержит два байта). Флаг
сбрасывается при пересылке принятых данных из сдвигового регистра
приемника в буфер.
UPE - Флаг ошибки контроля четности. Флаг устанавливается в 1, если в данных,
находящихся в буфере приемника, выявлена ошибка контроля четности.
При отключенном контроле четности этот бит постоянно сброшен в 0
U2X - Удвоение скорости обмена. Если этот бит установлен в 1, то коэффициент
деления предделителя контроллера скорости передачи уменьшается с 16 до
8, удваивая тем самым скорость асинхронного обмена по последовательному
каналу. Этот бит используется только при асинхронном режиме работы
и в синхронном режиме должен быть сброшен
MPCM - Режим мультипроцессорного обмена. Если этот бит установлен в 1, ведомый
микроконтроллер ожидает приема кадра, содержащего адрес. Кадры,
не содержащие адреса устройства, игнорируются */
UCSRB = (1<<RXCIE)|(0<<TXCIE)|(0<<UDRIE)|(1<<RXEN)|(1<<TXEN)|(0<<UCSZ2)|(0<<RXB8)|(0<<TXB8);
/* RXCIE - Разрешение прерывания по завершении приема. Если данный бит установлен
в 1, то при установке флага RXC0 регистра UCSR0A генерируется прерывание
«прием завершен» (если флаг I регистра SREG установлен в1)
UDRIE - Разрешение прерывания при очистке регистра данных UART. Если данный бит
установлен в 1, то при установке флага UDRE регистра UCSRA
генерируется прерывание «регистр данных пуст» (если флаг I
регистра SREG установлен в 1)
UCSZ2 - Формат посылок. Этот бит совместно с битами UCSZ01:0 регистра UCSR0C
используется для задания размера слов данных, передаваемых по
последовательному каналу.
RXB8 - 8-й бит принимаемых данных. При использовании 9-битных слов данных этот
бит содержит значение старшего бита принятого слова. Содержимое этого
бита должно быть считано до прочтения регистра данных UDR0.
TXB8 - 8-й бит передаваемых данных. При использовании 9-битных слов данных
содержимое этого бита является старшим битом передаваемого слова.
Требуемое значение должно быть занесено в этот бит до загрузки байта данных в
регистр UDR0 */
UCSRC = (1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)|(0<<UCPOL);
/*
Режим работы USART
-----------------------------------
UMSEL Режим работы USART
-----------------------------------
0 Асинхронный USART
1 Синхронный USART
-----------------------------------
Как работает USART разбираться не будем, (уже разобрано не один раз) ибо тема сейчас другая. Этот кусок кода можно
скопировать, и при желании разобраться потом.
Вот как бы с настройкой МК все. Теперь надо бы слегка вникнуть в сам радио модуль. В чипе nRF24L01+ есть память ОЗУ. То есть
набор байтов. В эти байты надо в нужные места воткнуть нули или единицы. Ну точно так же как мы это сделали с Atmega8 выше.
Воткнув их радио модуль будет готов к работе. Для начала ознакомимся с некоторыми регистрами радио модуля.
Регистр STATUS — самый популярный и часто используемый регистр. В нем находится информация что происходит с нашим радио
модулем. Ну значит определим его и его биты для использования в нашей программе. То что не прокомментировано, значит это для
быстрого старта пока не надо.
/*регистр STATUS*/
#define STATUS 0x07
#define RX_DR 6 /*прерывание: данные получены. Для сброса записать 1.*/
#define TX_DS 5 /*прерывание: данные переданы. Для сброса записать 1.*/
#define MAX_RT 4 /*прерывание: данные не переданы. Для сброса записать 1.*/
#define RX_P_NO2 3
#define RX_P_NO1 2
#define RX_P_NO0 1
#define TX_FULL0 0 /*флаг переполнения TX FIFO буфера передачи. 1-переполнен, 0-есть еще место.*/
Как видим адрес регистра STATUS 0х07. Всего у нас регистров управления nRf24L01 аж 29 штук. Следующий по нужности регистр
это регистр CONFIG. Определим и его.
#define RX_PW_P0 0x11//указываем в нем из скольких байтов будет состоять наше поле данных для отправки.
Сейчас надо разобраться как считать данные из регистра и записать новые данные. Для этого есть команды. Всего команд в нашем
радио модуле 12. Вот они.
Но перед этим еще определим пару макросов для удобной и наглядной работы с битами.
IRQ — выход прерывания. Когда все пучком, то нога находится прижатой к питанию (высокий уровень). Но как только что нибудь
произошло, например их космоса/в космос поймали/отправили байт, или байт не отправился, то этот пин сразу падает на землю. Как
тока он упал, надо все бросить и считать регистр STATUS. И в этом регистре уже конкретно видно что произошло. Это видно из трех
битов-флагов — RX_DR, TX_DS, MAX_RT. Что они означают выше прокомментировано. Как только стало ясно какие биты равны
значению 1, их тут же надо сбросить, записью 1. Иначе нога IRQ всегда будет лежать на земле. Причем сбросить надо только те
биты в которых значение 1. Те в которых 0 писать ничего ненадо, ну 0 можно записать, но не 1. Иначе IRQ опять упадет на землю.
CE — вход. Если модуль в режиме приема, то СЕ прижимаем к питанию. Если режим передачи, то СЕ лежит на земле. И когда надо
передать байт, СЕ поднимаем к питанию не менее чем на 10 мксек, потом снова прижимаем к земле. Байт улетел в пространство.
CSN — вход. Всегда находится прижатым к питанию. Если надо что то записать/считать в радио модуль, то перед началом любых
телодвижений прижимаем к земле. Записали/считали — прижимаем снова к питанию.
CSK, MOSI, MISO — пины SPI интерфейса. Подключаются к одноименным выводам МК. MISO определяем на вход, MOSI, CSK на
выход. Все это делаем ручками, так как при включения интерфейса SPI эти выводы сами по себе не переопределяются по
назначению.
Вывод: всегда 1й вывалившийся байт из SPI радиомодуля это будет значение байта STATUS. Что бы мы туда не писали это будет
железно значение STATUS. Не всегда это надо, если не надо то этот байт можно игнорировать. Итак функция чтения регистра статус
может иметь такой вид.
Как раз таки на этих 135 мксек я и погорел. После смены значение бита PRIM_RX радио модуль находится в неопределенном
состоянии в течении 135 мксек. В этот момент в него нельзя ничего писать. Все равно не поймет. Так что эта выдержка обязательна.
Кстати шаг 1 и 2 делается один раз в начале инициализации модуля, а потом только меняем значение бита PRIM_RX и ноги СЕ.
w_register(CONFIG,(1<<PWR_UP)|(1<<EN_CRC)|(0<<PRIM_RX));
_delay_ms(2);
w_register(CONFIG,(1<<PWR_UP)|(1<<EN_CRC)|(1<<PRIM_RX));
SetBit(PORTC,CE);
_delay_us(135);
//режим према RX
А так переводим на передачу данных
ClearBit(PORTC,CE);
w_register(CONFIG,(1<<PWR_UP)|(1<<EN_CRC)|(0<<PRIM_RX));
_delay_us(135);
Перед всеми манипуляциями с модулем один раз в начале в момент инициализации надо в регистре RX_PW_P0 указать чему будет
равен размер поля данных. В нашем случае будем стрелять по одному байту. Поэтому поле будет равно 1 байту. Максимум можно до
32 байт.
В обычном режиме модуль все время находится на приеме данных. А что делать если вдруг модуль поймал байт от другого модуля? В
главном цикле можно замутить опрос флагов прерываний. И анализируя эти флаги можно выяснить, принят ли байт.
if (BitIsClear(PINC,IRQ))//если нога IRQ упала, значит надо выяснить, может принят байт?
{
uint8_t a= r_register(STATUS);//прочитали статус регистр
w_register(STATUS, a);//сброс флагов прерываний - обязательно
if (BitIsSet(a,RX_DR))//если этот бит равен 1 то байт принят.
{
buff_RX[IN_RX++]=r_register(R_RX_PAYLOAD);//чтение 1 байта из буфера приема RX_FIFO в озу buff
и отправка в USART.
}
}
Байты ведь могут сыпаться один за одним. И если пытаться принятые байты пихать сразу в USART, то особо ничего не выйдет. Ибо
скорость работы SPI и USART очень сильно отличаются. Поэтому кажется неплохо бы замутить кольцевые буфера. В один буфер
складывать данные которые получены, а в другой складывать то, что надо отправить в эфир. Ну и потом пусть по прерываниям сам
МК выгребает данные и распихивает их по интерфейсам, отправляемые в SPI, принятые в USART.
В главном цикле
if (IN_TX != OUT_TX)//если конец и начало не совпадают значит в буфер отправки что то попало из USART. И это что то
надо выдать в эфир
{
send_byte(buff_TX[OUT_TX++]);//отправим из буфера 1 байт в пространство.
}
Весь проект как есть выкладываю в топик. Писал в AtmelStudio6.2. Он сильно черновой и с магическими числами, но рабочий.
Прошивку можно сразу загрузить в платку и она будет работать. Если что, то код можно напильником допилить. Надо бы будет как
нибудь, замутить статью про более продвинутые возможности данного радио модуля.
симальная мощность передатчика самого чипа (без внешних усилителей) – 0dBm (1мВт); чувствительность
приёмника -82dBm при скорости 2Мбит/с, и -85dBm при скорости 1Мбит/с.
Чип работает на частотах в диапазоне 2400-2525 МГц. Конкретная частота из этого диапазона с шагом в 1МГц
задаётся настройками.
Энергопотребление чипа составляет около 0,9мкА в режиме power-down, до 11,3мА при передаче, и до 13,5мА при
приёме, и 26 и 320мкА в режимах готовности (standby-I и standby-II). Использование автоматизации в передаче
пакета позволяет минимизировать время нахождения в энергоёмких режимах, тем самым значительно снижая
энергопотребление устройств работающих в режиме передатчика.
Чип может работать как в режиме приёмника, так и в режиме передатчика, но в каждый момент времени может
находиться только в одном из этих двух состояний. Формирование пакетов и контроль передачи происходит
автоматически. Максимальная длина полезного содержимого пакета – 32 байта.
И приёмник и передатчик используют очереди FIFO на три элемента каждая. В каждый элемент очередь
помещается всё содержимое пакета сразу, и извлекаться из очереди должно также за одну операцию чтения.
Приёмник поддерживает получение данных по шести каналам, в зависимости от переданного адреса. Каналы 1-5
различаются только младшим байтом адреса. Адрес канала 0 может быть настроен независимо, но при передаче
этот канал используется для получения подтверждений приёма.
Назначение выводов
GND
Общий, "земля".
VCC
Питание, от 1.9 до 3.6 Вольт. Однако, если напряжение на линиях MOSI, SCK, CE, SN более 3.6 Вольт, то Н
напряжение питания должно быть в пределах 2.7 - 3.3 Вольт. а
CE
Входной, активный - высокий уровень. Наличие высокого уровня на этом входе активирует режим приёма. В
режиме передачи импульс не менее 10мкс начинает передачу.
CSN
Входной, активный - низкий уровень. Низкий уровень устанавливает границы сеанса обмена по шине SPI.
SCK
Входной. Тактовый импульс для обмена по шине SPI. Данные на линиях MOSI и MISO считываются Р
противоположной стороной по нарастающему фронту на линии SCK, и выставляются по спаду. а
MOSI
Входной. Линия SPI, передающая данные от микроконтроллера к радио-модулю.
MISO
IRQ
С
Выходной, активный - низкий уровень. При наличии одного из прерываний устанавливается низкий уровень на о
этой линии.
Команды
Сеанс обмена начинается с установки низкого уровня на линии CSN. Первый переданный после этого от
микроконтроллера байт является командой. Одновременно с байтом команды от микроконтроллера, к
микроконтроллеру по линии MISO передаётся байт статуса.
Перечень команд:
16-
Дво
чн
Наименован ичн Размер Описан
ый
ие ый данных ие
ко
код
д
Прочита
0x0
000n 1-5 ть
R_REGISTER 0+
nnnn (приём) регистр
n
n
Записат
0x2 1-5
001n ь
W_REGISTER 0+ (переда
nnnn регистр
n ча)
n
Записат
ьв
очередь
1-32 передат
W_TX_PAYLO 1010 0xA
(переда чика
AD 0000 0
ча) данные
для
отправк
и
Сбросит
ь
1110 0xE
FLUSH_TX 0 очередь
0001 1
передат
чика
Сбросит
ь
1110 0xE
FLUSH_RX 0 очередь
0010 2
приёмн
ика
Использ
овать
повторн
о
1110 0xE
REUSE_TX_PL 0 последн
0011 3
ий
передан
ный
пакет
Прочита
ть
размер
данных
принято
го
пакета
в
начале
очереди
приёмн
ика.
Значени
е
0110 0x6 1 больше
R_RX_PL_WID
0000 0 (приём) 32,
означае
т
ошибку
приёма,
в таком
случае
пакет
должен
быть
удалён
командо
й
FLUSH_
RX
Записат
ьв
очередь
передат
чика
данные
для
1-32
W_TX_PAYLO 1011 0xB отправк
(переда
AD_NOACK 0000 0 и, для
ча)
которых
не
требует
ся
подтвер
ждение
приёма.
Все байты данных, сопутствующие команде должны быть переданы/получены в течение одного сеанса обмена.
Сеанс обмена завершается установкой высокого уровня на линии CSN
Регистры
0x00 CONFIG
Регистр настроек.
7 6 5 4 3 2 1 0
P
E P
R
MA MA MAS N C W
I
SK_ SK_ K_M _ R R
- M
RX_ TX_ AX_ C C _
_
DR DS RT R O U
R
C P
X
0x01 EN_AA
7 6 5 4 3 2 1 0
EN EN EN EN EN EN
AA AA AA AA AA AA
- -
_P _P _P _P _P _P
5 4 3 2 1 0
0x02 EN_RXADDR
7 6 5 4 3 2 1 0
ER ER ER ER ER ER
- - X_ X_ X_ X_ X_ X_
P5 P4 P3 P2 P1 P0
0x03 SETUP_AW
7 6 5 4 3 2 1 0
- - - - - - AW
AW - два бита, задающие длину поля адреса: 01 - 3 байта; 10 - 4 байта; 11 - 5 байт.
Эта настройка влияет на передачу и приём пакетов по всем каналам. Данная настройка у передающего и
принимающего устройств должна быть идентичной.
0x04 SETUP_RETR
7 6 5 4 3 2 1 0
ARD ARC
ARD - четыре бита, задающие время ожидания подтверждения приёма перед повторной отправкой: 0000 -
250мкс; 0001 - 500мкс; 0010 - 750мкс; ... ; 1111 - 4000мкс;
Значение поля ARD необходимо выбирать в зависимости от скорости обмена и количества данных, передаваемых с
пакетом подтверждения. Если данные с пакетом подтверждения не передаются, то для скоростей обмена 1 и 2
Мбит/с достаточное время ожидания 250мкс. Если вместе с пакетом подтверждения на скорости 1Мбит/с передаётся
более 5 байт данных, или более 15 на скорости 2Мбит/с, или скорость обмена выбрана 250кбит/с, то необходимо
выбрать паузу 500мкс.
ARC - четыре бита, задающие количество автоматических повторов отправки. 0000 - автоповтор отключен; 0001 -
возможен однократный повтор; ... ; 1111 - возможно до 15 повторов.
0x05 RF_CH
Регистр задаёт номер радиоканала - частоту несущей с шагом 1Мгц. Радиочастота несущей вычисляется по
формуле 2400 + RF_CH МГц.
Допустимые значения от 0 до 125. При обмене на скорости 2Мбит/с, частота должна отличатся от частоты
используемой другими устройствами минимум на 2 МГц.
0x06 RF_SETUP
7 6 5 4 3 2 1 0
Регистр статуса. Его значение также передаётся на линии MISO одновременно с передачей байта команды по
интерфейсу SPI.
7 6 5 4 3 2 1 0
RX TX
MAX TX_F
- _D _D RX_P_NO
_RT ULL
R S
RX_DR - Прерывание по получению пакета. Бит устанавливается в единицу, когда усройство в режиме приняло
адресованый ему пакет с совпавшей контрольной суммой. Бит сбрасывается путём записи в него значения 1.
Принятый пакет доступен в очереди приёмника, и может быть прочитан командой R_RX_PAYLOAD, либо удалён
командой FLUSH_RX.
TX_DS - Прерывание по успешной отправке пакета. Бит устанавливается в единицу, когда устройство в режиме
передатчика успешно отправило пакет и, если включено автоподтверждение, приняло подтверждение получения.
После успешной отправки пакет удаляется из очереди передатчика. Бит сбрасывается путём записи в него значения
1.
MAX_RT - Прерывание по превышению числа попыток повторной отправки. Бит устанавливается в единицу, когда
устройство в режиме передатчика предприняло заданное в регистре SETUP_RETR количество попыток отправки, но
так и не получило подтверждение от удалённого устройства. Передаваемый пакет остаётся в очереди передатчика.
Для удаления его можно воспользоваться командой FLUSH_TX. Дальнейшая коммуникация невозможна, пока этот бит
установлен. Бит сбрасывается путём записи в него значения 1.
Пока любой из бит RX_DR, TX_DS, MAX_RT установлен в единицу и соответствующее ему прерывание не
запрещено (т.е. соответствующие из бит MASK_RX_DR, MASK_TX_DS, MASK_MAX_RT в регистре CONFIG равны
нулю), то на выходе IRQ чипа устанавливается низкий уровень. Для сброса значений этих бит, необходимо записать
регистр STATUS с этими битами, установленными в 1.
RX_P_NO - три бита кодирующие номер канала, пакет по которому доступен в начале очереди приёмника для
чтения. Значения 000 - 101 кодируют каналы с 0 по 5, соответственно, значение 111 указывает, что очередь
приёмника пуста.
TX_FULL - значение 1 этого бита показывает, что в очереди передатчика нет свободных слотов.
0x08 OBSERVE_TX
7 6 5 4 3 2 1 0
PLOS_CNT ARC_CNT
PLOS_CNT - четыре бита, значение которых увеличивается, вплоть до достижения 15, при каждой отправке, на
которую не получено ожидаемое подтверждение. Значение сбрасывается при записи в регистр RF_CH.
ARC_CNT - четыре бита, возвращающие количество предпринятых повторов отправки при передаче последнего
пакета. Сбрасывается в 0, когда начинается отправка очередного пакета.
0x09 RPD
7 6 5 4 3 2 1 0
- - - - - - - RPD
RPD - младший бит принимает значение 1, если чип находится в режиме приёмника, и уровень принимаемого
сигнала превышает -64dBm
0x0A RX_ADDR_P0
40-битный (5 байт) регистр, используемый для указания адреса канала 0 приёмника. Этот канал используется для
приёма автоподтверждений в режиме передатчика. Автоподтверждения высылаются принимающей стороной с
указанием собственного адреса. Поэтому значение этого регистра должно соответствовать значению
регистра TX_ADDR для корректной работы в режиме передатчика.
Реальная используемая ширина адреса задаётся в регистре SETUP_AW.
Значение регистра записывается и читается, начиная с младших байт. Если записано менее 5 байт, то старшие
байты остаются неизменными.
Значение регистра по умолчанию: 0xE7E7E7E7E7
0x0B RX_ADDR_P1
40-битный (5 байт) регистр, используемый для указания адреса канала 1 приёмника. Старшие 4 байта этого
регистра являются общими для адресов на каналах 1 - 5.
Реальная используемая ширина адреса задаётся в регистре SETUP_AW.
Значение регистра записывается и читается, начиная с младших байт. Если записано менее 5 байт, то старшие
байты остаются неизменными.
Значение регистра по умолчанию: 0xC2C2C2C2C2
8-битные регистры, задающие значения младшего байта адреса для каналов 2-5. Значения старших 32 бит берутся
из регистра RX_ADDR_P1.
Значение регистров по умолчанию: 0xC3, 0xC4, 0xC5, 0xC6, соответственно.
0x10 TX_ADDR
40-битный (5 байт) регистр, используемый в режиме передатчика в качестве адреса удалённого устройства. При
включенном режиме автоподтверждения, удалённое устройство ответит подтверждением с указанием своего же
адреса. Это подтверждение принимается на канале 0, поэтому для успешной передачи, значение
регистра RX_ADDR_P0 должно быть идентично этому.
Реальная используемая ширина адреса задаётся в регистре SETUP_AW.
Значение регистра записывается и читается, начиная с младших байт. Если записано менее 5 байт, то старшие
байты остаются неизменными.
Значение регистра по умолчанию: 0xE7E7E7E7E7
0x17 FIFO_STATUS
7 6 5 4 3 2 1 0
TX RX
TX_ TX_ RX_
_F _F
- REU EMP - - EMP
UL UL
SE TY TY
L L
0x1C DYNPD
7 6 5 4 3 2 1 0
DP DP DP DP DP DP
- - L_ L_ L_ L_ L_ L_
P5 P4 P3 P2 P1 P0
DPL_Px разрешает приём пакетов произвольной длины по соответствующему каналу. При этом такая опция
должна быть включена установленным битом EN_DPL в регистре FEATURE, а также включено автоподтверждение
установкой соответствующего бита ENAA_Px в регистре EN_AA
В случае если бит принимает значение 0, то размер данных в принимаемых пакетах должен быть равен значению
соответствующего регистра RX_PW_Px
0x1D FEATURE
Регистр опций
7 6 5 4 3 2 1 0
EN
EN_AC EN_DYN
- - - - - _D
K_PAY _ACK
PL
EN_DPL включает поддержку приёма и передачи пакетов с размером поля данных произвольной длины.
В этом случае приём пакетов произвольной длины по каналам должен быть разрешён в регистре DYNPD и
включено автоподтверждение в регистре EN_AA.
Если опция отключена, то размер принимаемых данных задаётся значением регистров RX_PW_P0 - RX_PW_P5.
При передаче также передаётся поле, указывающее длительность пакета. Длина передаваемого пакета
определяется размером записанных командой W_TX_PAYLOAD данных и она должна соответствовать настройкам
принимающей стороны.
Структура пакета
Чипы nRF24L01+ автоматически производят сборку пакета при передаче, контроль адреса, проверку контрольной
суммы и разбор пакета при приёме.
Поэтому передача и приёма данных осуществляется без оглядки на истинную структуру пакета, передаваемого в
эфир, чья структура выглядит следующим образом:
1-2
3-5 0-32
1 байт 9 бит байт
байт байта
а
Преамбула
Последовательность бит 01010101, или 10101010, служащая для синхронизации приёмника. Если старший бит в
адресе 1, то преамбула 10101010, иначе 01010101
Адрес
Длина поля адреса задаётся значением бит AW в регистре SETUP_AW. Чтобы исключить ложные обнаружения
адреса (что может привести к пропуску реального адреса), желательно чтобы адрес удовлетворял следующим
условиям:
- Старшие биты адреса не должны быть чередующимися значениями нулей и единиц, поскольку в таком случае
часть преамбулы может быть спутана с адресом.
- Адрес должен содержать несколько переходов из нуля в единицу и обратно, иначе за адрес могут быть приняты
помехи.
Пакеты подтверждения приёма высылаются приёмником с указанием собственного адреса в этом поле. Поэтому
передающая сторона должна быть настроена на получение пакетов по этому же адресу на канале 0, т.е. значение
регистра RX_ADDR_P0 должно быть равно значению регистра TX_ADDR.
Управляющее поле
Длина данных - размер поля "Данные" в пакете. Если опция данных произвольной длины отключена, принимает
значение 33 (100001), в этом случае длина данных на принимающей стороне определяется значением
соответствующего регистра RX_PW_Px. Значения в диапазоне 1-32 кодируют размер данных в режиме произвольной
длины, значение 0 указывает на отсутствие данных и используется в пакетах подтверждения. Режим произвольной
длины должен быть включен у передающей стороны для канала 0, чтобы принимать пакеты подтверждения.
PID - двухбитное поле, значение которого циклически увеличивается на 1 при отправке нового пакета. В случае
если принимающая сторона приняла пакет, но отправленное подтверждение о приёме не дошло до отправляющей
стороны, может быть предпринята повторная отправка с таким же значением PID, как при первой попытке. Если
приёмник получает пакет, где поле PID равно полученному в предыдущий раз и значение поля CRC также идентично
последнему полученному, то автоматически отправляется подтверждение о получении, но полученные данные
считаются повтором и игнорируются, не помещаются в очередь FIFO приёмника, и прерывание TX_DS в этом случае
не появляется.
NO_ACK - флаг указывающий получателю на то, что подтверждение получения пакета высылать не требуется.
Сами пакеты подтверждения маркируются этим флагам. Также можно отправить пакет не требующий подтверждения
командой W_TX_PAYLOAD_NOACK, если в регистре FEATURE установлен бит EN_DYN_ACK.
Данные
Поле данных содержит, собственно, передаваемые данные. Их длина определяется количеством данных,
загруженных одной из команд W_TX_PAYLOAD, W_TX_PAYLOAD_NOACK, W_ACK_PAYLOAD.
CRC
60мГн 3мс
90мГн 4.5мс
Если включено автоматическое подтверждение приёма, то прерывание RX_DR появляется сразу по получению
пакета, после этого nRF24L01+ автоматически переходит в режим передатчика, после чего в течение 130мкс
происходит выравнивание частоты блока PLL, и затем осуществляется отправка пакета подтверждения.
В этом случае, если отправка ответа предполагается сразу после получения пакета (появления прерывания
RX_DR), то перед сбросом бита PRIM_RX и переходом в режим передатчика необходимо выдержать паузу
достаточную, чтобы чип успел завершить передачу пакета подтверждения. Рассчитать это время можно по формуле:
Время_подтверждения = 130мкс + ((длина_адреса + длина_CRC + размер_данных_в_подтверждении)
* 8 + 17) / скорость_обмена
Это время отсчитывается с момента появления прерывания RX_DR. Поскольку управляющий микроконтроллер на
обработку прерывания, чтение пакета данных, подготовку ответа и прочее также затратит некоторое время,
реальная необходимая задержка может быть значительно меньше.
Типичное время, необходимое для отправки подтверждений не включающих в себя передаваемых данных:
/* Команды */
/* Регистры */
/* Биты регистров */
// CONFIG
#define MASK_RX_DR 6 // Запрещает прерывание по RX_DR (получение пакета)
#define MASK_TX_DS 5 // Запрещает прерывание по TX_DS (завершение отправки пакета)
#define MASK_MAX_RT 4 // Запрещает прерывание по MAX_RT (превышение числа повторных
попыток отправки)
#define EN_CRC 3 // Включает CRC
#define CRCO 2 // Размер поля CRC: 0 - 1 байт; 1 - 2 байта
#define PWR_UP 1 // Включение питания
#define PRIM_RX 0 // Выбор режима: 0 - PTX (передатчик) 1 - PRX (приёмник)
// EN_AA
#define ENAA_P5 5 // Включает автоподтверждение данных, полученных по каналу 5
#define ENAA_P4 4 // Включает автоподтверждение данных, полученных по каналу 4
#define ENAA_P3 3 // Включает автоподтверждение данных, полученных по каналу 3
#define ENAA_P2 2 // Включает автоподтверждение данных, полученных по каналу 2
#define ENAA_P1 1 // Включает автоподтверждение данных, полученных по каналу 1
#define ENAA_P0 0 // Включает автоподтверждение данных, полученных по каналу 0
// EN_RXADDR
#define ERX_P5 5 // Включает канал 5 приёмника
#define ERX_P4 4 // Включает канал 4 приёмника
#define ERX_P3 3 // Включает канал 3 приёмника
#define ERX_P2 2 // Включает канал 2 приёмника
#define ERX_P1 1 // Включает канал 1 приёмника
#define ERX_P0 0 // Включает канал 0 приёмника
// SETUP_AW
#define AW 0 // Два бита, Выбирает ширину поля адреса: 1 - 3 байта; 2 - 4 байта; 3 - 5
байт.
// SETUP_RETR
#define ARD 4 // 4 бита. Задаёт значение задержки перед повторной отправкой пакета: 250
x (n + 1) мкс
#define ARC 0 // 4 битай. Количество повторных попыток отправки, 0 - повторная отправка
отключена.
// RF_SETUP
#define CONT_WAVE 7 // (Только для nRF24L01+) Непрерывная передача несущей (для
тестов)
#define RF_DR_LOW 5 // (Только для nRF24L01+) Включает скорость 250кбит/с. RF_DR_HIGH
должен быть 0
#define PLL_LOCK 4 // Для тестов
#define RF_DR_HIGH 3 // Выбор скорости обмена (при значении бита RF_DR_LOW = 0): 0 -
1Мбит/с; 1 - 2Мбит/с
#define RF_PWR 1 // 2бита. Выбирает мощность передатчика: 0 - -18dBm; 1 - -16dBm; 2
- -6dBm; 3 - 0dBm
// STATUS
#define RX_DR 6 // Флаг получения новых данных в FIFO приёмника. Для сброса флага
нужно записать 1
#define TX_DS 5 // Флаг завершения передачи. Для сброса флага нужно записать 1
#define MAX_RT 4 // Флаг превышения установленного числа повторов. Без сброса (записать
1) обмен невозможен
#define RX_P_NO 1 // 3 бита. Номер канала, данные для которого доступны в FIFO
приёмника. 7 - FIFO пусто.
#define TX_FULL_STATUS 0 // Признак заполнения FIFO передатчика: 1 - заполнено; 0 - есть
доступные слоты
// (переименовано из TX_FULL во избежание путаницы с одноимённым битом из
регистра FIFO_STATUS)
// OBSERVE_TX
#define PLOS_CNT 4 // 4 бита. Общее количество пакетов без подтверждения. Сбрасывается
записью RF_CH
#define ARC_CNT 0 // 4 бита. Количество предпринятых повторов при последней отправке.
// FIFO_STATUS
#define TX_REUSE 6 // Признак готовности последнего пакета для повторной отправки.
#define TX_FULL_FIFO 5 // Флаг переполнения FIFO очереди передатчика.
// (переименовано из TX_FULL во избежание путаницы с одноимённым битом из
регистра STATUS)
#define TX_EMPTY 4 // Флаг освобождения FIFO очереди передатчика.
#define RX_FULL 1 // Флаг переполнения FIFO очереди приёмника.
#define RX_EMPTY 0 // Флаг освобождения FIFO очереди приёмника.
// DYNDP
#define DPL_P5 5 // Включает приём пакетов произвольной длины по каналу 5
#define DPL_P4 4 // Включает приём пакетов произвольной длины по каналу 4
#define DPL_P3 3 // Включает приём пакетов произвольной длины по каналу 3
#define DPL_P2 2 // Включает приём пакетов произвольной длины по каналу 2
#define DPL_P1 1 // Включает приём пакетов произвольной длины по каналу 1
#define DPL_P0 0 // Включает приём пакетов произвольной длины по каналу 0
// FEATURE
#define EN_DPL 2 // Включает поддержку приёма и передачи пакетов произвольной длины
#define EN_ACK_PAY 1 // Разрешает передачу данных с пакетами подтверждения приёма
#define EN_DYN_ACK 0 // Разрешает использование W_TX_PAYLOAD_NOACK
Подключение SPI
Чип nRF24L01+ обменивается данными с управляющим микроконтроллером по шине SPI в режиме 0 (CPHA=0,
CPOL=0). Это значит, что на линии SCK до начала обмена выдерживается низкий уровень. Начинается обмен с
установки низкого уровня на линии CSN, при этом и ведущая и ведомая сторона выставляют на линиях MOSI и MISO
соответственно, значения старших бит передаваемых байт. При нарастающем фронте на линии SCK, происходит
чтение выставленных значений противоположными сторонами. При спадающем фронте SCK, выставляются значения
следующих бит. Передача идёт от старших бит в байте к младшим. Сеанс обмена завершается установкой высокого
уровня на линии CSN.
nRF24L01+ поддерживает обмен по SPI на частоте до 10МГц. Однако, в случае большой паразитной емкости линий
данных и при наличии помех, может потребоваться уменьшить частоту.
Примеры ниже показывают различные варианты подключения микроконтроллера к шине SPI и определяют две
функции:
void spi_init() - производит первичную настройку интерфейса SPI;
uint8_t spi_send_recv(uint8_t data) - отправляет 1 байт по SPI, по линии MOSI, дожидается окончания обмена и
возвращает байт принятый по линии MISO.
В этих примерах не определяется использование линии CSN.
#define SPI_SS 2
#define SPI_MOSI 3
#define SPI_SCK 5
// Инициализация интерфейса
void spi_init() {
SPI_DDR |= (1 << SPI_MOSI) | (1 << SPI_SCK) | (1 << SPI_SS);
SPCR = (1 << SPE) | (1 << MSTR); // режим 0, мастер, частота 1/4 от частоты ЦП
}
#define USART_XCK 4
#define SWSPI_MOSI 6
#define SWSPI_MISO 7
#define SWSPI_SCK 8
Взаимодействие с nRF24L01+
Функции настройки портов и базового взаимодействия
Линия CSN, определяющая сеанс обмена по интерфейсу SPI, имеет активным низкий уровень. Линия CE,
наоборот, активна по высокому уровню. Чтобы избежать путанницы определим
функции radio_assert_ce, radio_deassert_ce, csn_assert, csn_deassert, которые будут переводить линии
ce/csn к активному (assert) и неактивному (deassert) уровню.
Также ниже будут определены функции читающие/записывающие регистры и вызывающие выполнение команд
чипа nRF24L01+.
Но для начала нужно определить порты, на которых будет происходить обмен.
#define RADIO_PORT PORTD
#define RADIO_DDR DDRD
#define RADIO_PIN PIND
#define RADIO_CSN 1
#define RADIO_CE 2
#define RADIO_IRQ 3
// Инициализирует порты
void radio_init() {
RADIO_DDR |= (1 << RADIO_CSN) | (1 << RADIO_CE); // Ножки CSN и CE на выход
RADIO_DDR &= ~(1 < RADIO_IRQ); // IRQ - на вход
csn_deassert();
radio_deassert_ce();
spi_init();
}
// Выполняет команду cmd, и читает count байт ответа, помещая их в буфер buf, возвращает
регистр статуса
uint8_t radio_read_buf(uint8_t cmd, uint8_t * buf, uint8_t count) {
csn_assert();
uint8_t status = spi_send_recv(cmd);
while (count--) {
*(buf++) = spi_send_recv(0xFF);
}
csn_deassert();
return status;
}
// Выполняет команду cmd, и передаёт count байт параметров из буфера buf, возвращает
регистр статуса
uint8_t radio_write_buf(uint8_t cmd, uint8_t * buf, uint8_t count) {
csn_assert();
uint8_t status = spi_send_recv(cmd);
while (count--) {
spi_send_recv(*(buf++));
}
csn_deassert();
return status;
}
// Читает count байт многобайтового регистра reg (от 0 до 31) и сохраняет его в буфер
buf,
// возвращает регистр статуса
uint8_t radio_readreg_buf(uint8_t reg, uint8_t * buf, uint8_t count) {
return radio_read_buf((reg & 31) | R_REGISTER, buf, count);
}
// Записывает count байт из буфера buf в многобайтовый регистр reg (от 0 до 31),
возвращает регистр статуса
uint8_t radio_writereg_buf(uint8_t reg, uint8_t * buf, uint8_t count) {
return radio_write_buf((reg & 31) | W_REGISTER, buf, count);
}
В крайних случаях, если нужно сэкономить линию, пин прерывания можно не подключать, а проверять наличие
прерывания анализируя регистр статуса:
uint8_t radio_is_interrupt() {
// использовать этот вариант только в крайних случаях!!!
return (radio_cmd(NOP) & ((1 << RX_DR) | (1 << TX_DS) | (1 << MAX_RT))) ? 1 : 0;
}
Хотя все регистры имеют определённое значение по-умолчанию, которое загружается в них после подачи питания,
рекомендую явно задать значения всех необходимых регистров. Особенно это актуально, если линия CSN не
притянута внешним резистором к питанию: тогда в момент сброса микроконтроллера, радио-модуль может
улавливать помехи и хаотичным образом перенастроить регистры.
Пример ниже показывает инициализацию с готовностью работы в режиме приёма по каналу 1 и передачи.
Выбирается длина адреса 5-байт, радио канал 3 (2403 МГц). Собственный адрес 0xE7E7E7E7E7, адрес удалённой
стороны - 0xC2C2C2C2C2
radio_deassert_ce();
for(uint8_t cnt = 100;;) {
radio_writereg(CONFIG, (1 << EN_CRC) | (1 << CRCO) | (1 << PRIM_RX)); // Выключение
питания
if (radio_readreg(CONFIG) == ((1 << EN_CRC) | (1 << CRCO) | (1 << PRIM_RX)))
break;
// Если прочитано не то что записано, то значит либо радио-чип ещё инициализируется,
либо не работает.
if (!cnt--)
return 0; // Если после 100 попыток не удалось записать что нужно, то выходим с
ошибкой
_delay_ms(1);
}
radio_writereg(RX_PW_P0, 0);
radio_writereg(RX_PW_P1, 32);
radio_writereg(DYNPD, (1 << DPL_P0) | (1 << DPL_P1)); // включение произвольной длины
для каналов 0 и 1
radio_writereg(FEATURE, 0x04); // разрешение произвольной длины пакета данных
В общем случае, алгоритм работы программы таков: всё время радио-модуль находится в режиме приёма (PRX),
ожидая, когда к нему обратятся по радио-эфиру.
Когда возникает необходимость передать пакет, nRF24L01+ переводится в режим передатчика, осуществляет
отправку пакета, а по завершению - удачному, или нет - возвращается в режим приёмника.
void check_radio() {
if (!radio_is_interrupt()) // Если прерывания нет, то не задерживаемся
return;
uint8_t status = radio_cmd(NOP);
radio_writereg(STATUS, status); // Просто запишем регистр обратно, тем самым сбросив
биты прерываний
if (status & ((1 << TX_DS) | (1 << MAX_RT))) { // Завершена передача успехом, или нет,
if (status & (1 << MAX_RT)) { // Если достигнуто максимальное число попыток
radio_cmd(FLUSH_TX); // Удалим последний пакет из очереди
on_send_error(); // Вызовем обработчик
}
if (!(radio_readreg(FIFO_STATUS) & (1 << TX_EMPTY))) { // Если в очереди передатчика
есть что передавать
radio_assert_ce(); // Импульс на линии CE приведёт к началу передачи
_delay_us(15); // Нужно минимум 10мкс, возьмём с запасом
radio_deassert_ce();
} else {
uint8_t conf = radio_readreg(CONFIG);
radio_writereg(CONFIG, conf | (1 << PRIM_RX)); // Устанавливаем бит PRIM_RX: приём
radio_assert_ce(); // Высокий уровень на линии CE переводит радио-чип в режим
приёма
}
}
uint8_t protect = 4; // В очереди FIFO не должно быть более 3 пакетов. Если больше,
значит что-то не так
while (((status & (7 << RX_P_NO)) != (7 << RX_P_NO)) && protect--) { // Пока в очереди
есть принятый пакет
uint8_t l = radio_read_rx_payload_width(); // Узнаём длину пакета
if (l > 32) { // Ошибка. Такой пакет нужно сбросить
radio_cmd(FLUSH_RX);
} else {
uint8_t buf[32]; // буфер для принятого пакета
radio_read_buf(R_RX_PAYLOAD, &buf[0], l); // начитывается пакет
if ((status & (7 << RX_P_NO)) == (1 << RX_P_NO)) { // если datapipe 1
on_packet(&buf[0], l); // вызываем обработчик полученного пакета
}
}
status = radio_cmd(NOP);
}
}
// Основной цикл
int main(void) {
radio_init();
while (!radio_start()) {
_delay_ms(1000);
}
// Перед включением питания чипа и сигналом CE должно пройти время достаточное для
начала работы осциллятора
// Для типичных резонаторов с эквивалентной индуктивностью не более 30мГн достаточно
1.5 мс
_delay_ms(2);
radio_assert_ce();
for(;;) {
check_radio();
Только приём
В случае, если устройство работает только на приём, т.е. принимает пакеты, но не отправляет их, канал 0 может
быть запрещён в регистрах EN_RXADDR и DYNPD в radio_start().
Из функции check_radio() можно исключить часть, ответственную за прерывания передатчика.
Только передача
Если вы реализуете пульт дистанционного управления, то он должен обеспечивать только передачу. А в целях
экономии энергии сразу после передачи одиночной команды переводить радио-чип в спящий режим.
В этом случае в radio_start() канал 1 может быть запрещён в регистрах EN_RXADDR и DYNPD.
void check_radio() {
if (!radio_is_interrupt()) // Если прерывания нет, то не задерживаемся
return;
uint8_t status = radio_cmd(NOP);
radio_writereg(STATUS, status); // Просто запишем регистр обратно, тем самым сбросив
биты прерываний
if (status & ((1 << TX_DS) | (1 << MAX_RT))) { // Завершена передача успехом, или нет,
if (status & (1 << MAX_RT)) { // Если достигнуто максимальное число попыток
radio_cmd(FLUSH_TX); // Удалим последний пакет из очереди
on_send_error(); // Вызовем обработчик
}
if (!(radio_readreg(FIFO_STATUS) & (1 << TX_EMPTY))) { // Если в очереди передатчика
есть что передавать
radio_assert_ce(); // Импульс на линии CE приведёт к началу передачи
_delay_us(15); // Нужно минимум 10мкс, возьмём с запасом
radio_deassert_ce();
} else {
uint8_t conf = radio_readreg(CONFIG);
radio_writereg(CONFIG, conf & ~(1 << PWR_UP)); // Если пусто, отключаем питание
}
}
uint8_t protect = 4; // В очереди FIFO не должно быть более 3 пакетов. Если больше,
значит что-то не так
while (((status & (7 << RX_P_NO)) != (7 << RX_P_NO)) && protect--) { // Пока в очереди
есть принятый пакет
radio_cmd(FLUSH_RX); // во всех случаях выкидываем пришедший пакет.
status = radio_cmd(NOP);
}
}
Код:00384
Артикул:NRF24L01
В наличии:есть
150 руб
1
В корзину
Модуль NRF24L01 позволяет связать приборы радиоканалом передачи данных. С помощью NRF24L01 до семи приборов объединяются в общую радиосеть
топологии звезда на частоте 2,4 ГГц. Один прибор в радиосети ведущий, остальные ведомые. При упрощенном рассмотрении модуль приемопередатчика 2,4
ГГц NRF24L01 является конвертером интерфейса SPI в радиосигнал. Берет на себя все функции преобразования проводного интерфейса SPI в радиосигнал,
содержит приемник, передатчик и миниатюрную антенну. Специалисту не обязательно знать особенности кодирования модулем данных по радио, достаточно
правильно организовать работу SPI и установить настройки каждого модуля работающего в радиомосте.
Основа модуля микросхема nRF24L01+ фирмы Nordic Semiconductor. На плате размещены компоненты необходимые для работы МС и вилка разъема.
Установка выходной мощности модуля, каналов радиообмена и настройка протокола производятся через интерфейс SPI. Совместим с модулями nRF2401A,
nRF2402, nRF24E1 и nRF24E2.
Применение устройства наиболее актуально для мобильных приборов. Например, можно создать беспроводную связь с пультом управления видеоигрой,
джойстиком, компьютерными мышью и клавиатурой. Интересная область применения – управление движущимися системами малой робототехники: колесными
и гусеничными платформами, квадрокоптерами. Благодаря NRF24L01 становится возможным решить технические проблемы простой телемеханики и сбора
данных с датчиков. Это находит применение в охранно-пожарной сигнализации, в системах «умный дом», устройствах централизованного сбора информации и
других.
Характеристики
Питание
Напряжение 1,9–3,6 В
Ток
13,5 мА когда скорость обмена 2 Мбод
11,3 мA если мощность 0 dBм
22 мА пиковое потребление при приеме
Микросхема nRF24L01+
В микросхему входят: синтезатор частоты, усилитель мощности, генератор, демодулятор, модулятор и другие части, образующие многофункциональный
трансивер. Связь происходит в диапазоне частот 2,4–2,4835 ГГц. Частота, на которой будут работать модули, определяется номером канала. Они имеют шаг 1
МГц. Каналу 0 соответствует частота 2,4 ГГц, каналу 76 частота 2,476 ГГц. При скорости 250 Кбод связь возможна на большей дистанции. В режиме приема
данных RX потребление тока выше, чем в режиме передачи TX. Модуль работает в четырех режимах: Power Down – выключен, Standby – спящий режим, RX
Mode – приемник, TX Mode – передатчик. Микросхема nRF24L01+ имеет функции энергосбережения.
Надежный обмен данными гарантирует собственный протокол обмена Enhanced ShockBurst™. Прием данных подтверждает обратная связь в виде ответа.
Принимающий данные модуль приемопередатчика 2.4 ГГц NRF24L01 отвечает подтверждением приема. Если подтверждение приема не получено, то передача
повторяется.
Приемопередатчик – трансивер, имеет трехуровневый FIFO буфер приема, разделенный на шесть каналов, и трехуровневый FIFO буфер передачи. Одна
микросхема nRF24L01+ конфигурируется как центральный принимающий узел и 6 как сообщающие данные. Такие обозначения функций до некоторой степени
условны. На самом деле при любой роли МС в обмене данными каждая из них работает поочередно как приемник и передатчик. Обмен данными в такой сети
происходит на одном частотном канале. Благодаря большому количеству каналов рядом могут работать еще 7 микросхем и еще и еще…
В пакете передаваемых данных есть 9 бит идентификации после битов адреса. Первые 2 бита используются для индикации данных счетчика приема пакетов
для контроля очередности приема. Остальные семь бит не используются и зарезервированы под будущие продукты. Для совместимости с микросхемами
nRF2401, nRF24E1 и nRF905, nRF9E5 поле идентификации пакета может не использоваться. Количество повторных попыток передачи пакета задается
программно. Если отправить пакет не удалось, то генерируется прерывание для контроллера, а в регистре статуса трансивера устанавливается бит MAX_RT.
Для успешной передачи пакета вырабатывается сигнал прерывания (вывод TX_DS IRQ) и передающий FIFO буфер очищается.
Для настройки различных параметров и функций используются регистры микросхемы. Каждый регистр (кроме трех регистров полезной нагрузки) имеет 5-
битный адрес, который маскируется в R_REGISTER и W_REGISTER инструкциями, соответственно чтение и запись.
Подключение
Кроме выводов питания контакты линий сигналов могут подключаться к контактам прибора питающегося напряжением 5 В. Такая совместимость обеспечена
внутренними цепями микросхемы. При подключении к порту Р0 МК класса 51 нужен подтягивающий резистор 10 кОм, для других портов он не нужен. Входы
устройства подключаемого к модулю должны потреблять ток не более 10 мА. Модуль соединяется с микроконтроллером класса AVR без цепей согласования
уровней сигналов.
Подключение является универсальным и подходит для всех плат Arduino UNO, DUE, MEGA, Леонардо, Yun и подобных. Сигналы SPI выведены на соединитель
ICSP микроконтроллерного модуля Arduino. Контакт питания VCC соединяется с контактом стабилизатора Arduino напряжения 3,3 В. Общий провод
подключается к контакту GND. Сигналы выбора CE и CSN подключаются к контактам, определенным в библиотеке RF24, например 7 и 8.
Особенности программирования
Для программ Arduino используется библиотека RF24 https://github.com/maniacbug/RF24/ Эта библиотека снабжена большим количеством примеров. При записи
программы в Arduino модуль приемопередатчика 2,4 ГГц NRF24L01 нужно отключить от Arduino. Перед первой командой инициализации нужна пауза две
секунды после подачи питания. Необходимо сделать публичной функцию RF24::flush_tx в библиотеке RF24 и очищать буфер передачи перед отправкой нового
сообщения. По умолчанию модуль работает на передающем канале 76h.
Примечание
Перед первым включением следует смонтировать на модуле 2 конденсатора. Между выводами VCC и GND припать конденсатор в SMD корпусе (планарный)
емкостью 0,1 мкФ со стороны пайки к монтажным площадкам на плате, затем к ним припаять электролитический конденсатор емкостью 100 мкФ на напряжение
10 В. Питать лучше не от Arduino, а от отдельного стабилизатора напряжения 3,3 В, способного обеспечить ток нагрузки 200 мА.