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

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

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

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

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

Модуль имеет антенну на плате, что очень удобно. Не смотря на все достоинства, запустить трансивер – большая проблема из-за плохой документации. На TR24A я потратил довольно много времени и, надеюсь, мой опыт сможет вам пригодиться.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/ – тут есть даташит

 

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

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

 

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

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

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

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

  2. BSVi написал(а) 22nd Октябрь, 2009 в 8:20

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

  3. Alexander написал(а) 22nd Октябрь, 2009 в 11:19

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

  4. BSVi написал(а) 22nd Октябрь, 2009 в 12:27

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

  5. Alexander написал(а) 22nd Октябрь, 2009 в 14:15

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

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

  6. a9d написал(а) 24th Октябрь, 2009 в 14:35

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

  7. BSVi написал(а) 24th Октябрь, 2009 в 15:20

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

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

  8. a9d написал(а) 24th Октябрь, 2009 в 18:16

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

  9. BSVi написал(а) 24th Октябрь, 2009 в 18:37

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

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

    Спасибо.

  11. BSVi написал(а) 26th Октябрь, 2009 в 21:05

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

  12. Alexander Zhevak написал(а) 28th Октябрь, 2009 в 7:58

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

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

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

  13. BSVi написал(а) 28th Октябрь, 2009 в 8:18

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

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

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

  14. Alexander Zhevak написал(а) 28th Октябрь, 2009 в 21:12

    да. да. да.

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

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

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

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

  16. Andrey написал(а) 18th Ноябрь, 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

  17. BSVi написал(а) 18th Ноябрь, 2009 в 16:02

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

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

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

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

  19. BSVi написал(а) 23rd Ноябрь, 2009 в 14:14

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

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

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

  21. BSVi написал(а) 28th Ноябрь, 2009 в 18:01

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

  22. kalina написал(а) 28th Ноябрь, 2009 в 23:24

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

  23. BSVi написал(а) 28th Ноябрь, 2009 в 23:36

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

  24. Nick написал(а) 1st Декабрь, 2009 в 23:21

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

  25. BSVi написал(а) 1st Декабрь, 2009 в 23:26

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

  26. tipok написал(а) 12th Декабрь, 2009 в 18:15

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

  27. BSVi написал(а) 12th Декабрь, 2009 в 19:53

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

  28. Ra3wum написал(а) 5th Июнь, 2010 в 12:36

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

  29. BSVi написал(а) 5th Июнь, 2010 в 12:44

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

  30. agris написал(а) 8th Июнь, 2010 в 17:39

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

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

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

  31. BSVi написал(а) 8th Июнь, 2010 в 19:35

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

  32. agris написал(а) 8th Июнь, 2010 в 21:07

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

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

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

  33. BSVi написал(а) 8th Июнь, 2010 в 23:22

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

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

  34. agris написал(а) 8th Июнь, 2010 в 23:41

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

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

  35. Ray написал(а) 21st Июнь, 2010 в 16:28

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

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

  36. BSVi написал(а) 21st Июнь, 2010 в 16:37

    Да незачто ))

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

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

  38. BSVi написал(а) 17th Август, 2010 в 12:23

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

  39. GreenDot написал(а) 21st Октябрь, 2012 в 12:09

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт защищен reCAPTCHA и применяются Политика конфиденциальности и Условия обслуживания применять.