Программирование STM32. Часть 9: Описание регистров DMA

Так как предыдущая статья про DMA оказалась довольно большой, то описание регистров я решил вынести отдельной частью. Предыдущая статья здесь, все статьи цикла можно посмотреть тут: https://dimoon.ru/category/obuchalka/stm32f1.

В микроконтроллере STM32F103C8 контроллер DMA имеет 6 типов регистров. Организованы они следующим образом.

Регистры, которые являются общими для всех каналов DMA:

  • DMA_ISR — регистр статуса прерываний
  • DMA_IFCR — регистр очистки флагов прерываний

Регистры, которые являются индивидуальными для каждого канала DMA:

  • DMA_CCRx (x=1..7) — регистр конфигурации канала номер x DMA
  • DMA_CNDTRx (x=1..7) — регистр количества передаваемых данных канала номер x DMA
  • DMA_CPARx (x=1..7) — регистр адреса периферии канала номер x DMA
  • DMA_CMARx (x=1..7) — регистр адреса памяти канала номер x DMA

Количество каналов у нас 7. Тогда общее число регистров DMA1 у нас будет 7*4 + 2 = 30 штук.

Регистры DMA

DMA interrupt status register (DMA_ISR) — регистр статуса прерываний от каналов DMA

DMA interrupt status register (DMA_ISR)

Содержит флаги прерываний от всех каналов DMA.

TEIFx: ошибка передачи канала DMA. Устанавливается аппаратно. Сбрасывается записью 1 в соответствующий бит регистра DMA_IFCR.

HTIFx: флаг передачи половины данных каналом DMA. Устанавливается аппаратно. Сбрасывается записью 1 в соответствующий бит регистра DMA_IFCR.

TCIFx: флаг конца передачи канала DMA. Устанавливается аппаратно. Сбрасывается записью 1 в соответствующий бит регистра DMA_IFCR.

GIFx: глобальный флаг прерывания канала DMA. Устанавливается в 1, когда произошло событие TEHT или TC данного канала. Устанавливается аппаратно. Сбрасывается записью 1 в соответствующий бит регистра DMA_IFCR.

 

DMA interrupt flag clear register (DMA_IFCR) — регистр очистки флагов прерываний каналов DMA

DMA interrupt flag clear register (DMA_IFCR)

Установка в единицу любого бита в регистре DMA_IFCR очищает флаг соответствующего прерывания в регистре DMA_ISR. Запись нуля в любой бит не оказывает ни какого эффекта.

CTEIFx: очистить флаг ошибки передачи канала DMA

CHTIFx: очистить флаг передачи половины данных

CTCIFx: очистить флаг завершения передачи

CGIFx: очистить глобальный флаг прерывания DMA

 

DMA channel x configuration register (DMA_CCRx) — регистр конфигурации канала номер x DMA

DMA channel x configuration register (DMA_CCRx)

MEM2MEM: режим «из памяти в память»

  • 0 — режим MEM2MEM отключен
  • 1 — режим MEM2MEM включен

PL[1:0]: уровень приоритета канала DMA

  • 00: Low (Низкий приоритет)
  • 01: Medium (Средний приоритет)
  • 10: High (Высокий приоритет)
  • 11: Very high (Очень высокий приоритет)

MSIZE[1:0]: разрядность данных в памяти

  • 00: 8 бит
  • 01: 16 бит
  • 10: 32 бита
  • 11: не используется

PSIZE[1:0]: разрядность периферии

  • 00: 8 бит
  • 01: 16 бит
  • 10: 32 бита
  • 11: не используется

MINC: режим инкремента памяти

  • 0 — режим инкремента памяти отключен
  • 1 — режим инкремента памяти включен

PINC: режим инкремента периферии

  • 0 — режим инкремента периферии отключен
  • 1 — режим инкремента периферии включен

CIRC: кольцевой режим DMA (Circular mode)

  • 0 — кольцевой режим отключен
  • 1 — кольцевой режим включен

DIR: направление передачи данных

  • 0 — чтение из периферии (направление из периферии в память)
  • 1 — чтение из памяти (направление из памяти в периферию)

TEIE: разрешить прерывание ошибки передачи DMA

  • 0 — прерывание запрещено
  • 1 — прерывание разрешено

HTIE: разрешить прерывание передачи половины буфера

  • 0 — прерывание запрещено
  • 1 — прерывание разрешено

