Программирование STM32. Часть 12: Прерывания DMA

Итак, мы рассмотрели обмен с периферийными устройствами посредством DMA на примере передачи данных из памяти в интерфейс SPI и обратно, а так же с помощью DMA копировали один массив данных в другой. В этой части мы рассмотрим прерывания, которые может генерировать контроллер DMA. Предыдущая статья здесь, все статьи цикла можно посмотреть тут: http://dimoon.ru/category/obuchalka/stm32f1.

Прерывания DMA

В stm32f103c8 каждый канал DMA может генерировать 3 типа прерываний:

  1. Передача данных завершена
  2. Завершена передача половины данных
  3. Ошибка передачи данных (возникает при обращении к зарезервированной области данных)

Для каждого канала нужные прерывания можно включить индивидуально в регистре конфигурации канала DMA_CCRx. За это отвечают биты TCIE (завершение передачи), HTIE ( передана половина буфера) и TEIE (ошибка передачи):

DMA channel x configuration register (DMA_CCRx)

 

Кроме того, есть еще 2 специальных регистра, один из которых содержит информацию об активных флагах прерываний всех каналов DMA (регистр DMA_ISR), а с помощью другого можно сбросить нужные флаги прерываний выбранных каналов (регистр DMA_IFCR):

Регистр статуса прерываний DMA_ISR

DMA interrupt flag clear register (DMA_IFCR)

Регистр сброса флагов прерываний DMA_IFCR

Более подробное описание всех регистров DMA можно посмотреть тут.

 

Использование прерываний DMA

Переходим к практике. В качестве основы возьмем код из статьи Программирование STM32. Часть 10: SPI + DMA, где мы через DMA отправляли массив данных в SPI. Инициализация SPI производится точно так же, только добавим в конец 3 строчки:

С помощью строки

мы на всякий случай сбрасываем флаг прерывания о завершении передачи данных. Затем в контроллере прерываний разрешаем прерывание от 3-го канала DMA:

Далее, рассмотрим функцию отправки данных в SPI через DMA:

Здесь мы добавили строчку

с помощью которой включаем прерывание в 3-м канале DMA после завершения передачи.

Остался обработчик прерывания. Он будет выглядеть вот так:

Обращаю внимание на DMA1->IFCR = 1<<DMA_IFCR_CTCIF3_Pos. С помощью этой строки мы сбрасываем флаг прерывания о завершении передачи данных в 3-м канале DMA. Без этой строки прерывание DMA1_Channel3_IRQHandler() будет вызываться бесконечное число раз, что застопорит выполнение основной программы МК.

Для проверки вот такой main():

На этом пока все, спасибо за внимание!!! 😉

Продолжение

Метки: , , , . Закладка Постоянная ссылка.

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *