Автоматика и аппаратура связи Дистанционное и непосредственное управление исполнительными механизмами, сотовая, а также радиосвязь. |
08.06.2012, 07:20
|
#351
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Сообщение от 123mib
|
посмотреть работу и может даже время пинга.
|
Время пинга прекрасно ловится программно, измеряя время между началом передачи и прерыванием по приходу подтверждения
|
|
|
|
08.06.2012, 09:18
|
#352
|
Частый гость
Регистрация: 26.06.2006
Адрес: г.Сарны, Украина
Сообщений: 27
Сказал спасибо: 30
Сказали Спасибо 18 раз(а) в 7 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Сообщение от 123mib
|
Подскажите,- зелёная "NRF24L01" без "+"
- чёрная - это "NRF24L01+" ???
|
А у меня зеленые с '+'.
|
|
|
|
08.06.2012, 09:29
|
#353
|
Частый гость
Регистрация: 28.08.2011
Сообщений: 11
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Да, на одной из фоток на ибее видно, что и зеленые тоже с плюсом.
|
|
|
|
08.06.2012, 09:41
|
#354
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Сообщение от 123mib
|
Спасибо niXto за ответ, думаю надо попробывать, .... стоят они копейки, заодно вникну "в тему", ... жаль нет осциллографа, посмотреть работу и может даже время пинга.
Подскажите,- зелёная "NRF24L01" без "+"
- чёрная - это "NRF24L01+" ???
|
Распиновка разъема разная. Один 10 пин, другой 8. Черные мне показались более удобными. Пользовал и те и другие.
|
|
|
|
23.07.2012, 11:48
|
#355
|
Прохожий
Регистрация: 26.11.2009
Сообщений: 5
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Здравствуйте. Купил на ebay радиомодули RF-2400 (построены на чипе BK2421). Не могу разобраться с отправкой-приемом. Видал кучу библиотек, но все были под PIC или AVR.
Переделал по STM. Изучил даташит, инициализация вроде верная - на приемнике и передатчике одинаковые параметры. Думаю есть какой-то маленький нюанс, который не учел.
При отправке на передатчике получаю статус 1E - превышен максимальный лимит попыток передачи. На приемнике посылки нету - прерывания на ноге IRQ нету.
Может кто имел с ними дело, подскажите, что я не учел.
Начну с того, что инициализация (записи в банки регистров) для разных банок разная. Команды все передаются от старшего бита к младшему. В Bank0 и Bank1 с 9 по 14 регистры передача идет от младшего байта к старшему. С 0 по 8 регистр Bank1 передача идет от старшего байта к младшему.
Ну и в принципе по отладчику проверял, все условия передачи учитываются, считываю все регистры Bank0 после записи - все записано верно. С Bank1 считывать не дает - он только для записи.
Наверное сперва напишу алгоритм общения с RF-2400, т.к. в команды выполняются, с модулем общаюсь хорошо, т.е. в коде ошибок не должно быть. Пытаюсь передать 1 байт "\x37"
Инициализация RF-2400:
- 1. Устанавливаем линию CE
- 2. Ждем 2 сек для запуска модуля (везде разные цифры, кто 100мс ждет, кто 200мс, кто 500мс. Я не тороплюсь - пусть будет 2000мс.
Отправляю команду ActivateCmd с параметром 0x73. Если честно, так и не понял, что это дает. Но так делают все. - 3. Переключаемся на Bank0
3.1 Опускаем линию CE
3.2 Ждем 50мс
3.3 Читаем статус
3.4 Если стоит Bank0, ничего не делаем, если Bank1 - переключаемся командой ActivateCmd с параметром 0x53
3.5 устанавливаем линию CE
3.6 Ждем 2 сек
- 4. Инициализируем модуль с параметрами Bank0:
Нажмите, чтобы открыть спойлер
ConfigRegValues = 0x0B, // Prim_RX, Power up, CRC 1 bytes, Enable CRC, Int RX, Int TX, Int RX_DR
EnableAutoAckRegValues = 0x3f, // Включить автоподтверждение для всех "pipe"
EnableRxAdressRegValues = 0x01, // включить data pipe 0
SetupAdressWidthRegValues = 0x03, // ширина адреса 5 байт
SetupRetryRegValues = 0x3F, // Повтор передачи через = 1000us, 15 попыток
RfChannelRegValues = 0x20, // канал для передачи - 32
RfSetupRegValues = 0x37, // 1Mbps, output power=5dBm, LNA=HIGHT
StatusRegValues = 0x70, // Флаги прерываний RX, TX, MAX_TX очищены
// MAX_RT - превышение максимума кол-ва попыток передачи
ObserveTxRegValues = 0x00, // только чтение
CarrierDetectRegValues = 0x00, // только чтение
RxAddress2Values = 0xc3, //
RxAddress3Values = 0xc4, //
RxAddress4Values = 0xc5, //
RxAddress5Values = 0xc6, //
RxDataLength0Values = 0x20, // RX Payload Length = 32
RxDataLength1Values = 0x20, //
RxDataLength2Values = 0x20, //
RxDataLength3Values = 0x20, //
RxDataLength4Values = 0x20, //
RxDataLength5Values = 0x20, //
DynamicPayloadValues = 0x3f,
FeatureValues = 0x04,
FifoStatusRegValues = 0x11
/*The Rx Address 5 bytes*/
const unsigned char RX_Address0[5] = { 0x3a, 0x3b, 0x3c, 0x3d, 0x01 };
/*The Tx Address 5 bytes*/
const unsigned char TX_Address0[5] = { 0x3a, 0x3b, 0x3c, 0x3d, 0x01 };
- 5. Переключаемся на Bank1
- 6. Инициализируем модуль с параметрами Bank1:
Нажмите, чтобы открыть спойлер
/*0*/ 0xE2014B40,
/*1*/ 0x00004BC0,
/*2*/ 0x028CFCD0,
/*3*/ 0x41390099,
/*4*/ 0x0B869ED9, //Change REG4[29:27] from 00 to 11
/*5*/ 0xA67F0624, //Disable RSSI measurement
/*6*/ 0x00000000,
/*7*/ 0x00000000,
/*8*/ 0x00000000,
/*9*/ 0x00000000,
/*0A*/ 0x00000000,
/*0B*/ 0x00000000,
/*0C*/ 0x00127300,
/*0D*/ 0x36B48000,
};
unsigned char Bank1_Reg14[Reg14Size]=
{
0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF, 0xFF //LSB first
};
- 7. Переключаемся на Bank0 для дальнейшего считывания статуса.
На этом инициализация закончена. В дальнейшем алгоритм отправки данных по нажатию кнопки: - 8. Отправляем пакет:
8.1 Переключаемся в режим передачи
8.1.1 Опускаем линию CSN
8.1.2 Отправляем команду FlushTx (0xE1)
8.1.3 Устанавливаем линию CSN
8.1.4 Опускаем линию CE
8.1.5 Ждем 200мс
8.1.6 читаем GONFIG и устанавливаем последний бит (PRIM_RX) в 0 для активации режима передачи
8.1.7 Поднимаем линию CE
8.1.8 Ждем 2 сек
8.2 Читаем FIFO_STATUS, получаем 10001 (0x11) - установлены TX_FULL и RX_EMPTY
8.3 Если 5-й бит (TX_FULL) установлен:
8.3.1 Опускаю линию CSN
8.3.2 Отправляю WriteTxDataCmd (0xA0)
8.3.3 Пока не закончится указанное число байт - отправляю содержимое буфера
8.3.4 Поднимаем линию CSN
- 9. Ждем 200мс и читаем статус. Получаем 1E - превышен лимит попыток отправки.
Ну собственно вот и все. Код для приемника и передатчика один и тот же. Приемник есс-но в режиме приема - насилу ему указываю SwitchToRxMode(), несмотря на то, что он уже по-умолчанию инициализируется с этим режимом, чтоб уж наверняка.
Может быть разная адресация - ставил разные: все адреса одни и те же; ставил перекрестные (условно: передатчик RX =0, TX=1. Приемник RX=1, TX=0). Читал на казусе, что адреса лучше ставить начиная с E7 для лучшей преамбулы и т.д. Что я не учел?
Ну и коды:
Функция передачи команды в RF-2400
Нажмите, чтобы открыть спойлер
Код:
|
/*-------------------------------------------------------------------------------------------*/
/* Записывает значение в RF-2400 и возвращает ответ */
/* Принимает: value: адрес регистра */
/* Возвращает: содержимое регистра DR */
/*----------------------------------------------------------------------------------------------------------*/
/* Команда передается от старшего бита к младшему, поэтому реализуем ручной SPI */
/*----------------------------------------------------------------------------------------------------------*/
unsigned char SPI_RW(unsigned char value)
{
unsigned char res = 0; // вывод полученного результата
unsigned char i = 0x80; // переменная для побитовой передачи и чтения данных
unsigned char bit_ctr=0; // счетчик переданных/полученных байт
for(bit_ctr=0;bit_ctr‹8;bit_ctr++) // передача 8-ми бит
{
if(value & 0x80) // сравниваем старший бит с '1000 0000'
{
SET_MOSI(); // если старший бит равен единице, поднимаем MOSI - передаем '1'
}
else
{
CLR_MOSI(); // иначе опускаем MOSI - передаем '0'
}
value = (value ‹‹ 1); // сдвигаем наш байт на единицу влево (передаем следующий бит)
SET_SCK(); // устанавливаем SCK в '1'
if(GET_MISO())
{
res |= i; // Записываем принятый бит
}
CLR_SCK(); // бит передан, опускаем SCK
i ››= 1;
}
return(res); //возвращаем принятый байт
}; |
Функция записи значения в регистр:
Нажмите, чтобы открыть спойлер
Код:
|
/*----------------------------------------------------------------------------------------------*/
/* Записывает значение 'value' в регистр 'reg' в RF-2400 */
/* Принимает: reg: адрес регистра */
/* Возвращает: ничего */
/*----------------------------------------------------------------------------------------------*/
void SPI_Write_Reg(unsigned char reg, unsigned char value)
{
delay_ms(10);
CLR_SS(); // опускаем CSN, инициируем передачу
SPI_RW(reg); // отсылаем адрес регистра
SPI_RW(value); // отсылаем значение регистра
SET_SS(); // поднимаем CSN, заканчиваем передачу
}; |
Функция записи массива байт в RF-2400:
Нажмите, чтобы открыть спойлер
Код:
|
/*----------------------------------------------------------------------------------------------*/
/* Записывает массив байт в регистр RF-2400 */
/* Принимает: reg: адрес регистра */
/* pBuffer: массив для отправки */
/* Length: размер массива */
/* Возвращает: ничего не возвращает */
/*----------------------------------------------------------------------------------------------*/
void SPI_Write_Buf(unsigned char reg, unsigned char *pBuffer, unsigned char Length)
{
CLR_SS(); // опускаем CSN, инициируем передачу
SPI_RW(reg); // отсылаем адрес регистра
while(Length--) // пока длина не равна нулю
{
SPI_RW(*pBuffer++); // отсылаем байты
}
SET_SS(); // поднимаем CSN, заканчиваем передачу
} |
Функция для отправки данных по радиоканалу:
Нажмите, чтобы открыть спойлер
Код:
|
/*----------------------------------------------------------------------------------------------*/
/* записывает данные в буфер передачи модуля */
/* Принимает: *buffer - ссылка на массив для передачи, size - длина массива */
/* Возвращает: если буфер передачи не полон: 1 */
/* если буфер передачи полон: 0 */
/*----------------------------------------------------------------------------------------------*/
unsigned char Write(void *buffer, unsigned char size)
{
SwitchToTxMode();
unsigned char fifoStatus = SPI_Read_Reg(ReadRegCmd | FifoStatusReg);
if(!(fifoStatus & 0x20 ))
{
SPI_Write_Buf(WriteTxDataCmd, (unsigned char*)buffer, size);
return 1;
}
return 0;
} |
Переключение в режим приемника:
Нажмите, чтобы открыть спойлер
Код:
|
/*----------------------------------------------------------------------------------------------*/
/* Процедура переключения в режим приема */
/* Принимает: ничего */
/* Возвращает: ничего не возвращает */
/*----------------------------------------------------------------------------------------------*/
void SwitchToRxMode(void)
{
unsigned char value;
CLR_SS(); // опускаем CSN, инициируем передачу
SPI_RW(FlushRxCmd); // очищаем буфер приема
SET_SS(); // поднимаем CSN, заканчиваем передачу
value = SPI_Read_Reg(ReadRegCmd | StatusReg); // читаем StatusReg
value = value & 0x70; // устанавливаем последний бит в '0' (PRIM_RX)
SPI_Write_Reg(WriteRegCmd | StatusReg, value ); // clear RX_DR or TX_DS or MAX_RT interrupt flag
CLR_CE();
delay_ms(200);
value = SPI_Read_Reg(ReadRegCmd | ConfigReg); // читаем ConfigReg
value = value | 0x01; // устанавливаем последний бит в '1' (PRIM_RX)
SPI_Write_Reg(WriteRegCmd | ConfigReg, value ); // устанавливаем PRX
SET_CE();
delay_ms(2000);
} |
Переключение в режим передатчика:
Нажмите, чтобы открыть спойлер
Код:
|
/*----------------------------------------------------------------------------------------------*/
/* Процедура переключения в режим передачи */
/* Принимает: ничего */
/* Возвращает: ничего не возвращает */
/*----------------------------------------------------------------------------------------------*/
void SwitchToTxMode(void)
{
unsigned char value;
CLR_SS(); // опускаем CSN, инициируем передачу
SPI_RW(FlushTxCmd); // очищаем буфер передачи
SET_SS(); // поднимаем CSN, заканчиваем передачу
CLR_CE(); // очищаем линию CE
delay_ms(200);
value = SPI_Read_Reg(ReadRegCmd | ConfigReg); // читаем ConfigReg
value = value & 0xfe; // устанавливаем последний бит в '0' (PRIM_RX)
SPI_Write_Reg(WriteRegCmd | ConfigReg, value ); // устанавливаем PTX
value = SPI_Read_Reg(ReadRegCmd | ConfigReg); // читаем ConfigReg
SET_CE(); // поднимаем CE в '1'
delay_ms(2000);
} |
Переключение банков регистров:
Нажмите, чтобы открыть спойлер
Код:
|
/*----------------------------------------------------------------------------------------------*/
/* Процедура переключение между Bank1 и Bank0 */
/* Принимает: номер банка: */
/* 1:register bank1 */
/* 0:register bank0 */
/* Возвращает: ничего не возвращает */
/*----------------------------------------------------------------------------------------------*/
/* переключение банков должно осуществляться при линии CE (EnablePin) */
/* установленной в низкий уровень */
/*----------------------------------------------------------------------------------------------*/
void SwitchCFG(unsigned char cfg)
{
unsigned char tmp = 0;
CLR_CE();
delay_ms(50);
tmp = SPI_Read_Reg(ReadRegCmd | StatusReg); //читаем STATUS
tmp = tmp & 0x80; //смотрим старший бит 'RBANK'
tmp = (tmp ›› 7); //сдвигаем полученный бит вправо, чтобы нормально сравнивать
if (cfg != tmp) //если устанавливаемый и установленный биты различаются
{
SPI_Write_Reg(ActivateCmd, 0x53); //отправляем команду ActivateCmd с параметром 0x53 для переключения банка
}
tmp = SPI_Read_Reg(ReadRegCmd | StatusReg); //читаем STATUS
SET_CE();
delay_ms(2000);
} |
|
|
|
|
24.07.2012, 12:47
|
#356
|
Частый гость
Регистрация: 06.12.2008
Сообщений: 49
Сказал спасибо: 2
Сказали Спасибо 11 раз(а) в 8 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Посмотрите примеры для RFM70 (основа HOPE) на сайте производителя и в интернете.
Есть на С, СРР,..
|
|
|
|
24.07.2012, 20:44
|
#357
|
Прохожий
Регистрация: 26.11.2009
Сообщений: 5
Сказал спасибо: 2
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
На основе этих примеров и делал.
|
|
|
|
09.08.2012, 19:53
|
#358
|
Частый гость
Регистрация: 14.06.2006
Сообщений: 22
Сказал спасибо: 13
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Здравствуйте! Столкнулся с проблемой у nRF24L01+ : передаю данные с автоподтверждением - всё работает. Но если выключить приёмник, а потом опять включить - передача данных не возобновляется, нужно выключить и включить передатчик. Как с этим можно бороться?
|
|
|
|
09.08.2012, 22:42
|
#359
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
Уже много раз писал про это выше, почитайте
Переполнение буфера, при отсутствии подтверждения вызывайте команду flush tx. Но не злоупотребляйте этой командой, если буфер и так пустой, то ее выполнение где-то в 1/1000 случаев приводит к полнейшему зависанию трансивера (старых, без + в названии, про новые не знаю, т.к. там все правильно прописано)
|
|
|
|
11.08.2012, 14:29
|
#360
|
Частый гость
Регистрация: 14.06.2006
Сообщений: 22
Сказал спасибо: 13
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Кто-нибудь работал с RF модулями nRF2401A?
А как программно грамотно перезапустить трансивер?
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 01:51.
|
|