Как я могу автоматически вызывать UART_Receive_IT () при получении данных? - PullRequest
0 голосов
/ 18 апреля 2019

Я новичок в STM32 и freertos. Мне нужно написать программу для отправки и получения данных из модуля через порт UART. Я должен отправить (передать) данные в этот модуль (например, M66). Затем я бы вернулся, чтобы сделать некоторые другие задачи. как только M66 отправит на это ответ, моя seial-port-receive-function (HAL_UART_Receive_IT) должна быть вызвана и получить этот ответ. Как мне этого добиться?

Ответы [ 3 ]

1 голос
/ 19 апреля 2019

Способ работы HAL_UART_Receive_IT состоит в том, что вы настраиваете его для получения указанного количества данных в данный буфер.Вы даете ему свой буфер, в который он будет читать полученные данные и количество байтов, которые вы хотите получить.Затем он начинает получать данные.Как только получен именно такой объем данных, вызывается функция обратного вызова HAL_UART_RxCpltCallback (из IRQ), где вы можете делать с этими данными все, что хотите, например, добавлять их в какую-то очередь для последующей обработки в контексте задачи.

Если я хочу выразить свой опыт работы с модулем UART HAL, это то, что он не самый лучший для общего использования, когда вы не знаете объем данных, который вы ожидаете получить заранее.В случае с модемом M66, о котором вы упомянули, это будет происходить постоянно.

Чтобы решить эту проблему, у вас есть два варианта:

  1. Просто не используйте функции HAL ввсе в случае UART, кроме функций инициализации.Реализуйте свой собственный обработчик прерываний UART (большая часть кода может быть скопирована из обработчика в HAL), где после получения данных вы помещаете полученные байты в очередь приема байтов, обработанную в вашей задаче RTOS.В этой задаче вы реализуете парсинг протокола.Этот подход я использую лично.

  2. Если вы действительно хотите использовать HAL, но также работать с модулем, который отправляет различное количество данных, позвоните по номеру HAL_UART_Receive_IT и укажите, что вы хотитеполучать 1 байт каждый раз.Это будет работать, но будет (потенциально намного) медленнее, чем первый подход.Предполагая, что позже вы захотите реализовать некоторую связь по протоколу tcp / ip (вы упомянули модуль M66 GPRS), вы, вероятно, не захотите делать это таким образом.

0 голосов
/ 19 апреля 2019

Я бы предпочел другой подход.Вы, вероятно, хотите архивировать более высокие скорости (скажем, 921600 бод), и способ прерывания слишком медленный для этого.

Вам необходимо реализовать преобразование DMA с функциями обнаружения конца данных.Запустите USART в режиме DMA в круговом режиме.У вас будет два мероприятия.Первым из них является DMA-конец прерывания передачи (затем вы копируете данные из текущего хвостового указателя в конец буфера, чтобы избежать переопределения данных) и прерывание USART IDLE - это обнаружит конец приема.

0 голосов
/ 19 апреля 2019

Вы должны попробовать следующий способ.

Включить прерывание UARTX Rx в NVIC.Установите приоритет прерывания.Снимите маску с запроса прерывания в EXTI.

Затем используйте функцию обработчика прерываний USARTX Определите свой вектор.

При получении данных от USARTX эта функция вызывается автоматически, и вы можете копировать данные из USARTX. Получать данные.Регистрация.

...