Драйвер модуля tr24a или трансивера EM198810
TR24A – один из самых дешевых радиомодулей. Его выпускает фирма Spirit-On на основе микросхемы EM198810.
Основные характеристики модуля:
-
диапазон частот: 2400MHz…2482MHz
-
скорость данных: 1Mbps
-
Бюджет связи: 82dBm — 87dBm
-
диапазон напряжения питания: 2.5V…3.7V
-
ток потребления: в режиме передачи — 26mA, в режиме приёма — 25mA, в режиме сна — 3.5uA
-
дальность связи однотипных модулей: 50m…100m
Модуль имеет антенну на плате, что очень удобно. Не смотря на все достоинства, запустить трансивер – большая проблема из-за плохой документации. На TR24A я потратил довольно много времени и, надеюсь, мой опыт сможет вам пригодиться.
За основу моего драйвера был взят драйвер от Sonny (https://code.google.com/p/spiriton-tr24a-demo/). Не смотря на большую дальность связи этот драйвер часто затыкался от помех. Пришлось штудировать регистры трансивера и, часто методом тыка, добиваться оптимального баланса между помехоустойчивостью и дальностью связи.
Драйвер написан для atmega88 и и использованием компилятора IAR. Естественно, драйвер писался под конкретную задачу, и, поэтому, в нем остались ее куски.
В этом исходнике используются несколько моих типов данных ( _FIFO, uint8 итп ), однако переделать их под вашу архитектуру/компилятор/типы данных не составит проблем. Самое ценное тут – это значение регистров.
Драйвер разделен на две части. Одна из них – интерфейс с SPI, а вторая – драйвер tr24a.
Частоту, на которой работает трансивер можно вычислить как f = 2402 + CH_NO, где CH_NO – номер канала.
Формат пакетов, которые передает трансивер таков (За CRC отвечает сам радиомодуль):
Длинна 1 байт |
Адрес 1 байт |
Команда 1 байт |
Данные |
Пример передающей программы
/* запускаем трансивер. 0x10 - номер частоты в частотной сетке, 0x20 - адрес текущего радиомодуля. */ em_init(0x10, 0x20, NULL); /* разрешаем прерывания */ _EINT(); /* послылаем содержимое буффера по адресу 0x30. */ em_Send( &fifo, fifo.count(), 0x30, 0x01 );
Этот код скопирует буфер в память трансивера и начнет передачу. Он вернет управление не дожидаясь конца передачи. Узнать окончена передача или нет можно, проверив переменную em_Mode на равенство em_tx.
Пример принимающей программы
/* запускаем трансивер. 0x10 - номер частоты в частотной сетке, 0x30 - адрес принимающего радиомодуля. */ em_init( 0x10, 0x30, NULL); /* разрешаем прерывания */ _EINT(); /* запускаем приемник, приемник скопирует данные в буффер fifo */ em_EnterRecvMode( &fifo ); /* ожидаем пакет */ while( em_Mode == em_rx ) {};
Есть два способа узнать о том, что данные приняты – проверять переменную em_Mode, или указать CALLBACK – функцию при вызове em_init.
Особенности
Принимающая функция выполняет довольно большой код в прерывании (копирует буффер трансивера в контроллер). Для того, чтобы в это время нормально работали прерывания таймеров, используются вложенные прерывания. В некоторых случаях, это может стать причиной переполнения стека.
В отладочных целях, в функции em_init() есть множество ловушек на которых контроллер повиснет, если что-то пошло не так.
У меня были проблемы с инициализацией, пока на тех-же линиях SPI что и модуль висели провода от avrDragon’а.
Пример включения tr24a
Распиновка этого радиомодуля показана в его даташите который можно без проблем найти в интернете.
Почитать еще
https://code.google.com/p/spiriton-tr24a-demo/
https://delanet.ru/content/view/532/1/ – тут есть даташит
Даташиты и апноуты
По прозьбе “типка” выкладываю всю документацию, что у меня есть по модулям.
Тестирование
Изначально это устройство планировалось как гальваническая развязка для трансформатора тесла. Однако приличных результатов получить так и не удалось. На помехоустойчивость модули я тестировал довольно экстравагантным методом:
Какой реальной дальности обмена удалось достичь?
При какой скорости и объёме передаваемых данных?
Я тестировал модуль в квартире. Он пробивает 2 стены и почти сразу за второй глохнет. Если через одну стену то еще +10 метров гдето. Вполне возможно, что по прямой видимости он обеспечит заявленные 100 метров. Скорость у модуля фиксированная — 1мегабит/с.
Стены, я надеюсь, железобетонные, а не кирпичные или деревянные? 😉
Если так — то довольно неплохо для такой частоты и мощности. 🙂
Одна стена — гипсокартоновая, вторая — железобетонная. В принципе, если нужно чтобы связь работала не в прямой видимости, лучше подыскать что-то другое.
Да, для НЕпрямой видимости частота явно высоковата. 🙂
Спасибо за публикацию!
Будем пробовать реализовать нечто в этом роде на PIC.. 🙂
А что находится в файле fifo.h ? В архиве его нет.
В этом файле класс _FIFO. Он не относится к драйверу, поэтому я не включил его в комплект. Тем-более, что с этим классом разобраться будет куда сложнее, чем с самими драйвером. Исходник — всего-лишь заготовка, которую вам прийдется перелопатить под свои нужды.
К примеру, вместо
rx_fifo->PutChar( SPI_Rx() );
можно напсать что-то свое типа
buffer[i] = SPI_Rx() ;
итп.
Понятно.
А в WinAVR классы пишуться точно также как и под PC? Уже много раз видел их использования но никто не вылаживает исходники, да и статей таких не видел.
Да, совершенно так-же.
1.
Спасибо автору за то, что обнародовали свой код. Причем не просто так-себе код юного радиолюбителя, а нормальный. Мне понравился подход инициализации модуля, в котором учитывается номер канала и адрес. Я, правда, это делал немного по другому. Брутальнее. Ваш код более красивый 🙂 (негласное правило: красивая схема работает лучше, красивый код более робастый).
2.
Всем, кто идет этой же дорожкой — китайский демо-код — это ужас летящий на крыльях ночи. Крайне не рекомендую ни повторять его, ни пытаться на его примере изучать работу TR24A. Вот пара простейших доказательств халтурного отношения к делу:
1) две совершенно одинаковые функции Raed_FIFO_End и Write_FIFO_End
и
2) многкратно встречающаяся в исходнике последовательность:
Port_status = Port_B;
Port_status |= RF_CSB;
Port_status &= ~RF_CLK;
Port_B = Port_status;
3.
Цитата:
Изначально это устройство планировалось как гальваническая развязка для трансформатора тесла. Однако приличных результатов получить так и не удалось.
Вопрос:
У Вас там на схеме стоит импульсный стабилизатор. А обычный 7805 (или LDO) не пробовали поставить? Если да, то каков результат? Я как-то в одной разработке долго не мог получить хороших результатов. Потом плюнул, и заменил 34063 на 7805. Проблемы как не бывало. И еще, я не совсем понял , собственно, назначение этого стабилизатора — у Вас же схему питает пара батареек. Я чего-то не замечаю?
Спасибо.
Импульсный стабилизатор был так как внутри теслы 12-вольтовое питание. Питание от батареек это только для теста. Пробовал питать от линейного стабилизатора — разницы совершенно никакой.
Коллега, Вы в курсе, что у Вас в функции SPI_init() выставляется бит фазы CPHA?
В описании на EM198810 на рисунках хорошо показано, что ввод данных осуществляется по переднему фронту SCK, а не по заднему.
Поясните пожалуйста Ваш ход.
Спасибо.
Дело в том, что фаза переключается одним из выводов микросхемы EM198810 (вывод называется CKPHA). А в документации на нее (заметьте, не на модуль) написанно «For illustration purpose, CKPHA=0 is shown».
В модуле-же обитатели поднебесной поддянули CKPHA к питанию. Фаза перевернулась.
Фазировка из статьи рбоатает на практике.
да. да. да.
Сейчас протестировал: записал и снова считал инфу в один из регистров c CPHA = 0 и с CPHA = 1. Первый вариант выдал не соответствие.
Разрисовал китайский код — точно! Так оно и есть — запись осуществляется по спаду.
чуть больше недели мои два tr24a обмениваются. В помещении далеко не уйдёшь не потеряв связь. на открытой местности — довольно далеко. метров 50 точно. дальше начинаются потери. Что следует изначально сделать — добиться обмена мк с модулем. т.е. запись-чтение регистров, после записи некоторых регистров нужны небольшие временные задержки. Инициализацию упростил, выкинув повторные проверки. не нужны они там. просто после первой партии регистров притормозить, а потом продолжить. По инету бродит всего несколько версий кода для этого модуля. и они уж очень похожи друг на друга (значения регистров не считаю похожестью кода).
Сложность работы с модулем считаю надуманной, сужу по себе — если бы внимательнее читал я даташит не через строчку, да не сидел до 5-6ч утра (естессно уже делая элементарные ошибки), то результат был бы «дешевле» здоровью.
Писал под пик. но под пик там только обработка прерываний и работа с SPI.
Добрый день всем, у меня к Вам вопрос имеется. Мне тоже захотельсь сделать беспроводной интерфейс, я купил tr24a и начал его програмить, но не тут то было. Для начала читаю регистры передатчика, но опять ничего он просто молчит на MISO ничего нет. Читаю уже 399 раз пдф. все сделал как написано, но в ответ тишина. Пробовал для согласования уровней 5 на 3,3 В и симиторы и делители, всеровно. Синал приходит уже красивый с хорошими фронтами. Использую мегу16 с 16 МГц кварц, вот программка, подскажите мне что я делаю не так, чатота SPI 5kHz. пауза между байтами 3мкс, между фреймами 6 мкс.
;Stack
LDI xl,LOW(ramend)
OUT SPL,xl
LDI xl,HIGH(ramend)
OUT SPH,xl
;SPI
ldi xl,(1<<SPE|1<<MSTR|1<<CPHA|0<<DORD|1<<SPR1|1<<SPR0);|0<<CPOL);|1<<SPIE)
out spcr,xl
;Ports
ldi xl,(1<<RESET_n|0<<FIFO_flag|0<<PKT_flag|1<<SS|0<<Din|1<<Dout|1<<CLK)
out ddrb, xl
ser xl
out ddra,xl
out ddrc,xl
sbi portb, RESET_n ;RESET
sbi portb, ss
rcall longwait ;10 ms
loop:
cbi portb, ss
rcall del
ldi r16,$30
out spdr, r16
sbis spsr,spif
rjmp PC-1
rcall del
ldi r16,$ff
out spdr, r16
sbis spsr,spif
rjmp PC-1
ldi r16, 129
in r16, spdr
out portc, r16
rcall del
ldi r16,$ff
out spdr, r16
sbis spsr,spif
rjmp PC-1
ldi r16, 129
in r16, spdr
out portc, r16
rcall del
sbi portb, ss
rcall wait
rjmp loop
Звините, но у меня нет времени разбираться в вашем коде. Вы можете попробовать мой драйвер. Он гарантированно работает.
Можно еще проверить
1. полярность и фазу SPI и последовательность передачи битов
2. Все задержки из даташита
3. Правильность физического подключения — когда я испытывал модуль, у меня к SPI был подключен программатор. Модуль не работал. Как только я убрал программатор, сразу все запустилось.
Исправь •Бюджет связи: 82dBm – 87dBm на «чувствительность приемника»
Бюджет связи и чувствительность приемника — это разные вещи.
Бюджет связи равен мощности передацичка минус чувствительность приемника и является более показательной цифрой для готового устройства, чем просто чувствительность.
Всем, кто начинает работать с радиомодулем TR24A, рекомендую ознакомиться вот с этим документом http://www.emc.com.tw/twn/database/Data_Sheet/COM/EM198810.pdf и многое станет ясным….
Ссылка не работает.
Только что проверил, она работоспособная…
Ага, щя заработала. Похоже, что что-то проглючило — или у меня, или у них. А вообще этот докуменник был чутьли не основным про инаписании драйвера.
А syncword не используется? reg52…55
В коде все написанно. К сожалению, моя память не безконечна и я не помню весь код, который я писал.
Здравствуйте, даташитом не поделитесь? Ато на деланете уже прикрыли.
Добавил в статью под заголовком «Даташиты и апноуты»
Как оцениваете возможность переноса вашего драйвера на ARM?
Легко, не вижу проблем.
Доброго времени суток, прошу помощи по TR24A.
После вызова инциализации модуля не читаются регистры — один из двух TR24A все время возвращает 0xFFFF, а второй то 0x0000 то 0x0080.
Использую ATMega48 и код от Sonny80 с ixbt (https://forum.ixbt.com/topic.cgi?id=48:7870-5)
Proteus в SPI-отладчике пишет что все передается хорошо в чип.
Вот кусочек кода чтения регистров
char msg[32];
u16 val;
u8 val_L, val_H;
//Test write
val = 0xAABB;
val_L = val; //Load lower 8-bits
val_H = (val >> 8); // Load upper 8-bits
sprintf(msg, «*TEST_L: %d*\r\n», val_L);
uart_putmessage(msg);
sprintf(msg, «*TEST_H: %d*\r\n», val_H);
uart_putmessage(msg);
for (int i=0;i> 8); // Load upper 8-bits
sprintf(msg, «***REG %i**Lo bit: %i***\r\n», i, val_L);
uart_putmessage(msg);
sprintf(msg, «***REG %i**Hi bit: %i***\r\n», i, val_H);
uart_putmessage(msg);
}
Выглядит так, как будто TR24A неживые и сгорели. Возможно, не стоило втыкать параллельно радиомодуль и программатор, или хз что.
Что посоветуете?
Заранее буду благодарен любым идеям. По результатам работ отпишусь подробно.
Да, у меня были глюки из-за парралельно воткнутого программатора и трансивера.
Спасибо за ответ.
Да вот дело в том, что программатор я уже давно вынул. Разницы нет — одно и тоже. Видать, повредились TR24A из-за этого (может им +5В много). Не было такого? Программатор был в COM-порт через MAX232.
А вообще, быстро наладился SPI обмен? Потому что у меня вообще регистры не читаются, я не у верен в том что они и пишуться… Самое странное, что два разных TR24A выдают при чтении разные данные — один всегда 0xFFFF, в второй 0x0000…
может им +5В много. Конечно много! Ты их сжег однозначно!
>А вообще, быстро наладился SPI обмен?
Да, SPI запускается сразу. Вся проблема в значениях регистров.
Бррр, значит опыт для следующих поколений — не стоит втыкать программатор и радиомодуль одновременно… Больше не будем. Послезавтра новая партия TR24A на тесты (надеюсь хоть эти 4 штуки новых выживут).
Спасибо за ответ!
Недавно запустил трансивер TR24A. Даташит и аппноут с описанием регистров пришлось вычитать основательно, дабы вникнуть в суть. Код выложенного драйвера помог изрядно, заметно ускорив процесс разработки. Пока что между собой общаются две ATmega16 в оба направления. В будущем может быть необходимо обрабатывать сигнал FIFO_FLAG по внешнему прерыванию, но пока что в этом нет необходимости. Проект будет совершенствоваться.
Хочу выразить автору статьи благодарность за обнародованный код.
Да незачто ))
А такие большие задержки у вас в коде инициализации — это просто так, «на всякий случай» или были проблемы ?
Тем более, там в аппноте написано, первая пауза 1-5мс, как-то неоднозначно. Хочется минимальное время старта для работы от батарейки.
И сколько времени требуется на переключение между режимами RX/TX, неизвестно ?
Я уже помню — много воты утекло с тех пор. Помоему, были проблемы. поэтому и оставил задержки. Время переключения должно быть написано в даташитах.
Собрал связку на STM32F417 + SRAM + видео камера, подключил к компу через USB, все работает. Хочу поставить камеру на удалении 2 км от компа и связать по радио каналу, скорость 5-6 Mbit/s, видимость непрямая.
Посоветуйте без шнуровые Transceiver/Receiver варианты решения передачи цифровых данных на 2 км.