STM32 Serial DMA - Нахождение начала потока
У меня есть известный формат последовательного потока, который я записываю через DMA. Имеет байты верхнего и нижнего колонтитула. Но иногда MCU начинает захват в середине потока, и затем синхронизация прекращается, потому что DMA ищет заданное количество байтов. Я читал о людях, использующих циклические буферы, но я изо всех сил пытался понять эту концепцию.
Вместо этого я думал об отключении DMA и включении последовательного прерывания при запуске MCU. Затем циклически перебирайте каждый байт, захваченный прерыванием, чтобы найти начальный байт. Затем, как только я нашел начальный байт, отключите захват последовательных прерываний и разрешите DMA захватить поток.
Это звучит выполнимо? Спасибо за любой вклад.
Я использую библиотеки STM32 HAL с новой средой разработки STM32, в которую входит STM32 CubeMX.
2 ответа
Если я правильно понимаю вашу ссылку на циклические буферы, концепция проста. У вас есть большой буфер с указателем записи и указателем чтения. Функция записи записывает данные в буфер с указателя записи и далее, следя за тем, чтобы, достигнув конца буфера, он оборачивался и сбрасывал данные в начале буфера и далее. Затем вам нужна функция чтения, которая считывает данные с указателя чтения и далее, и снова заботится о переносе в конец буфера.
И указатели чтения и записи начинаются с начала буфера. Два условия, которые вы должны проверить: 1) Когда указатель чтения находится в том же месте, что и указатель записи, нечего (больше) читать. 2) Когда указатель записи увеличивается и попадает в положение указателя чтения, возникает условие переполнения буфера. Этого никогда не должно происходить, поэтому либо вы должны использовать больший буфер, либо выполнять задачу чтения чаще, либо вы начинаете выбрасывать вещи.
Таким образом, в вашем сценарии DMA просто сбрасывает данные, и ваша задача чтения ищет байты заголовка и обрабатывает данные, пока не найдет байты нижнего колонтитула.
Поскольку протокол имеет промежутки времени простоя между пакетами, вы можете использовать функцию прерывания простоя UART для синхронизации приемника.
Включите прерывание UART, просто начните прием с DMA и установите UARTx->CR1 |= USART_CR1_IDLEIE
, Всякий раз, когда запускается простое прерывание, посмотрите на канал DMA, если он все еще работает, остановите передачу и отбросьте входной буфер (так как это означает, что прием был начат в середине пакета) и начните прием следующего пакета.