От UART к UART Мост STM32

есть ли простой способ "связать" 2 линии U (S) ART (USART1 и UART5 на STM32F107) программно?

Мне нужно перенаправить данные, поступающие на USART1, на UART5 и обратно.

Текущий MCU - STM32F107VCT7

Основная причина, по которой я хочу это сделать, - обновить устройство через UART, которое подключено к моему MCU. MCU подключен к ПК.

ПК --- STM32 --- Другое устройство


person guenthernagel    schedule 20.06.2019    source источник
comment
Если обе линии ввода-вывода каждого UART подключены к другому, откуда берутся данные?   -  person Lee Daniel Crocker    schedule 21.06.2019
comment
К ST32 не подключены обе линии uart, ST32 должен обрабатывать пересылку данных. Подключение такое же, как: ПК - ST32 - другое устройство   -  person guenthernagel    schedule 21.06.2019
comment
Работают ли 2 UART (номинально) с одинаковой скоростью передачи?   -  person followed Monica to Codidact    schedule 21.06.2019
comment
Да, у них есть и 115200, и остальная часть конфигурации uart тоже такая же   -  person guenthernagel    schedule 21.06.2019
comment
Что вы пытаетесь сделать помимо передачи данных? Если вы хотите реализовать просто сниффер, почему бы просто не соединить два устройства прямыми проводами и подключить к ним вывод RX двух USART?   -  person AterLux    schedule 21.06.2019
comment
Мне нужно обновить устройство UART, но мой STM32 находится между компьютером и другим устройством. ПК --- STM - Другое устройство Прямое подключение невозможно   -  person guenthernagel    schedule 21.06.2019
comment
Это все еще очень сильно пахнет проблемой XY. Что это за странный дизайн, использующий 100-контактный микроконтроллер для соединения двух пар дорожек на печатной плате?   -  person followed Monica to Codidact    schedule 22.06.2019
comment
@berendi Ха-ха, не волнуйтесь, это не единственная задача MCU. Но среда не позволяет прямое соединение с другим устройством и ПК.   -  person guenthernagel    schedule 22.06.2019


Ответы (3)


Не могли бы вы просто записать данные в соответствующие регистры usart? То есть, если у вас есть байт, прошедший через строку usart1, и он хранится в регистре данных usart1, прочтите его и запишите в регистр данных usart5 и установите бит, чтобы чип знал, что он готов передать байт. Сделайте то же самое для моста usart5 - usart1.

Если вас беспокоит чтение / запись нескольких байтов, подумайте о добавлении буферов передачи и приема, чтобы справиться с этим.

Если бы мы использовали метод опроса, код выглядел бы примерно так (примечание: я в основном имею дело с AVR, поэтому я могу не использовать свои имена регистров, но метод должен быть примерно таким):



// Check to see if data has been written to usart1 and transfer it usart5.
if(USART1_CR1&(1 << USART1_SR_RXNE))
{
    // May want to avoid race conditions, so disable interrupts.
    // Write the data in usart1 to usart5
    USART5_DR = USART1_DR;

    // Set the data ready bit on the usart5 control register.
    USART5_CR1 |= (1 << USART_SR_RXNE);
    // Enable interrupts.
}

Я использовал это руководство для языка STM32. Не дело в отключении прерываний. Вы также можете захотеть записать в буфер.

person Matthew Robinson    schedule 20.06.2019
comment
@guenthernagel Я добавил фрагмент того, на что я ожидал. - person Matthew Robinson; 21.06.2019
comment
Пытался, но регистры не совпадают. В руководстве, на которое вы ссылались, они используют то же самое. Я использую HAL_Libray для связи с USART. Есть идеи, как принять? - person guenthernagel; 21.06.2019
comment
Чтобы узнать, как обмениваться данными от ПК к STM и обратно, просто напишите тестовую программу для STM и проверьте ее с помощью какого-нибудь эмулятора терминала на стороне ПК. Если вы это сделали, вы знаете, как использовать свою библиотеку, и можете реализовать другой канал. Тогда основная часть вашего транспорта будет довольно простой. - person the busybee; 21.06.2019
comment
@MatthewRobinson не используйте это руководство. Что такое USART5_DR? Используйте современные определения CMSIS, статья, кстати, очень плохая. - person 0___________; 22.06.2019

