UART в UART Мост STM32 - PullRequest
       74

UART в UART Мост STM32

0 голосов
/ 21 июня 2019

Есть ли простой способ "соединить" линии 2 U (S) ART (USART1 и UART5 на STM32F107) с помощью программного обеспечения?

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

Текущий MCU - STM32F107VCT7

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

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

Ответы [ 4 ]

1 голос
/ 21 июня 2019

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

0 голосов
/ 22 июня 2019

Я попробовал ответ сверху с небольшими изменениями:

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  if(USART1 -> SR & USART_SR_RXNE)
     {
         data[0] = USART1 -> DR;
         UART5 -> CR1 |= USART_CR1_TXEIE;
     }

     if( (USART1 -> CR1 & USART_CR1_TXEIE) && (USART1 -> SR & USART_SR_TXE))
     {
         USART1 -> CR1 &= ~USART_CR1_TXEIE;
         USART1 -> DR = data[1];
     }
  /* USER CODE END USART1_IRQn 1 */
}




/**
  * @brief This function handles UART5 global interrupt.
  */
void UART5_IRQHandler(void)
{
  /* USER CODE BEGIN UART5_IRQn 0 */

  /* USER CODE END UART5_IRQn 0 */
  HAL_UART_IRQHandler(&huart5);
  /* USER CODE BEGIN UART5_IRQn 1 */

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

     if( (UART5 -> CR1 & USART_CR1_TXEIE) && (UART5 -> SR & USART_SR_TXE))
     {
         UART5 -> CR1 &= ~USART_CR1_TXEIE;
         UART5 -> DR = data[0];
     }

  /* USER CODE END UART5_IRQn 1 */
}

Но нет связи между обеими линиями UART.

0 голосов
/ 22 июня 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];
    }
}
0 голосов
/ 22 июня 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
  • сделать то же самое для другого направления
...