Перейти к содержанию
    

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

Привод 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

28.12.2021 в 18:41, pruwait сказал:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

38 минут назад, Andrew_Q сказал:

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

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

Цитата

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 минут назад, Herz сказал:

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

 

Да, я неправ. Девятибитный фрейм даст 10 бит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 минут назад, jcxz сказал:

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30.12.2021 в 17:15, Freibier сказал:

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кажется это LIN

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

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

 

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

 

 

Изменено пользователем mitya1698

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...