:::: MENU ::::

STM32 DMA

Процедура конфигурации канала DMA.

Итак, первоначально надо определиться с источником и получателем данных, откуда и куда будем пересылать. Фактически все задается прямыми адресами в пространстве памяти, для этого предназначены два регистра: DMA_CPARx (базовый адрес периферии) и DMA_CMARx (базовый адрес памяти). В этих регистрах заданы начальные адреса, они остаются неизменными.

Затем надо определиться с общим количеством данных. Допустим, мы проводим измерения с помощью АЦП, хотим провести N измерений, а затем усреднить. N раз нам надо передать результат измерений АЦП в память. Вот это количество транзакций (N) задается через регистр DMA_CNTDRx – по сути это счетчик с начальным значением, которое декрементируется на 1 после каждой пересылки данных.

Еще необходимо задать следующие параметры:

1. Установка уровней приоритета каналов. Тут уж надо самостоятельно определиться что важней при одновременном появлении нескольких запросов, если предвидится использование различных источников/получателей.

2. Направление передачи данных. Кто у нас будет отправителем данных, периферия или память.

3. Использование циклического режима. В этом режиме, как только счетчик DMA_CNTDRx обнулится (произошло N пересылок данных, как мы и задали в этом счетчике), он снова автоматически перезагрузится числом N, и все пойдет сначала. Опять с тех же начальных адресов памяти и периферии, которые мы задали. То есть предыдущие значения массива данных получателя начнут безжалостно затираться.

4. Размерность данных периферии/памяти. Задаются отдельно, и могут быть разными (8, 16, 32 бита). Если размерность данных задана разная для отправителя и получателя, контроллер DMA при операциях пересылки выполняет выравнивание данных.

5. Режима инкремента адресов периферии, памяти. Базовые (начальные адреса) мы уже задали через регистры DMA_CPARx и DMA_CMARx. Эти значения остаются неизменными при всей последовательности транзакций. А вот текущие адреса, по которым будет происходить чтение/запись после окончания каждой пересылки и перед началом следующей можно инкрементировать. Величина инкремента адреса вычисляется автоматически, в зависимости от того, какую размерность данных мы установили для источника/получателя.

6. Использование режима “Память – Память”. В этом режиме для пересылки данных не нужен запрос от периферии, для этого достаточно установить бит MEM2MEM в регистре DMA_CCRx (где x = 1..7 – номер канала). Этот режим не может быть одновременно использован с циклическим режимом.

7. Разрешение прерываний

Все эти настройки производятся через один регистр – DMA_CCRx (x – номер канала). И, напоследок, после всех настроек, канал DMA можно активировать установкой бита EN в том же регистре.

Есть одна особенность. Шина AHB может работать только с 32-разрядными данными. Поэтому при передаче 8 или 16-разрядных данных к устройствам шины AHB, эти значения дублируются в неиспользуемых разрядах. Например, если мы хотим передать значение 0xAB, контроллер DMA выставит на шину значение 0xABABABAB. Или же, при передаче значения 0xABCD, будет передано 0xABCDABCD. Подробней об этом можно посмотреть Reference Manual (RM0038)  в разделе “DMA controller”. Там же есть таблица, в которой собраны все возможные варианты разрядности данных источника и получателя, здесь же показано какой порядок следования байт (big-endian или little-endian) будет при пересылке данных.