Форум РадиоКот https://radiokot.ru/forum/ |
|
NRF24L01 и ATmega8 https://radiokot.ru/forum/viewtopic.php?f=57&t=197054 |
Страница 1 из 2 |
Автор: | Daniil4829 [ Ср мар 05, 2025 20:34:45 ] |
Заголовок сообщения: | NRF24L01 и ATmega8 |
Доброго времени суток! Который день пытаюсь реализовать связь между двумя atmega-ми через модули NRF24L01. Задумка проста, нужно чтобы при нажатии кнопки на одном микроконтроллере загорался светодиодик на другом. Делал как описано на этом сайте (https://aterlux.ru/article/nrf24l01p#__h2_42) используя приведенный там код, но передачи не происходит. Может есть у кого похожие проекты или библиотеки) был бы очень благодарен, если поделитесь ![]() |
Автор: | roman.com [ Чт мар 06, 2025 10:02:50 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Может есть у кого похожие проекты есть. https://www.radiokot.ru/forum/viewtopic ... 8&t=190542 |
Автор: | codenamehawk [ Чт мар 06, 2025 11:21:15 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Подключал к ат16. Как подключено можно посмотреть в протеусе, проект для еклипсе с авр плагином. Насколько помню, необходимо выставить одинаковые адреса. Перешел на есп, тянет намного дальше и сразу отсылает в "интернет". Вложение:
|
Автор: | OKF [ Чт мар 06, 2025 16:51:57 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Используй Ардуино, в нем есть поддержка Мега8. Ну и куча библиотек с примерами. |
Автор: | VNS [ Чт мар 06, 2025 22:08:31 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Может есть у кого похожие проекты viewtopic.php?p=4686152#p4686152 |
Автор: | Daniil4829 [ Чт мар 06, 2025 22:45:43 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Используй Ардуино, в нем есть поддержка Мега8. Ну и куча библиотек с примерами. Немного не понял, делать все устройство на ардуине или использовать код от ардуины? Добавлено after 5 minutes 32 seconds: Подскажите еще пожалуйста, на сайте (https://aterlux.ru/article/nrf24l01p#__h2_42 )написано что собственный адрес 0xE7E7E7E7E7 а адрес удаленной стороны 0xC2C2C2C2C2. Получаеться у передатчика собственный адрес Е7, удаленной стороны С2; а у приемника собственный адрес С2, а удаленной стороны Е7? |
Автор: | VNS [ Пт мар 07, 2025 03:24:21 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
написано что собственный адрес 0xE7E7E7E7E7 а адрес удаленной стороны 0xC2C2C2C2C2. Получаеться Вложение: Вложение: Вложение:
|
Автор: | OKF [ Пт мар 07, 2025 08:13:23 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Немного не понял, делать все устройство на ардуине или использовать код от ардуины? Ардуино - это что? Это, по простому, контроллер и софт. Мега8 - это плата Ардуино NG or older. Почитай, поразбирайся... |
Автор: | roman.com [ Пт мар 07, 2025 10:55:32 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
0xE7E7E7E7E7 а адрес удаленной стороны 0xC2C2C2C2C2. Получаеться у передатчика собственный адрес Е7, удаленной стороны С2; а у приемника собственный адрес С2, а удаленной стороны Е7? надо что бы у приёмника и передатчика были одинаковые адреса. Иначе ничего работать не будет)) 0xE7E7E7E7E7 - это адрес по умолчанию (заводские настройки). -мы можем записать свой адрес (любой). СпойлерКод: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Адрес приёмника: // 0x0A RX_ADDR_P0: // .... .... 0xE7 - LSB. - Сначала записывается LSB. // .... .... 0xE7 - // .... .... 0xE7 - // .... .... 0xE7 - // .... .... 0xE7 - MSB. // 5 байтов - 0xE7E7E7E7E7 (11100111 11100111 11100111 11100111 11100111) - По умолчанию ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Адрес предатчика: // 0x10 RX_ADDR_P0: // .... .... 0xE7 - LSB. - Сначала записывается LSB. // .... .... 0xE7 - // .... .... 0xE7 - // .... .... 0xE7 - // .... .... 0xE7 - MSB. // 5 байтов - 0xE7E7E7E7E7 (11100111 11100111 11100111 11100111 11100111) - По умолчанию ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// всего может быть вот столько адресов 1.099.511.627.775 т.е. к одной ATmega8 мы можем подключить больше триллиона NRF24L01... )) и каждый NRF24L01 будет со своим уникальным адресом. ![]() -мы можем изменить длину адреса (от 2-х до 5-ти байт). СпойлерКод: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Длина Адрес: // 0x03 SETUP_AW: (2,3,4,5 bytes) // 0... .... 0 // .0.. .... 0 // ..0. .... 0 // ...0 .... 0 // .... 0... 0 // .... .0.. 0 // .... ..1. 1 Адрес // .... ...1 1 Адрес // '00' - 2 байта, (много помех). // '01' - 3 байта, // '10' - 4 байта, // '11' - 5 байтов - 0xE7E7E7E7E7 (11100111 11100111 11100111 11100111 11100111) - По умолчанию ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ![]() |
Автор: | codenamehawk [ Пт мар 07, 2025 16:11:48 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
roman.com, Я об этом писал, но правильнее звучит так: Настраиваем, задаем адрес передатчика Код: uint8_t to_address[5] = { 0x01, 0x01, 0x01, 0x01, 0x01 }; nRF24L01 *rf = setup_rf(); А приемник должен слушать этот адрес Код: uint8_t address[5] = { 0x01, 0x01, 0x01, 0x01, 0x01 };
nRF24L01 *rf = setup_rf(); nRF24L01_listen(rf, 0, address); |
Автор: | Daniil4829 [ Пт мар 07, 2025 16:38:53 ] | ||
Заголовок сообщения: | Re: NRF24L01 и ATmega8 | ||
Повтыкал во все функции отправку сообщений на UART, чтобы отследить в чем проблема. Передача вроде как пошла (судя по UART), а вот приёма нет ![]() Может подскажите чего не так) NRF24L01.C СпойлерКод: #include "NRF24L01.h" // Инициализация интерфейса void spi_init() { DDRB |= (1<<SS) | (1<<SCK) | (1<<MOSI); SPCR = (1 << SPE) | (1 << MSTR); // режим 0, мастер, частота 1/4 от частоты ЦП } // Передаёт и принимает 1 байт по SPI, возвращает полученное значение uint8_t spi_send_recv(uint8_t data) { SPDR = data; while (!(SPSR & (1 << SPIF))); return SPDR; } // Выбирает активное состояние (высокий уровень) на линии CE void radio_assert_ce() { RADIO_PORT |= (1 << RADIO_CE); // Установка высокого уровня на линии CE } // Выбирает неактивное состояние (низкий уровень) на линии CE void radio_deassert_ce() { RADIO_PORT &= ~(1 << RADIO_CE); // Установка низкого уровня на линии CE } // Поскольку функции для работы с csn не предполагается использовать в иных файлах, их можно объявить static // Выбирает активное состояние (низкий уровень) на линии CSN void csn_assert() { RADIO_PORT &= ~(1 << RADIO_CSN); // Установка низкого уровня на линии CSN } // Выбирает неактивное состояние (высокий уровень) на линии CSN void csn_deassert() { RADIO_PORT |= (1 << RADIO_CSN); // Установка высокого уровня на линии CSN } // Инициализирует порты 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; } // Читает значение однобайтового регистра reg (от 0 до 31) и возвращает его uint8_t radio_readreg(uint8_t reg) { csn_assert(); spi_send_recv((reg & 31) | R_REGISTER); uint8_t answ = spi_send_recv(0xFF); csn_deassert(); return answ; } // Записывает значение однобайтового регистра reg (от 0 до 31), возвращает регистр статуса uint8_t radio_writereg(uint8_t reg, uint8_t val) { csn_assert(); uint8_t status = spi_send_recv((reg & 31) | W_REGISTER); spi_send_recv(val); 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); } // Возвращает размер данных в начале FIFO очереди приёмника uint8_t radio_read_rx_payload_width() { csn_assert(); spi_send_recv(R_RX_PL_WID); uint8_t answ = spi_send_recv(0xFF); csn_deassert(); return answ; } // Выполняет команду. Возвращает регистр статуса uint8_t radio_cmd(uint8_t cmd) { csn_assert(); uint8_t status = spi_send_recv(cmd); csn_deassert(); return status; } // Возвращает 1, если на линии IRQ активный (низкий) уровень. uint8_t radio_is_interrupt() { return (RADIO_PIN & RADIO_IRQ) ? 0 : 1; } // Функция производит первоначальную настройку устройства. Возвращает 1, в случае успеха, 0 в случае ошибки uint8_t radio_start() { uint8_t self_addr[] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7}; // Собственный адрес uint8_t remote_addr[] = {0xC2, 0xC2, 0xC2, 0xC2, 0xC2}; // Адрес удалённой стороны uint8_t chan = 3; // Номер радио-канала (в диапазоне 0 - 125) 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(EN_AA, (1 << ENAA_P1)); // включение автоподтверждения только по каналу 1 radio_writereg(EN_RXADDR, (1 << ERX_P0) | (1 << ERX_P1)); // включение каналов 0 и 1 radio_writereg(SETUP_AW, SETUP_AW_5BYTES_ADDRESS); // выбор длины адреса 5 байт radio_writereg(SETUP_RETR, SETUP_RETR_DELAY_250MKS | SETUP_RETR_UP_TO_2_RETRANSMIT); radio_writereg(RF_CH, chan); // Выбор частотного канала radio_writereg(RF_SETUP, RF_SETUP_1MBPS | RF_SETUP_0DBM); // выбор скорости 1 Мбит/с и мощности 0dBm ///////////////////////////// radio_writereg_buf(RX_ADDR_P0, &remote_addr[0], 5); // Подтверждения приходят на канал 0 radio_writereg_buf(TX_ADDR, &remote_addr[0], 5); radio_writereg_buf(RX_ADDR_P1, &self_addr[0], 5); 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); // разрешение произвольной длины пакета данных radio_writereg(CONFIG, (1 << EN_CRC) | (1 << CRCO) | (1 << PWR_UP) | (1 << PRIM_RX)); // Включение питания return (radio_readreg(CONFIG) == ((1 << EN_CRC) | (1 << CRCO) | (1 << PWR_UP) | (1 << PRIM_RX))) ? 1 : 0; } // Помещает пакет в очередь отправки. // buf - буфер с данными, size - длина данных (от 1 до 32) uint8_t send_data(uint8_t * buf, uint8_t size) { radio_deassert_ce(); // Если в режиме приёма, то выключаем его uint8_t conf = radio_readreg(CONFIG); if (!(conf & (1 << PWR_UP))){ // Если питание по какой-то причине отключено, возвращаемся с ошибкой UART_send_string("E1"); return 0; } uint8_t status = radio_writereg(CONFIG, conf & ~(1 << PRIM_RX)); // Сбрасываем бит PRIM_RX if (status & (1 << TX_FULL_STATUS)){ // Если очередь передатчика заполнена, возвращаемся с ошибкой UART_send_string("E2"); return 0; } radio_write_buf(W_TX_PAYLOAD, buf, size); // Запись данных на отправку radio_assert_ce(); // Импульс на линии CE приведёт к началу передачи _delay_us(15); // Нужно минимум 10мкс, возьмём с запасом radio_deassert_ce(); UART_send_string("C1"); return 1; } // Вызывается, когда превышено число попыток отправки, а подтверждение так и не было получено. void on_send_error() { // TODO здесь можно описать обработчик неудачной отправки UART_send_string("F2"); } // Вызывается при получении нового пакета по каналу 1 от удалённой стороны. // buf - буфер с данными, size - длина данных (от 1 до 32) void on_packet(uint8_t * buf, uint8_t size) { UART_send_string("F1"); } void check_radio() { if ((PIND&(1<<0)))// Если прерывания нет, то не задерживаемся { UART_send_string("P0"); return; } UART_send_string("P1"); uint8_t status = radio_cmd(NOP); radio_writereg(STATUS, status); // Просто запишем регистр обратно, тем самым сбросив биты прерываний 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); UART_send_string("PE1"); } else { uint8_t bufik[32]; // буфер для принятого пакета radio_read_buf(R_RX_PAYLOAD, &bufik[0], l); // начитывается пакет if ((status & (7 << RX_P_NO)) == (1 << RX_P_NO)) { // если datapipe 1 UART_send_string("C2"); on_packet(&bufik[0], l); // вызываем обработчик полученного пакета } } status = radio_cmd(NOP); } } NRF24L01.h СпойлерКод: #ifndef NRF24L01_H_ #define NRF24L01_H_ #define F_CPU 1000000 #include <avr/io.h> #include <util/delay.h> #define RADIO_PORT PORTB #define RADIO_DDR DDRB #define RADIO_PIN PINB #define RADIO_CSN 2 #define RADIO_CE 1 #define RADIO_IRQ 0 #define MOSI PB3 #define MISO PB4 #define SS PB2 #define CE PB1 #define SCK PB5 #define IRQ PB0 uint8_t spi_send_recv(uint8_t data); void spi_init(); void radio_assert_ce(); void radio_deassert_ce(); void csn_assert(); void csn_deassert(); void radio_init(); uint8_t radio_read_buf(uint8_t cmd, uint8_t * buf, uint8_t count); uint8_t radio_write_buf(uint8_t cmd, uint8_t * buf, uint8_t count); uint8_t radio_readreg(uint8_t reg); uint8_t radio_writereg(uint8_t reg, uint8_t val); uint8_t radio_readreg_buf(uint8_t reg, uint8_t * buf, uint8_t count); uint8_t radio_writereg_buf(uint8_t reg, uint8_t * buf, uint8_t count); uint8_t radio_read_rx_payload_width(); uint8_t radio_cmd(uint8_t cmd); uint8_t radio_is_interrupt(); uint8_t radio_start(); uint8_t send_data(uint8_t * buf, uint8_t size); void check_radio(); /* Команды */ #define R_REGISTER 0x00 // + n Прочитать регистр n #define W_REGISTER 0x20 // + n Записать регистр n #define R_RX_PAYLOAD 0x61 // Принять данные данные из верхнего слота очереди приёмника. #define W_TX_PAYLOAD 0xA0 // Записать в очередь передатчика данные для отправки #define FLUSH_TX 0xE1 // Сбросить очередь передатчика #define FLUSH_RX 0xE2 // Сбросить очередь приёмника #define REUSE_TX_PL 0xE3 // Использовать повторно последний переданный пакет #define R_RX_PL_WID 0x60 // Прочитать размер данных принятого пакета в начале очереди приёмника. #define W_ACK_PAYLOAD 0xA8 // + p Записать данные для отправки с пакетом подтверждения по каналу p. #define W_TX_PAYLOAD_NOACK 0xB0 // Записать в очередь передатчика данные, для отправки без подтверждения #define NOP 0xFF // Нет операции. Может быть использовано для чтения регистра статуса /* Регистры */ #define CONFIG 0x00 // Регистр настроек #define EN_AA 0x01 // Выбор автоподтверждения #define EN_RXADDR 0x02 // Выбор каналов приёмника #define SETUP_AW 0x03 // Настройка размера адреса #define SETUP_RETR 0x04 // Настройка повторной отправки #define RF_CH 0x05 // Номер радиоканала, на котором осуществляется работа. От 0 до 125. #define RF_SETUP 0x06 // Настройка радиоканала #define STATUS 0x07 // Регистр статуса. #define OBSERVE_TX 0x08 // Количество повторов передачи и потерянных пакетов #define RPD 0x09 // Мощность принимаемого сигнала. Если младший бит = 1, то уровень более -64dBm #define RX_ADDR_P0 0x0A // 3-5 байт (начиная с младшего байта). Адрес канала 0 приёмника. #define RX_ADDR_P1 0x0B // 3-5 байт (начиная с младшего байта). Адрес канала 1 приёмника. #define RX_ADDR_P2 0x0C // Младший байт адреса канала 2 приёмника. Старшие байты из RX_ADDR_P1 #define RX_ADDR_P3 0x0D // Младший байт адреса канала 3 приёмника. Старшие байты из RX_ADDR_P1 #define RX_ADDR_P4 0x0E // Младший байт адреса канала 4 приёмника. Старшие байты из RX_ADDR_P1 #define RX_ADDR_P5 0x0F // Младший байт адреса канала 5 приёмника. Старшие байты из RX_ADDR_P1 #define TX_ADDR 0x10 // 3-5 байт (начиная с младшего байта). Адрес удалённого устройства для передачи #define RX_PW_P0 0x11 // Размер данных при приёме по каналу 0: от 1 до 32. 0 - канал не используется. #define RX_PW_P1 0x12 // Размер данных при приёме по каналу 1: от 1 до 32. 0 - канал не используется. #define RX_PW_P2 0x13 // Размер данных при приёме по каналу 2: от 1 до 32. 0 - канал не используется. #define RX_PW_P3 0x14 // Размер данных при приёме по каналу 3: от 1 до 32. 0 - канал не используется. #define RX_PW_P4 0x15 // Размер данных при приёме по каналу 4: от 1 до 32. 0 - канал не используется. #define RX_PW_P5 0x16 // Размер данных при приёме по каналу 5: от 1 до 32. 0 - канал не используется. #define FIFO_STATUS 0x17 // Состояние очередей FIFO приёмника и передатчика #define DYNPD 0x1C // Выбор каналов приёмника для которых используется произвольная длина пакетов. #define FEATURE 0x1D // Регистр опций /* Биты регистров */ // 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 байт. #define SETUP_AW_3BYTES_ADDRESS (1 << AW) #define SETUP_AW_4BYTES_ADDRESS (2 << AW) #define SETUP_AW_5BYTES_ADDRESS (3 << AW) // SETUP_RETR #define ARD 4 // 4 бита. Задаёт значение задержки перед повторной отправкой пакета: 250 x (n + 1) мкс #define ARC 0 // 4 битай. Количество повторных попыток отправки, 0 - повторная отправка отключена. #define SETUP_RETR_DELAY_250MKS (0 << ARD) #define SETUP_RETR_DELAY_500MKS (1 << ARD) #define SETUP_RETR_DELAY_750MKS (2 << ARD) #define SETUP_RETR_DELAY_1000MKS (3 << ARD) #define SETUP_RETR_DELAY_1250MKS (4 << ARD) #define SETUP_RETR_DELAY_1500MKS (5 << ARD) #define SETUP_RETR_DELAY_1750MKS (6 << ARD) #define SETUP_RETR_DELAY_2000MKS (7 << ARD) #define SETUP_RETR_DELAY_2250MKS (8 << ARD) #define SETUP_RETR_DELAY_2500MKS (9 << ARD) #define SETUP_RETR_DELAY_2750MKS (10 << ARD) #define SETUP_RETR_DELAY_3000MKS (11 << ARD) #define SETUP_RETR_DELAY_3250MKS (12 << ARD) #define SETUP_RETR_DELAY_3500MKS (13 << ARD) #define SETUP_RETR_DELAY_3750MKS (14 << ARD) #define SETUP_RETR_DELAY_4000MKS (15 << ARD) #define SETUP_RETR_NO_RETRANSMIT (0 << ARC) #define SETUP_RETR_UP_TO_1_RETRANSMIT (1 << ARC) #define SETUP_RETR_UP_TO_2_RETRANSMIT (2 << ARC) #define SETUP_RETR_UP_TO_3_RETRANSMIT (3 << ARC) #define SETUP_RETR_UP_TO_4_RETRANSMIT (4 << ARC) #define SETUP_RETR_UP_TO_5_RETRANSMIT (5 << ARC) #define SETUP_RETR_UP_TO_6_RETRANSMIT (6 << ARC) #define SETUP_RETR_UP_TO_7_RETRANSMIT (7 << ARC) #define SETUP_RETR_UP_TO_8_RETRANSMIT (8 << ARC) #define SETUP_RETR_UP_TO_9_RETRANSMIT (9 << ARC) #define SETUP_RETR_UP_TO_10_RETRANSMIT (10 << ARC) #define SETUP_RETR_UP_TO_11_RETRANSMIT (11 << ARC) #define SETUP_RETR_UP_TO_12_RETRANSMIT (12 << ARC) #define SETUP_RETR_UP_TO_13_RETRANSMIT (13 << ARC) #define SETUP_RETR_UP_TO_14_RETRANSMIT (14 << ARC) #define SETUP_RETR_UP_TO_15_RETRANSMIT (15 << ARC) // 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 #define RF_SETUP_MINUS18DBM (0 << RF_PWR) #define RF_SETUP_MINUS12DBM (1 << RF_PWR) #define RF_SETUP_MINUS6DBM (2 << RF_PWR) #define RF_SETUP_0DBM (3 << RF_PWR) #define RF_SETUP_1MBPS (0 << RF_DR_HIGH) #define RF_SETUP_2MBPS (1 << RF_DR_HIGH) #define RF_SETUP_250KBPS (1 << RF_DR_LOW) // этот режим не должен использоваться с контролем доставки // 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 #endif Передатчик СпойлерКод: #include "NRF24L01.h" #include "UART_8.h" int main(void) { DDRD |= (1<<7); PORTD &= ~(1<<7); DDRB &= ~(1<<0); PORTB |= (1<<0); radio_init(); while (!radio_start()) { UART_send_string("S1"); _delay_ms(1000); } _delay_ms(2000); UART_ini(); while(1) { uint8_t a = 0xAA; send_data(a,8); _delay_ms(500); } } Приёмник СпойлерКод: #include "NRF24L01.h" #include "UART_8.h" int main(void) { DDRB &= ~(1<<0); PORTB |= (1<<0); radio_init(); while (!radio_start()) { UART_send_string("S1"); _delay_ms(1000); } _delay_ms(2000); UART_ini(); while(1) { check_radio(); _delay_ms(500); } } В терминал у передатчика приходит С1, а у приёмника P0 Собираю на макетной плате, может ли быть дело в ней?
|
Автор: | Demiurg [ Сб мар 08, 2025 16:13:04 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Приветствую. Могу скинуть два проекта. Один передатчик. Второй приемник. Говорю сразу, разбираться будете сами. Проект модульный. Проект реализован на конечных автоматах. Switch-case технология. И сразу предупреждаю. Нельзя отправлять на эти трансмиттеры слово "test", "TEST". Приемник сразу виснет. Как я понял, это заводской параметр, который переводит трансмиттер в тестовый режим. |
Автор: | Daniil4829 [ Сб мар 08, 2025 18:48:20 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Буду очень благодарен:)) |
Автор: | roman.com [ Сб мар 08, 2025 19:45:52 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
а что... мой проект не понравился совсем... там просто всё... по максимуму )) и главное всё умещается на одну страницу кода... а не на несколько)) не люблю растягивать код по разным страницам... |
Автор: | Demiurg [ Сб мар 08, 2025 22:48:09 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Выложил архив. Проект из двух проектов. Передатчик, приемник. Передатчик. Дисплей. 20х4. В меню я могу вывести состояние трансмиттера и его регистров. Настройки, адреса и так далее. Кнопки. Нажимаем кнопки, на приемнике включаются соответствующие светодиоды. Приемник. Принимает команды. Включает соответствующие светодиоды. Проект я давно делал. Насколько мне помнится, был взаимообмен сообщениями. Один модуль был со внешней антенной. На 1000 м. Второй со внутренней. Почему я забросил этот проект. Время. Был занят. Для себя на тот момент не нашел практического применения. Всплыл нюанс. При тестировании по истечении времени терялась связь между модулями. Почему, не знаю. Повторю. Время. Был занят. Была задумка периодически переинициализировать модули. Но. Был занят. С этими трансмиттерами пришлось повозиться. Мануалы и примеры перечитал вдоль и поперек не раз. Напоминаю. Нельзя приёмнику отправлять сообщение "TEST". Это заводской параметр. проект Добавлено after 2 hours 33 seconds: roman.com, если не ошибаюсь, уже обсуждали. Это предпочтение. А в проектах ваши предпочтения это ваши проблемы, но не проекта. |
Автор: | roman.com [ Вс мар 09, 2025 14:57:21 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
ничего не понял)) |
Автор: | Demiurg [ Вс мар 09, 2025 17:13:47 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
По проекту. Или по моим словам? |
Автор: | roman.com [ Вс мар 09, 2025 17:42:14 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
по всему)) По проекту... много букаф)) у меня всё проще... -я открыл даташит и выписал нужные регистры NRF24L01. -далее пишем непосредственно регистры NRF24L01. всё)) код максимально компактный и без библиотек. всё просто и понятно. -можно писать для ATmega8... -можно писать для Ардуино... (Ардуино IDE работает напрямую с регистрами). всем советую делать так же.)) |
Автор: | Daniil4829 [ Вс мар 09, 2025 21:29:50 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Все выходные убил на эти мудули, а они все не как не работают ![]() Просмотрел проекты roman.com и Demiurg, результата большого не дало. Имееться 1 ардуина, собрал сканер каналов и проверил все модули - все рабочии. Собираю передатчик, отправляю пакет, читаю STATUS там бит TX_DS (успешная отправка). Приемник на отправленые пакеты не реагирует (не появляется прерывание). У меня тактовая частота указана 1мГц, а в SPI она ещë и на пополам делится, думаю, может частота маленькая слишком? Если нет, остается грешить только на питание.. |
Автор: | Demiurg [ Вс мар 09, 2025 22:27:39 ] |
Заголовок сообщения: | Re: NRF24L01 и ATmega8 |
Моему проекту много лет. Макетки разобраны. За тебя не буду паять. В моем проекте все настройки nrf модулей. Проект рабочий. Все регистры и адреса настроены. Смотри в настройки. Mirf. Nrf. Просто прошарься посмотри, где настройки. Ну мне некогда. Разберись сам. Если что. Потом в личку. Я тебе дал рабочий пример. Пропадание связи между модулями это нормальная ситуация. Этот диапазон связи засран. Вай фай, сигнализации, блютуз, автосигнализации и прочее. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |