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

STM32 HAL UART+DMA

Здравствуйте, уважаемые коллеги.

Прошу помочь разобраться с использованием связки UART+DMA на прием, в частности интересует работа функции HAL_UART_Receive_DMA(…). Сразу оговорюсь, что я перечитал много постов по этой теме на большинстве известных форумов и многое оттуда почерпнул. Теперь к сути: в большом проекте есть кусок, который отвечает за связь между двумя контроллерами, один из которых раз в несколько миллисекунд отправляет короткое сообщение (не более 20 байт) другому контроллеру сообщение все время одинакового размера. UART включен на прием, DMA работает в нормальном режиме (не в циклическом). В main вызываю HAL_UART_Receive_DMA(&huart5,(uint8_t*) mc_mes, 4);  //4 байта взято просто для эксперимента

В бесконечном цикле мониторю hdma_uart5_rx.State

                               if (hdma_uart5_rx.State == HAL_DMA_STATE_READY)

                               {

                                               HAL_UART_Receive_DMA(&huart5,(uint8_t*) mc_mes, 4);

                                               hdma_uart5_rx.State = HAL_DMA_STATE_BUSY;

                               }

Вот собственно и весь упрощенный код.

Как я понимаю работу этой функции, поправьте меня, если я не прав:

Вызывая функцию HAL_UART_Receive_DMA(…) мы передаем ей ожидаемое кол-во байт для приема. Этот параметр устанавливает внутренний счетчик DMA, (регистр NDT). Для каждого байта, который он получает, счетчик уменьшается на единицу, пока не достигнет нуля. Когда счетчик становится равен нулю происходит передача данных. В этот момент мы попадаем в условие (hdma_usart2_rx.State==HAL_DMA_STATE_READY_MEM0), где мы опять вызываем  функцию HAL_UART_Receive_DMA(…).

Проблема: если мы намеренно посылаем пакет большего размера чем у нас заявлено, например, вместо четырех байт отправим пять, то массив принятых данных сбивается, «лишние» эл-ты заносятся в массив mc_mes [] на первые места (так как будто DMA работает в циклическом режиме!). А этого быть не должно т.к. у нас режим работы DMA – нормальный.

Может кто-то сталкивался с такой проблемой и может объяснить, почему так происходит?

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


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

1 hour ago, lomy said:

рмальный.

Может кто-то сталкивался с такой проблемой и может объяснить, почему так происходит?

Нет никакой проблемы. Вы считали 4 байта, снова проинитили ДМА вызвав HAL_UART_Receive_DMA(…), указатель начала области памяти куда дма кладет данные снова встал на начало массива куда и занеслись лишние байты из посылки

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


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

В UART у STM есть очень удобное прерывание по событию idle. Оно возникает если после очередного байта была пауза кажется в 3 символа.

Делаете на прием два буфера для UART. Включаете DMA с прерыванием по idle. В прерывании переключаете буфера. В основной программе анализируете что там у вас в буфере.

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


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

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

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

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

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

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

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

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

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

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