Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
Современные 32-разрядные
ARM-микроконтроллеры серии STM32:
прямой доступ к памяти
Олег Вальпа (г. Миасс, Челябинская обл.)
занием количества байтов этого буфе-
В статье приведено описание блока прямого доступа к памяти ра для передачи в регистр последова-
32-разрядных ARM-микроконтроллеров серии STM32 от компании тельного порта по мере его готовности.
STMicroelectronics. Рассмотрена архитектура и состав его регистров, После передачи всех данных из буфера,
а также приведены практические примеры программ. DMA с помощью флага сообщит об этом
процессору. Таким образом, процеду-
ра обслуживания запроса от компью-
Введение Во многих программах процессор тера по последовательному порту будет
Многие микроконтроллеры име- часто бывает загружен операциями, выполнена блоком DMA, что защитит
ют встроенный блок прямого доступа требующими непрерывной передачи процессор от перегрузки.
к памяти (ПДП), именуемый в англоя- данных. Это и опрос состояния датчи-
зычной литературе как Direct Memory ков, и регулярные расчёты. Примером Функциональное
Access (DMA). Блок DMA позволяет обе- таких процедур могут служить: вывод описание DMA
спечить высокоскоростную передачу информации на графический индика- Микроконтроллеры серии STM32 [1]
данных между внешними устройствами тор, опрос клавиатуры, чтение данных также имеют DMA. Причём более насы-
и памятью микроконтроллера, а также с карты памяти и тому подобное. Если щенные модели имеют два независи-
передачу данных типа память-память в это время ещё потребуется обслужи- мых блока DMA: DMA1 и DMA2, каждый
без участия процессора. Это позволя- вать запрос от компьютера по после- из которых имеет несколько независи-
ет освободить процессор от рутинной довательному порту, то процессор мых каналов. Блок DMA1 содержит 7
операции по пересылке данных, уско- может начать притормаживать выпол- каналов, а DMA2 – 5. Структурная схе-
рить данную процедуру за счёт прямой нение некоторых операций. В подоб- ма DMA приведена на рисунке.
пересылки данных и выполнять раз- ных случаях DMA может помочь про- Блок DMA STM32 может быть исполь-
личные операции в микроконтролле- цессору. Для этого достаточно будет зован такими основными периферий-
ре одновременно и независимо самим сформировать задание блоку DMA ными устройствами микроконтролле-
процессором и блоком DMA. в виде начала буфера в памяти с ука- ра STM32, как SPI, ЦАП, I2C, USART, тай-
меры и АЦП.
К каждому каналу можно подклю-
ICode чить одно из периферийных устройств,
FLITF Flash
Ядро DCode закреплённых за этим каналом. Напри-
АRM-микроконтроллера мер, регистр передачи данных модуля
Cortex-M3
Sys tem USART1 можно подключить к каналу 4,
SRAM а регистр приёма данных – к каналу 5.
Матрица шин
оритетов, запросы регулируются аппа- нам периферии APB1, APB2 и AHB, вину пропускной способности систем-
ратно. Запрос с номером 1 имеет прио- как к источнику и как к приёмнику ной шины для процессора при одно-
ритет над запросом 2, и так далее. данных. временном обращении как к памяти,
Блок DMA обеспечивает независимые Программируемый размер данных так и к периферии.
размерности данных для обмена между для обмена может достигать значения
источником и адресатом в виде байта, 65536. Описание регистров DMA
полуслова и 32-разрядного слова. Под- Если блок DMA и процессор микро- Для настройки контроллера DMA
держивается режим эмуляции упаков- контроллера обращаются к одному предусмотрено две категории реги-
ки и распаковки данных. Адреса источ- и тому же устройству, то время обра- стров:
ника и приёмника обмена могут быть щения между ними будет распре- ●● регистры настройки и управления
DMA поддерживает три флага собы- на несколько рабочих тактов, а затем каждого канала.
тий: половина обмена DMA, заверше- освобождает её. Для настройки и управления DMA
ние обмена DMA и ошибка обмена Блок DMA выполняет прямой обмен в целом предназначены регистры:
DMA. Эти флаги логически объединя- с памятью, разделяя системную шину ●● DMA_ISR – регистр флагов прерыва-
ются с помощью функции «ИЛИ» в еди- с ядром микроконтроллера. DMA- ния от каналов;
ный запрос на прерывание для каждо- запрос может приостановить доступ ●● DMA_IFCR – регистр очистки флагов
Flash, SRAM, памяти периферии, ши- гарантирует, по крайней мере, поло- необходимых для передачи байт;
HTIF6
HTIF5
HTIF4
HTIF3
HTIF2
HTIF1
TCIF7
TCIF6
TCIF5
TCIF4
TCIF3
TCIF2
TCIF1
TEIF7
TEIF6
TEIF5
TEIF4
TEIF3
TEIF2
TEIF1
GIF7
GIF6
GIF5
GIF4
GIF3
GIF2
GIF1
0x000 DMA_ISR
Резерв
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
CHTIF7
CHTIF6
CHTIF5
CHTIF4
CHTIF3
CHTIF2
CHTIF1
CTCIF7
CTCIF6
CTCIF5
CTCIF4
CTCIF3
CTCIF2
CTCIF1
CTEIF7
CTEIF6
CTEIF5
CTEIF4
CTEIF3
CTEIF2
CTEIF1
CGIF7
CGIF6
CGIF5
CGIF4
CGIF3
CGIF2
CGIF1
0x004 DMA_IFCR
Резерв
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
M SIZE [1:0]
MEM2MEM
PSIZE [1:0]
PL[1:0]
MINC
PINC
CIRC
HTIE
TCIE
TEIE
DIR
0х008 DMA_CCR1
EN
Резерв
Исх. значение 0 0 0 0 0 00 0 0 0 0 0 0 0 0
0x00C DMA_CNDTR1 NDT[15:0]
Резерв
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x010 DMA_CPAR1 PA[31:0]
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x014 DMA_CMAR1 MA[31:0]
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x018 Резерв
M SIZE [1:0]
MEM2MEM
PSIZE [1:0]
PL[1:0]
MINC
PINC
CIRC
HTIE
TCIE
TEIE
DIR
0x01C DMA_CCR2
EN
Резерв
Исх. значение 0 0 0 0 0 00 0 0 0 0 0 0 0 0
0x020 DMA_CNDTR2 NDT[15:0]
Резерв
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x024 DMA_CPAR2 PA[31:0]
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x028 DMA_CMAR2 MA[31:0]
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x02C Резерв
… …
M SIZE [1:0]
MEM2MEM
PSIZE [1:0]
PL[1:0]
MINC
PINC
CIRC
HTIE
TCIE
TEIE
DIR
0x080 DMA_CCR7
EN
Резерв
Исх. значение 0 0 0 0 0 00 0 0 0 0 0 0 0 0
0x084 DMA_CNDTR7 NDT[15:0]
Резерв
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x088 DMA_CPAR7 PA[31:0]
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x08C DMA_CMAR7 MA[31:0]
Исх. значение 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x090 Резерв
●● DMA_CPAR – содержит указатель на (пер. с англ. – очистить). Установка решён, этот регистр можно будет толь-
периферийное устройство, которое и обнуление этих флагов производит- ко читать, чтобы определить число
подключено к каналу; ся программно. байт, оставшееся для обмена. Данный
●● DMA_CMAR – содержит указатель Регистры DMA_CCRx нужны для кон- регистр декрементируется после каж-
области памяти, в которой будут фигурации соответствующего канала x: дой DMA-транзакции.
записаны или прочитаны данные. ●● биты 31…15 в нём зарезервированы Как только обмен завершён, этот
Карта размещения регистров DMA и всегда читаются как «0»; регистр может либо остаться обну-
в пространстве памяти представлена ●● бит 14 MEM2MEM позволяет запре- лённым, либо автоматически переза-
в таблице 1. В ней также показано зна- тить или разрешить режим работы грузиться ранее запрограммирован-
чение регистров после сброса. «память-память» для DMA; ным значением, если канал сконфи-
Каждый блок DMA включает в свой ●● биты 13…12 PL[1:0] определяют уро- гурирован в режиме автоматической
состав несколько групп регистров вень приоритета канала и могут при- перезагрузки, то есть цикличности.
в соответствии с количеством обслужи- нимать следующие значения: Если значение этого регистра равно
ваемых им каналов. На карте показаны −− 00 – низкий приоритет, нулю, никакая транзакция не может
группы регистров для каналов 1, 2 и 7. −− 01 – средний приоритет, быть обслужена, причём независимо
Регистры для остальных каналов имеют −− 10 – высокий приоритет, от того, разрешён канал или нет.
аналогичную структуру и одноимённые −− 11 – очень высокий приоритет; Регистр DMA_CPARx позволяет задать
названия, отличающиеся лишь номе- ●● биты 11…10 MSIZE[1:0] задают размер адрес периферии для канала x DMA.
ром канала и смещением относитель- данных в памяти и могут принимать В этот регистр нельзя производить
но базового адреса. значения: запись, когда канал разрешён. Значе-
Рассмотрим подробнее назначе- −− 00 – 8 бит, ние его бит:
ние всех разрядов этих регистров. −− 01 – 16 бит, ●● биты 31…0 PA[31:0] задают базовый
чены для обнуления описанных выше данных обмена в байтах от 0 до 65535. DMA-транзакции
разрядов регистра DMA_ISR и имеют В этот регистр можно произво- и особенности работы
соответствующие им названия с добав- дить запись только тогда, когда канал После возникновения запланиро-
лением префикса «С» от слова Clear выключен. Как только канал будет раз- ванного события, периферия посыла-
ет сигнал запроса для DMA. Блок DMA го размера элемента данных. Первый
обслуживает этот запрос в зависимо- адрес обмена – это тот адрес, который
сти от приоритета канала. Как только запрограммирован в регистрах DMA_
DMA получает доступ к периферии, он CPARx и DMA_CMARx. Во время опера-
посылает ей сигнал уведомления. Внеш- ций обмена эти регистры сохраняют
нее устройство снимает свой запрос первоначально запрограммированное
после получения сигнала уведомле- значение. Текущие адреса обмена, хра-
ния от DMA. Как только снимается сиг- нимые во внутреннем регистре текуще-
нал запроса от периферии, DMA, в свою го адреса периферии или памяти, недо-
очередь, снимает свой сигнал уведом- ступны программе.
ления. Если появятся новые запросы, Если канал сконфигурирован в не-
периферия может инициализировать циклическом режиме, то после послед-
следующую транзакцию. ней транзакции DMA-запрос не обслу-
В итоге каждый DMA-обмен состоит живается, поскольку число элемен-
из трёх операций: тов данных, которые нужно переда-
1. Загрузка данных из регистров дан- вать, достигло нуля. Чтобы загрузить
ных периферии или из области памяти, в регистр DMA_CNDTRx новое число
производимая с помощью внутреннего элементов данных, которые надо пере-
регистра текущего адреса периферии давать, DMA-канал должен быть забло-
или памяти. Стартовый адрес, который кирован.
используется для первого обмена, явля- Если DMA-канал блокируется, то
ется базовым адресом периферии или DMA-регистр не сбрасывается. Реги-
памяти, и записывается в регистр DMA_ стры DMA-каналов (DMA_CCRx, DMA_
CMARx или DMA_CPARx. CPARx и DMA_CMARx) сохраняют
2. Сохранение данных путём за- начальные значения, запрограммиро-
грузки в регистры периферии или ванные на этапе конфигурации канала.
в область памяти, адресуя их через В циклическом режиме, после
внутренний регистр текущего адреса последней транзакции, регистр DMA_
периферии или памяти. Стартовый CNDTRx автоматически перезагружа-
адрес, который используется для пер- ется первоначально запрограммиро-
вого обмена, является базовым адре- ванным значением. Внутренние реги-
сом периферии или памяти, и про- стры текущего адреса периферии
граммируется в регистре DMA_CMARx или памяти перезагружаются значе-
или DMA_CPARx. ниями из регистров базового адреса
3. Пост-декремент регистра DMA_ DMA_CPARx или DMA_CMARx соответ-
CNDTRx, который содержит число ственно.
транзакций, которые ещё необходи-
мо выполнить. Конфигурация каналов
Каждый канал может обработать Чтобы сконфигурировать DMA-ка-
DMA-обмен между регистром перифе- нал, необходимо выполнить следую-
рии, имеющим фиксированный адрес, щую последовательность:
и адресом в памяти. Количество дан- ●● задать адрес регистра периферии
Как только будет передана поло- Режим «память–память» щего канала DMA_CCRx. Выставляет-
вина байтов, будет установлен флаг Каналы DMA могут также рабо- ся флаг запроса прерывания от ошиб-
HTIF и сгенерировано прерывание, тать без запроса от периферии. Такой ки обмена в регистре DMA_IFR канала
если такое прерывание разрешено режим называют «память–память». TEIF и генерируется прерывание, если
битом HTIE. В конце обмена будет Если установлен «1» бит MEM2MEM оно разрешено битом TEIE в регистре
установлен флаг его завершения в регистре DMA_CCRx, то канал ини- DMA_CCRx.
TCIF и сгенерировано прерывание, циализирует обмен сразу, как только
если такое прерывание разрешено он программно разрешается битом Прерывания
битом TCIE. EN в регистре DMA_CCRx. Обмен оста- Запрос на прерывание может гене-
навливается в тот момент, когда значе- рироваться событиями «завершение
Режим цикличности ние в регистре DMA_CNDTRx достигает половины обмена», «завершение пол-
Режим цикличности использует- нуля. Режим «память–память» не может ного обмена» или «ошибка обмена»
ся для управления непрерывным использоваться одновременно с режи- в каждом DMA-канале. Для удобства
потоком данных с помощью кольце- мом цикличности. обработки доступны отдельные биты
вых буферов, например, от АЦП в ре- разрешения прерываний, представлен-
жиме сканирования. Эта особенность Обработка ошибок ные в таблице 2.
может быть разрешена битом CIRC Генерация ошибки обмена по
в регистре DMA_CCRx. Когда режим DMA может возникнуть при опера- Карта запросов DMA
цикличности активизирован, то зна- ции чтения или записи в зарезер- Сводная таблица запросов на обслу-
чение числа данных, которые будут вированном адресном простран- живание для DMA1 и DMA2 приведена
переданы за один цикл, автомати- стве. Если происходит ошибка обме- соответственно в таблицах 3 и 4. Для
чески перезагружается начальным на по DMA во время доступа на каждого канала существует несколь-
значением, запрограммированным чтение или запись, то канал автома- ко источников запроса, которые объ-
на этапе конфигурации канала, тически отключается посредством ап- единяются с помощью логической
и DMA-запросы продолжают обслу- паратного сброса бита EN в реги- операции «ИЛИ». Любой из каналов
живаться. стре конфигурации соответствую- может быть разрешён или запрещён
программно. Высшей приоритетно-
Таблица 2. Запросы прерываний от DMA стью обслуживания обладает первый
канал.
Бит управления
Событие прерывания Флаг события
разрешением
Завершение половины обмена HTIF HTIE Программирование DMA
Для использования блока DMA
Завершение полного обмена TCIF TCIE
в программе необходимо выпол-
Ошибка обмена TEIF TEIE
нить его инициализацию и настрой-
ку параметров. Рассмотрим эти опе-
Таблица 3. Сводная таблица запросов для DMA1 рации на примере подключения пере-
Периферия Канал 1 Канал 2 Канал 3 Канал 4 Канал 5 Канал 6 Канал 7
датчика последовательного порта
ADC1 ADC1 USART1_TX к каналу 4 DMA1 для пере-
SPI/I2S SPI1_RX SPI1_TX SPI/I2S2_RX SPI/I2S2_TX дачи 64 байт. Начнём с настройки
USART USART3_TX USART3_RX USART1_TX USART1_RX USART2_RX USART2_TX адреса источника и приёмника дан-
I2C I2C2_TX I2C2_RX I2C1_TX I2C1_RX ных канала DMA.
TIM1_CH4 Инициализация контроллера DMA,
TIM1 TIM1_CH1 TIM1_CH2 TIM1_TRIG TIM1_UP TIM1_CH3 так же как и любого периферийного
TIM1_COM
устройства, начинается с подачи на
TIM2_CH2
TIM2 TIM2_CH3 TIM2_UP TIM2_CH1 него тактовых импульсов. Делается это
TIM2_CH4
TIM3_CH4 TIM3_CH1 с помощью операции:
TIM3 TIM3_CH3
TIM3_UP TIM3_TRIG
TIM4 TIM4_CH1 TIM4_CH2 TIM4_CH3 TIM4_UP if ((RCC->AHBENR & RCC_AHBENR_
DMA1EN) != RCC_AHBENR_DMA1EN)
Таблица 4. Сводная таблица запросов для DMA2 RCC->AHBENR |=RCC_AHBENR_DMA1EN;
Листинг 1
unsigned char BuffTxd[32]; // Инициализация буфера передатчика
// Функция инициализации DMA1 для передачи в порт USART1
void USART1_TX_DMA1_Init (void)
{
// Включить тактирование DMA1
if ((RCC->AHBENR & RCC_AHBENR_DMA1EN) != RCC_AHBENR_DMA1EN)
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// Задать адрес источника и приемника и количество данных для обмена
DMA1_Channel4->CPAR = (uint32_t)&USART1->DR; // Задать адрес реги-
стра периферии
DMA1_Channel4->CMAR = (uint32_t)&BuffTxd[0]; // Задать адрес буфера
в памяти
DMA1_Channel4->CNDTR = 32; // Задать количество данных для обмена
// Настройка конфигурации
DMA1_Channel4->CCR = 0; // Обнуление регистра конфигурации
DMA1_Channel4->CCR &= ~DMA_CCR4_CIRC; // Отключить циклический режим
DMA1_Channel4->CCR |= DMA_CCR4_DIR; // Задать направление чтения из
памяти
// Настроить работу с периферийным устройством
DMA1_Channel4->CCR &= ~DMA_CCR4_PSIZE; // Задать размерность данных
8 бит
DMA1_Channel4->CCR &= ~DMA_CCR4_PINC; // Запретить инкремент указателя
// Настроить работу с памятью
DMA1_Channel4->CCR &= ~DMA_CCR4_MSIZE; // Задать размерность данных
8 бит
DMA1_Channel4->CCR |= DMA_CCR4_MINC; // Включить инкремент указателя
USART1->CR3 |= USART_CR3_DMAT; // Разрешить передачу USART1 через DMA
}
●●задание уровня приоритета канала; тически начнёт новый цикл. Для это-
Листинг 2 ●●разрешение при необходимости пре- го необходимо выполнить следующие
unsigned char BuffTxd[32]; // рываний. операции:
Инициализация буфера передатчика Данные настройки выполняются
void main() с помощью битов регистра управления DMA1_Channel4->CCR |= DMA_CCR4_
{ канала CCR, описанных ранее. Запись CIRC; // Включить циклический
// Загрузка буфера данных в управляющий регистр мож- режим
BuffTxd[0] = ‘Д’; но выполнять побитно или в один при- DMA1_Channel4->CCR |= DMA_CCR4_
BuffTxd[1] = ‘о’; ём 32-разрядным словом. Для нагляд- DIR; // Задать направление пере-
BuffTxd[2] = ‘б’; ности рассмотрим пример побитного дачи данных из памяти
BuffTxd[3] = ‘р’; занесения данных. DMA1_Channel4->CCR |= DMA_CCR4_
BuffTxd[4] = ‘ы’; Вначале выполним предварительную EN; // Разрешить работу канала
BuffTxd[5] = ‘й’; очистку управляющего регистра:
BuffTxd[6] = ‘ ’; Кроме этого необходимо разрешить
BuffTxd[7] = ‘д’; DMA1_Channel4->CCR=0; // Очистка работу периферии через DMA, восполь-
BuffTxd[8] = ‘е’; регистра конфигурации четвертого зовавшись описанием периферийного
BuffTxd[9] = ‘н’; канала устройства, которое нужно подключить
BuffTxd[10] = ‘ь’; к DMA. В нашем случае для подключе-
BuffTxd[11] = ‘!’; Далее зададим размер элемента дан- ния USART1 используем следующий
USART1_TX_DMA1_Init(); // Иници- ных размером 8 бит путём обнуления код:
ализация режима DMA1 для USART1 соответствующего поля:
StartDMAChannel4(12); // Пуск USART1->CR3 |= USART_CR3_DMAT;
передачи DMA1_Channel4->CCR &= ~DMA_CCR4_ // Разрешить передачу USART1 че-
while(GetStateDMAChannel4()==0) MSIZE; // 8 бит рез DMA
{}; // Ждать окончания передачи
StartDMAChannel4(12); // Повтор- Для задания другого размера можно Узнать об окончании процедуры
ный пуск передачи использовать следующие операции: обмена через DMA помогут следую-
while(GetStateDMAChannel4()==0) щие флаги в регистре ISR: TEIF – ошиб-
{}; // Ждать окончания передачи DMA1_Channel4->CCR |= DMA_CCR4_ ка обмена в канале, HTIF – передана
} MSIZE_0; // 16 бит половина буфера, TСIF – передан весь
DMA1_Channel4->CCR |= DMA_CCR4_ буфер и GIF – общий флаг прерыва-
MSIZE_1; // 32 бита ния в канале, который устанавливает-
Данную процедуру можно разделить ся, если установлен любой из флагов
на три части: Аналогично задаём размер элемента TEIF, HTIF или TCIF.
●● настройка режима связи с перифе- данных для периферии: Для проверки соответствующего фла-
рийным устройством; га канала 4 необходимо выполнить сле-
●● настройка режима связи с памятью; DMA1_Channel4->CCR &= ~DMA_CCR4_ дующие процедуры:
●● настройка канала в целом. PSIZE; // 8 бит
Настройка режима связи с перифе- if (DMA1->ISR & DMA_ISR_TEIF4)
рийным устройством подобна настрой- Для передачи всего массива данных {} // Проверить флаг TEIF ошибки
ке режима связи с памятью. Необходи- из буфера активируем режим инкре- обмена
мо задать размерность данных и акти- мента указателя в памяти: if (DMA1->ISR & DMA_ISR_HTIF4)
вировать инкремент указателя. {} // Проверить флаг HTIF пере-
Размерность данных может состав- DMA1_Channel4->CCR |= DMA_CCR4_ дачи половины буфера
лять 8, 16 или 32 бита. В рассматрива- PINC; // Инкремент указателя if (DMA1->ISR & DMA_ISR_TCIF4)
емом примере данные будут переме- {} // Проверить флаг TCIF окон-
щаться из буфера памяти в регистр дан- Запретим инкремент указателя для чания обмена
ных USART1_TX. Для этого необходимо периферии:
будет поместить в один и тот же регистр Для обнуления установленного фла-
данных USART1_TX первый байт из DMA1_Channel4->CCR &= ~DMA_CCR4_ га канала 4 существует регистр IFCR.
буфера, затем второй и так далее до PINC; Очистка соответствующего флага
конца буфера. Значит, инкремента- выполняется так:
ция указателя на память необходима, В обычном режиме DMA останав-
а инкрементация указателя на перифе- ливается после выполнения одного DMA1->IFCR |= DMA_ISR_TEIF4; //
рийное устройство не требуется. цикла обмена. Чтобы инициировать Очистить флаг ошибки обмена TEIF
Настройки канала в целом включа- следующий цикл обмена, необходи- DMA1->IFCR |= DMA_ISR_HTIF4; //
ют в себя: мо выполнить следующие действия: Очистить флаг передачи половины
●● задание режима цикличности в виде отключить канал DMA, перезагрузить буфера HTIF
однократного или циклического регистр CNDTR, вновь включить канал DMA1->IFCR |= DMA_ISR_TCIF4; //
обмена; DMA. Но можно изначально задать Очистить флаг окончания обмена
●● задание направления чтения из памя- режим циклического обмена. Тогда TCIF
ти или периферии; по окончании передачи DMA автома-
Примеры программ
В листинге 1 приведён пример про- Листинг 3
граммного кода набора функций uint16_t Buffer[10] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
настройки DMA для работы с USART1_ 0x38, 0x39, 0x3A};
TX, созданных на основе изложенно- // Обработчик прерывания DMA1
го материала. void DMA1_Channel6_IRQHandler(void)
Приведённые функции используем {
в программе, которая позволит пере- DMA_ClearITPendingBit(DMA1_IT_TC6);
дать содержимое буфера в порт USART1 DMA_Cmd(DMA1_Channel6, DISABLE);
через DMA без участия процессора. }
Пример такой программы приведён // Функция инициализации DMA1 для USART2
в листинге 2. В качестве данных буфера void init_DMA1_USART2()
будет загружена фраза «Добрый день!». {
Естественно, перед использованием RCC->APB2ENR |= RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN;
программы необходимо будет выпол- RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
нить инициализацию USART1. AFIO->MAPR |= AFIO_MAPR_USART2_REMAP;
Данная программа обладает опре- GPIOD->CRL &= !GPIO_CRL_CNF5;
делённым недостатком, связанным GPIOD->CRL |= GPIO_CRL_CNF5_1 | GPIO_CRL_MODE5_0 | GPIO_CRL_CNF6_0;
с необходимостью проверять флаг USART2->BRR = USART_BRR;
окончания передачи. Избавиться от USART2->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
этого недостатка поможет использо- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
вание прерываний от канала DMA. DMA_InitTypeDef DMA_InitStruct;
В качестве нового примера исполь- DMA_StructInit(&DMA_InitStruct);
зования прерываний от DMA рас- DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
смотрим программу, приведённую DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t) &(USART2->DR);
в листинге 3. DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t) Buffer;
В этой программе формируется DMA_InitStruct.DMA_BufferSize = 10;
буфер данных для передачи в порт DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
USART2 и производится инициали- DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
зация канала 6 DMA1 с разрешением DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
прерываний. По окончании переда- DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
чи произойдёт прерывание, которое DMA_Init(DMA1_Channel6, &DMA_InitStruct);
вызовет обработчик DMA1_Channel6_ USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
IRQHandler. В этом обработчике обну- DMA_Cmd(DMA1_Channel6, ENABLE);
ляется бит прерывания и отключается DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
6-й канал DMA1. NVIC_EnableIRQ(DMA1_Channel6_IRQn);
Подробнее познакомиться с блоком }
DMA поможет первоисточник [2]. // Главный модуль программы
void main()
Литература {
1. www.st.com. init_DMA1_USART2();
2. w w w . s t . c o m / w e b / e n / r e s o u r c e / t e c h - while(1);
nical/document/reference_manual/ }
CD00246267.pdf.