Dma stm32 cmsis настройка и использование

0
8

Dma stm32 cmsis

Для быстрого обмена данными между периферией и памятью без участия ядра активируйте нужный канал через регистр CCR. Укажите направление передачи, размер данных и режим приоритета. Например, для USART1 в режиме приема настройте DMA1_Channel5:

DMA1_Channel5->CCR |= DMA_CCR_DIR; – чтение из периферии.

DMA1_Channel5->CCR |= DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0; – размер слова 8 бит.

DMA1_Channel5->CCR |= DMA_CCR_PL_1; – высокий приоритет.

Перед запуском задайте адреса источника и приемника:

DMA1_Channel5->CPAR = (uint32_t)&USART1->DR;

DMA1_Channel5->CMAR = (uint32_t)buffer;

Количество передач указывается в CNDTR. Для 64 байт:

DMA1_Channel5->CNDTR = 64;

Разрешите прерывания по завершению или ошибке через CCR и активируйте канал:

DMA1_Channel5->CCR |= DMA_CCR_TCIE | DMA_CCR_EN;

Обработчик прерывания очищает флаг в ISR и выполняет необходимые действия с данными.

Работа с прямым доступом к памяти в микроконтроллерах ST

Инициализация периферии

Для активации модуля включите тактирование через регистр RCC->AHBENR. Например, для DMA1 на STM32F103 установите бит DMA1EN:

RCC->AHBENR |= RCC_AHBENR_DMA1EN;

Конфигурация канала передачи

Задайте параметры в структуре DMA_Channel_TypeDef:

DMA1_Channel1->CCR =
DMA_CCR_MINC |          // Инкремент адреса памяти
DMA_CCR_DIR |           // Направление: из памяти в периферию
DMA_CCR_TCIE;           // Прерывание по завершении
DMA1_Channel1->CNDTR = 128; // Количество передаваемых элементов
DMA1_Channel1->CPAR = (uint32_t)&USART1->DR; // Адрес периферии
DMA1_Channel1->CMAR = (uint32_t)buffer;      // Адрес буфера

Приоритет устанавливается битами PL[1:0] в регистре CCR. Для максимальной скорости передачи выберите значение 0b11.

Для старта передачи активируйте канал:

DMA1_Channel1->CCR |= DMA_CCR_EN;

Передача информации между памятью и модулями через прямой доступ

Активация канала

Включите нужный канал, установив бит EN в регистре CCRx (DMA_CCR). Например, для канала 1:

DMA1_Channel1->CCR |= DMA_CCR_EN;

Перед этим убедитесь, что остальные параметры (направление, приоритет, размер данных) заданы.

Конфигурация регистров

Укажите адреса источника и приемника в PAR (DMA_CPAR) и MAR (DMA_CMAR). Для отправки из массива в USART:


DMA1_Channel4->CPAR = (uint32_t)&USART1->DR;
DMA1_Channel4->CMAR = (uint32_t)buffer;

Задайте количество элементов в CNDTR (DMA_CNDTR):

DMA1_Channel4->CNDTR = sizeof(buffer);

Выберите режим: циклический (DMA_CCR_CIRC) или однократный. Для непрерывной работы:

DMA1_Channel4->CCR |= DMA_CCR_CIRC;

Разрешите прерывания, если требуется обработка завершения или ошибок. Установите биты TCIF и TEIF в регистре ISR (DMA_ISR), затем активируйте их в CCR (DMA_CCR_TCIE, DMA_CCR_TEIE).

Работа с прерываниями при передаче данных через контроллер

Для обработки событий завершения передачи или ошибок активируйте соответствующие биты в регистре CR канала. Например, для включения прерывания по завершению установите флаг TCIE, а для ошибок – TEIE.

Перед запуском канала убедитесь, что обработчик зарегистрирован в таблице векторов. В Cortex-M это делается через NVIC_EnableIRQ(). Пример для канала 1:

NVIC_SetPriority(DMA1_Channel1_IRQn, 0);
NVIC_EnableIRQ(DMA1_Channel1_IRQn);

В обработчике проверяйте флаги статуса в регистре ISR. Для канала 1 биты TCIF1 (завершение) и TEIF1 (ошибка) очищаются записью 1 в соответствующие позиции IFCR.

Пример кода обработчика:

void DMA1_Channel1_IRQHandler(void) {
if (DMA1->ISR & DMA_ISR_TCIF1) {
// Действия при успешной передаче
DMA1->IFCR |= DMA_IFCR_CTCIF1;
}
if (DMA1->ISR & DMA_ISR_TEIF1) {
// Реакция на ошибку
DMA1->IFCR |= DMA_IFCR_CTEIF1;
}
}

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

При работе с кольцевым буфером проверяйте флаг HTIF (половина передачи) для двойной буферизации. Это позволяет обрабатывать данные параллельно с заполнением следующей части буфера.