Драйвер модуля tr24a или трансивера EM198810

Опубликовано в рубрике "Исходники", 2 октября, 2009.

TR24A – один из самых дешевых радиомодулей. Его выпускает фирма Spirit-On на основе микросхемы EM198810.

Основные характеристики модуля:

  • диапазон частот: 2400MHz…2482MHz
  • скорость данных: 1Mbps
  • Бюджет связи: 82dBm — 87dBm
  • диапазон напряжения питания: 2.5V…3.7V
  • ток потребления: в режиме передачи — 26mA, в режиме приёма — 25mA, в режиме сна — 3.5uA
  • дальность связи однотипных модулей: 50m…100m

Модуль имеет антенну на плате, что очень удобно. Не смотря на все достоинства, запустить трансивер – большая проблема из-за плохой документации. На TR24A я потратил довольно много времени и, надеюсь, мой опыт сможет вам пригодиться.tr24a

За основу моего драйвера был взят драйвер от Sonny (http://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

Распиновка этого радиомодуля показана в его даташите который можно без проблем найти в интернете.

 

Почитать еще

http://code.google.com/p/spiriton-tr24a-demo/

http://delanet.ru/content/view/532/1/ – тут есть даташит

 

Даташиты и апноуты

По прозьбе “типка” выкладываю всю документацию, что у меня есть по модулям.

 

Тестирование

Изначально это устройство планировалось как гальваническая развязка для трансформатора тесла. Однако приличных результатов получить так и не удалось. На помехоустойчивость модули я тестировал довольно экстравагантным методом:




Комментарии
  1. Alexander написал(а) 22 октября, 2009 в 7:48

    Какой реальной дальности обмена удалось достичь?
    При какой скорости и объёме передаваемых данных?

    BSVi Reply:

    Я тестировал модуль в квартире. Он пробивает 2 стены и почти сразу за второй глохнет. Если через одну стену то еще +10 метров гдето. Вполне возможно, что по прямой видимости он обеспечит заявленные 100 метров. Скорость у модуля фиксированная — 1мегабит/с.

    Alexander Reply:

    Стены, я надеюсь, железобетонные, а не кирпичные или деревянные? ;)
    Если так — то довольно неплохо для такой частоты и мощности. :)

    BSVi Reply:

    Одна стена — гипсокартоновая, вторая — железобетонная. В принципе, если нужно чтобы связь работала не в прямой видимости, лучше подыскать что-то другое.

    Alexander Reply:

    Да, для НЕпрямой видимости частота явно высоковата. :)

    Спасибо за публикацию!
    Будем пробовать реализовать нечто в этом роде на PIC.. :)

  2. a9d написал(а) 24 октября, 2009 в 14:35

    А что находится в файле fifo.h ? В архиве его нет.

    BSVi Reply:

    В этом файле класс _FIFO. Он не относится к драйверу, поэтому я не включил его в комплект. Тем-более, что с этим классом разобраться будет куда сложнее, чем с самими драйвером. Исходник — всего-лишь заготовка, которую вам прийдется перелопатить под свои нужды.

    К примеру, вместо
    rx_fifo->PutChar( SPI_Rx() );
    можно напсать что-то свое типа
    buffer[i] = SPI_Rx() ;
    итп.

    a9d Reply:

    Понятно.
    А в WinAVR классы пишуться точно также как и под PC? Уже много раз видел их использования но никто не вылаживает исходники, да и статей таких не видел.

    BSVi Reply:

    Да, совершенно так-же.

  3. Alexander Zhevak написал(а) 26 октября, 2009 в 19:06

    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. Проблемы как не бывало. И еще, я не совсем понял , собственно, назначение этого стабилизатора — у Вас же схему питает пара батареек. Я чего-то не замечаю?

    Спасибо.

    BSVi Reply:

    Импульсный стабилизатор был так как внутри теслы 12-вольтовое питание. Питание от батареек это только для теста. Пробовал питать от линейного стабилизатора — разницы совершенно никакой.

  4. Alexander Zhevak написал(а) 28 октября, 2009 в 7:58

    Коллега, Вы в курсе, что у Вас в функции SPI_init() выставляется бит фазы CPHA?

    В описании на EM198810 на рисунках хорошо показано, что ввод данных осуществляется по переднему фронту SCK, а не по заднему.

    Поясните пожалуйста Ваш ход.
    Спасибо.

    BSVi Reply:

    Дело в том, что фаза переключается одним из выводов микросхемы EM198810 (вывод называется CKPHA). А в документации на нее (заметьте, не на модуль) написанно «For illustration purpose, CKPHA=0 is shown».

    В модуле-же обитатели поднебесной поддянули CKPHA к питанию. Фаза перевернулась.

    Фазировка из статьи рбоатает на практике.

  5. Alexander Zhevak написал(а) 28 октября, 2009 в 21:12

    да. да. да.

    Сейчас протестировал: записал и снова считал инфу в один из регистров c CPHA = 0 и с CPHA = 1. Первый вариант выдал не соответствие.

    Разрисовал китайский код — точно! Так оно и есть — запись осуществляется по спаду.

  6. bioname написал(а) 4 ноября, 2009 в 10:40

    чуть больше недели мои два tr24a обмениваются. В помещении далеко не уйдёшь не потеряв связь. на открытой местности — довольно далеко. метров 50 точно. дальше начинаются потери. Что следует изначально сделать — добиться обмена мк с модулем. т.е. запись-чтение регистров, после записи некоторых регистров нужны небольшие временные задержки. Инициализацию упростил, выкинув повторные проверки. не нужны они там. просто после первой партии регистров притормозить, а потом продолжить. По инету бродит всего несколько версий кода для этого модуля. и они уж очень похожи друг на друга (значения регистров не считаю похожестью кода).
    Сложность работы с модулем считаю надуманной, сужу по себе — если бы внимательнее читал я даташит не через строчку, да не сидел до 5-6ч утра (естессно уже делая элементарные ошибки), то результат был бы «дешевле» здоровью.
    Писал под пик. но под пик там только обработка прерываний и работа с SPI.

  7. Andrey написал(а) 18 ноября, 2009 в 15:08

    Добрый день всем, у меня к Вам вопрос имеется. Мне тоже захотельсь сделать беспроводной интерфейс, я купил 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

    BSVi Reply:

    Звините, но у меня нет времени разбираться в вашем коде. Вы можете попробовать мой драйвер. Он гарантированно работает.

    Можно еще проверить
    1. полярность и фазу SPI и последовательность передачи битов
    2. Все задержки из даташита
    3. Правильность физического подключения — когда я испытывал модуль, у меня к SPI был подключен программатор. Модуль не работал. Как только я убрал программатор, сразу все запустилось.

  8. Bot написал(а) 23 ноября, 2009 в 14:11

    Исправь •Бюджет связи: 82dBm – 87dBm на «чувствительность приемника»

    BSVi Reply:

    Бюджет связи и чувствительность приемника — это разные вещи.
    Бюджет связи равен мощности передацичка минус чувствительность приемника и является более показательной цифрой для готового устройства, чем просто чувствительность.

  9. kalina написал(а) 28 ноября, 2009 в 16:26

    Всем, кто начинает работать с радиомодулем TR24A, рекомендую ознакомиться вот с этим документом http://www.emc.com.tw/twn/database/Data_Sheet/COM/EM198810.pdf и многое станет ясным….

    BSVi Reply:

    Ссылка не работает.

    kalina Reply:

    Только что проверил, она работоспособная…

    BSVi Reply:

    Ага, щя заработала. Похоже, что что-то проглючило — или у меня, или у них. А вообще этот докуменник был чутьли не основным про инаписании драйвера.

  10. Nick написал(а) 1 декабря, 2009 в 23:21

    А syncword не используется? reg52…55

    BSVi Reply:

    В коде все написанно. К сожалению, моя память не безконечна и я не помню весь код, который я писал.

  11. tipok написал(а) 12 декабря, 2009 в 18:15

    Здравствуйте, даташитом не поделитесь? Ато на деланете уже прикрыли.

    BSVi Reply:

    Добавил в статью под заголовком «Даташиты и апноуты»

  12. Ra3wum написал(а) 5 июня, 2010 в 12:36

    Как оцениваете возможность переноса вашего драйвера на ARM?

    BSVi Reply:

    Легко, не вижу проблем.

  13. agris написал(а) 8 июня, 2010 в 17:39

    Доброго времени суток, прошу помощи по TR24A.

    После вызова инциализации модуля не читаются регистры — один из двух TR24A все время возвращает 0xFFFF, а второй то 0x0000 то 0x0080.

    Использую ATMega48 и код от Sonny80 с ixbt (http://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 неживые и сгорели. Возможно, не стоило втыкать параллельно радиомодуль и программатор, или хз что.

    Что посоветуете?

    Заранее буду благодарен любым идеям. По результатам работ отпишусь подробно.

    BSVi Reply:

    Да, у меня были глюки из-за парралельно воткнутого программатора и трансивера.

    agris Reply:

    Спасибо за ответ.

    Да вот дело в том, что программатор я уже давно вынул. Разницы нет — одно и тоже. Видать, повредились TR24A из-за этого (может им +5В много). Не было такого? Программатор был в COM-порт через MAX232.

    А вообще, быстро наладился SPI обмен? Потому что у меня вообще регистры не читаются, я не у верен в том что они и пишуться… Самое странное, что два разных TR24A выдают при чтении разные данные — один всегда 0xFFFF, в второй 0x0000…

    BSVi Reply:

    может им +5В много. Конечно много! Ты их сжег однозначно!

    >А вообще, быстро наладился SPI обмен?
    Да, SPI запускается сразу. Вся проблема в значениях регистров.

    agris Reply:

    Бррр, значит опыт для следующих поколений — не стоит втыкать программатор и радиомодуль одновременно… Больше не будем. Послезавтра новая партия TR24A на тесты (надеюсь хоть эти 4 штуки новых выживут).

    Спасибо за ответ!

  14. Ray написал(а) 21 июня, 2010 в 16:28

    Недавно запустил трансивер TR24A. Даташит и аппноут с описанием регистров пришлось вычитать основательно, дабы вникнуть в суть. Код выложенного драйвера помог изрядно, заметно ускорив процесс разработки. Пока что между собой общаются две ATmega16 в оба направления. В будущем может быть необходимо обрабатывать сигнал FIFO_FLAG по внешнему прерыванию, но пока что в этом нет необходимости. Проект будет совершенствоваться.

    Хочу выразить автору статьи благодарность за обнародованный код.

    BSVi Reply:

    Да незачто ))

  15. Klim написал(а) 17 августа, 2010 в 12:20

    А такие большие задержки у вас в коде инициализации — это просто так, «на всякий случай» или были проблемы ?
    Тем более, там в аппноте написано, первая пауза 1-5мс, как-то неоднозначно. Хочется минимальное время старта для работы от батарейки.
    И сколько времени требуется на переключение между режимами RX/TX, неизвестно ?

    BSVi Reply:

    Я уже помню — много воты утекло с тех пор. Помоему, были проблемы. поэтому и оставил задержки. Время переключения должно быть написано в даташитах.

  16. GreenDot написал(а) 21 октября, 2012 в 12:09

    Собрал связку на STM32F417 + SRAM + видео камера, подключил к компу через USB, все работает. Хочу поставить камеру на удалении 2 км от компа и связать по радио каналу, скорость 5-6 Mbit/s, видимость непрямая.
    Посоветуйте без шнуровые Transceiver/Receiver варианты решения передачи цифровых данных на 2 км.

Создать новую ветку комментариев


Вы должны войти или зарегистрироваться чтобы оставить комментарий.