TCIE: разрешить прерывание об окончании передачи

  • 0 — прерывание запрещено
  • 1 — прерывание разрешено

EN: включить канал DMA

  • 0 — канал отключен
  • 1 — канал включен

 

DMA channel x number of data register (DMA_CNDTRx) — количество данных для передачи

DMA channel x number of data register (DMA_CNDTRx)

NDT[15:0]: количество данных для передачи.

Количество данных для передачи может быть от 0 до 65535. Этот регистр может быть записан только если данный канал DMA отключен (EN=0 в регистре DMA_CCRx). Когда канал DMA включен, этот регистр является только для чтения (read-only) и показывает, сколько транзакций DMA еще осталось. Этот регистр уменьшается на единицу после каждой транзакции DMA. Как только передача завершена, этот регистр либо остается в нуле, либо автоматически перезагружается изначально записанным в него значением, если включен кольцевой режим. Если этот регистр равен нулю, ни одна транзакция DMA не может быть выполнена, вне зависимости от того, включен ли данный канал, или нет.

 

DMA channel x memory address register (DMA_CMARx) — регистр адреса памяти канала DMA

DMA channel x memory address register (DMA_CMARx)

Этот регистр не может быть записан, когда данный канал DMA включен

MA[31:0]: адрес памяти.

Базовый адрес (указатель) области памяти, которую необходимо записать/прочитать. Когда MSIZE=01 (разрядность памяти 16 бит) бит MA[0] игнорируется. Доступ автоматически выравнивается с адресом в пол-слова. Когда MSIZE=10 (разрядность памяти 32 бита), биты MA[1:0] игнорируются.  Доступ автоматически выравнивается с адресом в машинное слово.

Примечание. Получается, что при передаче массива данных по DMA по 16 или 32 бита, надо помнить, что элементы передаваемого массива в памяти должны быть выравнены по границе 16 или 32 бита соответственно. Если в коде на Си передаваемый массив объявлен как int16_t/uint16_t, и передача этого массива осуществляется по 16 бит, то проблем возникнуть не должно, так как компилятор по-умолчанию выравнивает данные массива по соответствующей границе (но это не точно). То же самое и для int32_t/uint32_t массивов и передачи данных по DMA по 32 бита. Так же проблем не должно быть при передаче массивов  int32_t/uint32_t по 16 бит за раз. А вот если мы объявили  int8_t/uint8_t, и хотим его передать куда-либо по 16 или 32 бита за раз, то в этом случае могут возникнуть проблемы. С регистрами периферийных устройств таких проблем нет, так как они все выравнены по границе 32 бита. 

 

DMA channel x peripheral address register (DMA_CPARx) — регистр адреса периферии канала DMA

DMA channel x peripheral address register (DMA_CPARx)

Этот регистр не может быть записан, когда данный канал DMA включен

PA[31:0]: адрес периферии

Базовый адрес (указатель) области памяти, которую необходимо записать/прочитать. Когда MSIZE=01 (разрядность памяти 16 бит) бит MA[0] игнорируется. Доступ автоматически выравнивается с адресом в пол-слова. Когда MSIZE=10 (разрядность памяти 32 бита), биты MA[1:0] игнорируются.  Доступ автоматически выравнивается с адресом в машинное слово.

См. Примечание к регистру DMA_CMARx

Заключение

На этом описание регистров завершено, в следующей части мы перейдем к практике и научимся быстро копировать данные из памяти одной области памяти в другую, а так же разберемся с обменом данными через интерфейс SPI посредством DMA.

Продолжение следует! Продолжение

 

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

3 комментария: Программирование STM32. Часть 9: Описание регистров DMA

  1. СКАЗОЧИК пишет:

    Заключение
    На этом описание регистров завершено, в следующей части мы перейдем к практике и научимся быстро копировать данные из памяти одной области памяти в другую, а так же раздеремся с обменом данными через интерфейс SPI посредством DMA.

    Ошибка (опечатка) в слове РАЗБЕРЕМСЯ. )

  2. СКАЗОЧНИК пишет:

    Материал хороший, хотелось бы дальше в том же духе. Про ШИМ. ДМА и ШИМ на таймерах общего назначения. И вообще конфигурации этих таймеров. И используя только CMSYS, без ХАЛ, ЛЛ и тем более СПЛ.

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