Простое копирование байтов с одного UART на другой не сработает.

Если передающая сторона (последовательный адаптер ПК) всего на 0,1% быстрее, чем MCU, она начнет отбрасывать байты после 1000-го байта. Точность частоты внутренних часов STM32F107 указана в таблице данных от -1,1% до + 1,8% при комнатной температуре, так что это могло произойти раньше, и два других участника также могут быть не совсем точными.

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

Вам нужны кольцевые буферы (FIFO) в обоих направлениях

Размер буфера определяется размером пакетов данных и суммой неточностей частоты в участвующих устройствах. Например. если в одном блоке содержится 64 КБ данных, и оба устройства имеют точность частоты +/- 2%, то вам потребуется буфер размером не менее 65536 * 0,04 ~ 2622 байта.

Делайте это в бесконечном цикле,

  • проверьте RXNE в USART1->SR
  • если установлено, считывать данные из USART1->DR и помещать их в начало буфера (громко жаловаться, если буфер заполнен)
  • проверьте TXE в UART5-> SR`
  • если установлено, И буфер не пуст, запишите байт в конце буфера в UART5->DR
  • сделайте то же самое для другого направления
person followed Monica to Codidact    schedule 22.06.2019
comment
Спасибо. Я боялся, что простая копия вообще не сработает. Проверим с кольцевым буфером, я читал об этом раньше. - person guenthernagel; 22.06.2019
comment
@berendi Нет, если между этими 1000 байтами есть пробелы (более 1 символа). Затем счетчик начинается с начала - person 0___________; 22.06.2019
comment
@P__J__ С точностью +/- 2% HSI на обоих концах он может выйти из строя на 25-м байте - person followed Monica to Codidact; 22.06.2019
comment
В зависимости от модели stm32 и даже для какой-то кремниевой версии. Некоторые из уартов компенсируют отклонения часов. Например, f303 на внутренних часах только что протестировал циклические случайные данные DMA со скоростью 1M из флэш-памяти. Никаких ошибок через 4 часа - person 0___________; 22.06.2019
comment
@P__J__ В этом и заключается проблема. Принимающий UART допускает отклонения скорости до 5%, но другой не будет передавать данные быстрее, чем запрограммированная скорость передачи. Буферы будут заполнены быстро. - person followed Monica to Codidact; 22.06.2019
comment
@guenthernagel Если у вас есть аппаратное обеспечение или управление потоком XON / XOFF, простая копия будет работать. - person tonypdmtr; 23.06.2019

Простой метод двусторонней связи, предполагающий одинаковую скорость обоих UART.

volatile uint8_t data[2];

void USART1_IRQHandler(void)
{
    if(USART1 -> SR & USART_SR_RXNE)
    {
        data[0] = USART1 -> DR;
        USART5 -> CR1 |= USART_CR1_TXEIE;
    }

    if( (USART1 -> CR1 & USART_CR_TXEIE) && (USART1 -> SR & USART_SR_TXE))
    {
        USART1 -> CR1 &= ~USART_CR1_TXEIE;
        USART1 -> DR = data[1];
    }
}

void USART5_IRQHandler(void)
{
    if(USART5 -> SR & USART_SR_RXNE)
    {
        data[1] = USART5 -> DR;
        USART1 -> CR1 |= USART_CR1_TXEIE;
    }

    if( (USART5 -> CR1 & USART_CR_TXEIE) && (USART5 -> SR & USART_SR_TXE))
    {
        USART5 -> CR1 &= ~USART_CR1_TXEIE;
        USART5 -> DR = data[0];
    }
}
person 0___________    schedule 22.06.2019
comment
Спасибо. Пробовал с небольшими изменениями (см. Мой вопрос-ответ с кодом), но он не работает. - person guenthernagel; 22.06.2019
comment
@guenthernagel Конечно, не будет. Вы видели где-нибудь в моем коде вызовы функций HAL? - person 0___________; 22.06.2019
comment
Нет, но прерывания генерируются Cube IDE. - person guenthernagel; 22.06.2019
comment
Ха-ха. Куб генерирует функции прерывания, а остальное HAL_UART_IRQHandler(&huart1); без библиотеки HAL. Почему не должно работать? - person guenthernagel; 22.06.2019