Jump to content

    
Sign in to follow this  
pruwait

UART с нестандартным заголовком.

Recommended Posts

Привод Nice для распашных ворот имеет свой протокол обмена BusT4.

Два устройства (А и Привод) общаются через rx и tx.

Команда "Стоп" от А к приводу выглядит как стандартный uart 19200 8n1.

uart_stop.thumb.png.0a901dd75d732847f47e0e359a3f8010.png

Длина импульса условного бита примерно 52us, то есть каждый фрейм должен быть примерно 520us. (стоп бит + 8 + старт бит =10*52=520).

 

Но перед пакетом всегда добавлен заголовок, который не укладывается в 8n1. Выглядит как более длинный импульс, длиннее обычного фрейма на 1 бит!

uart_stop_header2.thumb.png.1c10313e7b98b64f7025c56d2934ef59.png

Далее следует ответ от мотора, что он всё понял и исполняет. И в этом ответе также есть нестандартный импульс. Только ещё более длительный и с паузой после него.

uart_stop_header3.thumb.png.5248e87b9e247132047f657d08b48c03.png

А дальше стандартный UART 8n1. Часть байт в посылках удалось быстро понять, это адрес спросившего, адрес получателя, данные, crc дважды в виде количества байт в посылке минус 3 и что-то ещё.

Если устройство А спрашивает у мотора номер прошивки, то в посылке добавляются байты данных, в которых есть ASCII символы текущей прошивки.

Желаю отправлять контроллером вроде ESP8266 или каким другим команду, которая выглядит как запрос от устройства А.

Сформировать UART 8n1 могу и на графике он такой же как оригинал. А вот с добавкой импульса беда. Уже голову сломал, пытаясь понять, как туда импульс этот добавить.

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

Нужна подсказка.

uart_stop_header.png

uart_stop_header_answer.png

uart_stop_header_answer.png

Share this post


Link to post
Share on other sites

В общем, пинок в нужном направлении сработал. 

Я не нашел на Ардуино библиотек, которые поддерживают uart.break, но нашел способ отправлять пакет с данными 0x00, изменив битрейт.

При скорости 17400 отправка 0x00 выглядит как нужный мне break на 19200.

Дальше переключаю на 19200 и отправляю основной пакет. Между break  и пакетом получился интервал 122us (Arduino Mega) вместо положенных 52us как в оригинальном сигнале.

Но контроллер мотора это всё съел и открылся по команде!

Share this post


Link to post
Share on other sites
28.12.2021 в 18:41, pruwait сказал:

Я не нашел на Ардуино библиотек, которые поддерживают uart.break,

Может потому, что УАРТ в АВР не умеет выдавать таких кадров...

Share this post


Link to post
Share on other sites
38 минут назад, Andrew_Q сказал:

Передать девятибитный фрейм. AVR умеет.

А разве достаточно? Пишут, что

Цитата

Стандартный UART Break содержит 11 нулевых битов подряд.

 

Share this post


Link to post
Share on other sites

Даже если AVR-овский UART не умеет BREAK, то почему бы просто ногу не перевести в режим GPIO и выдать импульс '0' нужной длительности? Или в AVR нельзя UART.TX в режим GPIO перевести?

Share this post


Link to post
Share on other sites
30.12.2021 в 17:15, Freibier сказал:

Проще запретить передатчик и сделать всё что нужно с выходом TX :)

Не проще, а только так и никак иначе.

30.12.2021 в 16:54, jcxz сказал:

Или в AVR нельзя UART.TX в режим GPIO перевести?

Только запретом передатчика. Но там это сделать проще, чем в стм перевести ногу в режим гпио)))

Share this post


Link to post
Share on other sites

Подобный метод синхронизации начала передачи пакета используется в разных протоколах, в частности в ДМХ512.

Программно проще реализовать BREAK через изменение скорости передачи. Ногодрыгом , или с использованием таймера - однозначно получается сложнее.

В UART  контроллера есть бит FRAME ERROR (название взял из PIC) по нему удобно отслеживать начало пакетов. В прерывании проверяем FRAME ERROR и подготавливаем переменные к приему кадра. Получается очень простая синхронизация по кадру.

Во многих МК включенный UART(аналогично и другие некоторые модули) имеют приоритет управления пином. Поэтому сначала нужно отключить передатчик , а потом уж дергать пин.  И дергать однократно пин программно на такую маленькую задерку не всегда простая задача , если работают прерывания нескольких таймеров , или другие прерывания. Поэтому аппаратно формировать через посылку 00 на меньшей скорости - оптимальное решение.

Share this post


Link to post
Share on other sites

Кажется это LIN

В STM32 делается просто:   USARTx->CR1 |= CR1_SBK_Set;
 

  • Поле Break — это поле представляет из себя 13 нулевых битов подряд.
  • Поле Sync — поле синхронизации. Этот байт имеет определенное значение — 0x55. Именно это число выбрано по той причине, что в двоичном виде оно представляет из себя чередующиеся нули и единицы — 0b01010101. При помощи этого поля устройства могут настроить свою скорость передачи данных.
  • Поле PID — поле идентификатора
  • Поле DATA
  • Поле CRC

 

На ATTINY делал софтварно на таймере и внешнем прерывании.

 

 

Edited by mitya1698

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this