Программирование ARM STM32: ADC с использованием DMA и двойной буферизации Tue, January 25 2022  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

STM32: ADC с использованием DMA и двойной буферизации Печать
Добавил(а) microsin   

В архиве [6] находятся два простых примера, в которых демонстрируется оцифровка сигнала с помощью аппаратного DMA и двойной буферизации. Это дает возможность программно обрабатывать одну половинку буфера, в то время как аппаратура DMA заливает выборки сигнала в другую половинку. Достоинство такого метода - разгрузка процессора, который освобождается от лишних прерываний и переноса данных из ADC в память. Прерывания происходят только по заполнению каждой половины буфера, а перемещением данных ADC -> память занимается DMA. Оба проекта примера тестировались в среде IAR Embedded Workbench версии 8.30.1 на отладочной плате 32F429IDISCOVERY [1].

В двух примерах запуск ADC реализован по-разному. В примере проекта woTimer периферийное устройство ADC работает в режиме "свободной оцифровки", запуская себя само по окончанию преобразования. Поэтому в этом случае для запуска преобразования ADC таймер не используется, и частота дискретизации подбирается выбором частоты тактирования ADC и запрограммированным количеством циклов для времени выборки ADC. Во втором примере wTimer для запуска ADC используется таймер TIM3. За основу обоих примеров взят проект примера ADC_RegularConversion_DMA из пакета библиотек STM32Cube_FW_F4_V1.24.0.

Назначение файлов и папок архива [6]:

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

doc - документация.

doc\STMicroelectronics-Nicolas-FILLON - обучающий урок, из которого был взят принцип запуска ADC по таймеру.

settings\Project.wsdt - настройки рабочей среды IAR.

STM32Cube_FW_F4_V1.24.0 - библиотечные модули от STMicroelectronics, которые использовались в проектах.

woTimer - проект примера ADC + DMA, где для запуска преобразования ADC3 не используется таймер.

woTimer - проект примера ADC + DMA, для запуска преобразования ADC3 не используется таймер TIM3.

Процессор STM32F429ZI работает на тактовой частоте 144 МГц, частота тактирования шины APB2 72 МГц. От тактов шины APB2 с помощью прескалера генерируется частота тактирования ADC3. Для индикации запуска обработчиков прерываний DMA используются светодиоды LED3 (зеленый) и LED4 (красный), подключенные к ножкам портов PG13 и PG14 соответственно.

[Проект woTimer]

В этом проекте примера для запуска преобразования ADC таймер не используется. ADC запускается автоматически по завершению собственного преобразования. Достоинство такого подхода - экономится таймер, потому что он не используется для запуска ADC. Недостаток - неудобно устанавливать частоту дискретизации, потому что для требуется подбирать коэффициент деления прескалера ADC, а иногда даже тактовую частоту шины периферийных устройств и системную тактовую частоту процессора. Такой способ запуска ADC подойдет для случаев, когда не нужно точно устанавливать частоту оцифровки, и не требуется её менять на лету.

Отличие этого проекта от проекта ADC_RegularConversion_DMA из пакета библиотек STM32Cube_FW_F4_V1.24.0:

1. Изменен размер буфера оцифровки. В оригинальном проекте ADC_RegularConversion_DMA это была только одна выборка. Прерывание DMA срабатывало с частотой дискретизации. В проекте woTimer буфер выбран размером в 512 выборок, и прерывание DMA срабатывает в 512 раз реже.

2. Используется два обработчика прерывания DMA - один запускается при заполнении половины буфера (HAL_ADC_ConvHalfCpltCallback), второй при заполнении буфера целиком (HAL_ADC_ConvCpltCallback). Это дает возможность использовать двойную буферизацию - когда сработало прерывание HAL_ADC_ConvHalfCpltCallback, то можно программно обрабатывать первую половину буфера, а когда сработало прерывание HAL_ADC_ConvCpltCallback - вторую половину буфера. Принцип двойной буферизации подсмотрел из поста на stackoverflow.com [3].

Ниже на скриншоте осциллографа (Rigol 1102C) показана осциллограмма сигналов на ножках GPIO LED3 и LED4. Импульс LED3 показывает запуск обработчика HAL_ADC_ConvCpltCallback, а LED4 обработчика HAL_ADC_ConvHalfCpltCallback. Видно, что они запускаются поочередно, что соответствует заполнению половинок общего буфера.

ADC DMA woTimer

[Проект wTimer]

Этот пример использует таймер для запуска преобразования ADC. Здесь частота дискретизации зависит от частоты событий обновления таймера. Такой способ запуска подойдет для приложений, где нужно точно устанавливать частоту дискретизации, и появляется возможность легко менять частоту дискретизации во время работы программы.

Этот проект отличается от проекта woTimer только наличием настройки таймера TIM3 и соответствующим изменением настройки запуска ADC.

ADC DMA wTimer

[Ссылки]

1STM32F429 Discovery.
2. Hands-On with STM32 Timers: Trigger Periodic ADC Conversions site:youtube.com.
3. STM32 ADC DMA Double/Multi Buffer example site:stackoverflow.com.
4. AN3126: формирование аудиосигнала с помощью DAC STM32.
5. STM32: использование контроллера DMA.
6. 211031ADC-DMA-double-buffer.zip - примеры кода, документация.

 

Добавить комментарий


Защитный код
Обновить

Top of Page