Использование DMA в микроконтроллерах Xmega

    Данная статья посвящена особенностям использования прямого доступа к памяти DMA в микропроцессорах Xmega.
    Прямой доступ к памяти (Direct Memory Access, DMA) — режим обмена данными между устройствами или же между устройством и основной памятью (RAM) без участия центрального процессора.
    Контроллер DMA (DMAC) в микропроцессорах Xmega является очень гибким четырехканальным контроллером, предназначенным для обмена данными между памятью и периферийными устройствами без вмешательства центрального процессора. Пока центральный процессор находится в спящем режиме или выполняет другие задачи, контроллер DMA берет на себя задачи по копированию данных из одной области в другую.
    Гибкий выбор приоритета канала, различные способы адресации, возможность двойной буферизации и большой объем делает контроллер DMA микропроцессора Xmega мощным инструментом для всех применений ориентированных на обмен данными, таких как обработка сигналов и промышленное управление.
    Пример использования DMA контроллера проиллюстрирован на следующем рисунке:
    Каналы DMA
    В дополнение к общим регистрам у контроллера DMA есть четыре независимых канала с отдельно устанавливаемыми регистрами управления и состояния. Каждый канал имеет необходимую информацию по управлению и состоянию для одиночного DMA обмена: источник, адреса получателя, количество байтов и состояние. После завершения обмена, канал можно отключить, перенастроить для другого обмена или запустить на повторение предыдущей передачи.
    Передача данных
    Понятие передачи данных в таком контексте подразумевает операцию, когда контроллер DMA копирует один, два четыре или восемь байтов от источника в заданное место в одной пакетной передаче.
    Когда канал DMA настроен на передачу двух, четырех или восьми байтов за раз, то контроллер, захватив шину, удерживает ее в течение передачи соответствующего количества байтов.
    Многобайтные пакеты полезны для передачи многобайтных регистров данных, например от АЦП, без риска того, что центральный процессор или другие DMA каналы, имеющие доступ к многобайтным регистрам испортят данные, хранящиеся во временных многобайтных регистрах.
    Длина пакета передачи настраивается в битовом поле режима придачи канала (BURSTLEN) в регистре управления (CTRL) по каждому каналу отдельно.
Рис.1 иллюстрирует передачи данных в пакетном режиме.
    Блочная передача и режим повтора
    Под понятием блочной передачи подразумевается операция выполнения передачи всех требуемых данных, которые измеряются в байтах и задаются размером блока. Размер блока задается в 16-битном регистре счетчика блока передачи (TRFCNT), который позволяет задавать величину блока до 64 Кбайт. Значение ноль – соответствует размеру блока 64 Кбайт.
Размер блока не должен быть кратным количеству байтов пакетной передачи, передача данных остановится, когда все байты блока будут переданы. Например, используя режим четырехбайтной пакетной передачи с размером блока в 10 байт, передача будет выполнена двумя полными передачами данных и одной заключительной двухбайтной передачей.
    Для увеличения количества передаваемых данных более 64 Кбайт, может быть использован счетчик повторов блочной передачи требуемое количество раз. Общая сумма переданных данных будет равна величине блока умноженной на значение счетчика повторов. Режим повтора включается установкой бита режима повтора (REPEAT) в регистре управления каналом (CTRL). Информация о количестве повторений находится в регистре счетчика повторов (REPCNT). При использовании 8-битного счетчика повторений контроллер DMA может передать 16 Мбайт данных без вмешательства центрального процессора.
Также возможно достичь бесконечного числа повторений, установкой разрешения режима повтора и настроив счетчик повторов в ноль.
    Рис.1 иллюстрирует блочную передачу в примере передачи посылке данных DMA.
    DMA посылка
    Понятие DMA посылки в данном контексте означает полную процедуру, включающую в себя передачу всех данных с учетом повторных блочных передач. DMA посылка начинается с первого DMA запроса, после подготовки канала и заканчивается когда все блочные передачи завершены и счетчик повторений равен нулю.
    Рис.1 иллюстрирует различие между передачей данных, блочными передачами и DMA посылкой.
Рис.1. Передача данных, блочная передача и DMA посылка
    Режимы адресации
    По умолчанию адреса источника и приемника фиксированы все время, пока идет передача, это означает, что каждая передача данных по каналу копирует данные из одной области памяти в другую. Такой режим удобен, например, для прямой пересылки данных от одного периферийного устройства другому. Длина пакета определяет количество байтов, копируемое в течение каждой передачи данных, но адреса источника и приемника остаются фиксированным для каждого доступа. Например, при четырехбитном пакетном режиме один и тот же бит будет копироваться четыре раза в течение каждой передачи данных.
    Для применений, где данные должны храниться в массивах, контроллер DMA может быть настроен на увеличение или уменьшение адреса получателя после каждого доступа к байту. Точно также, когда данные должны быть получены из массива, контроллер DMA может быть настроен на увеличение или уменьшение адреса источника после каждого доступа к байту. И, наконец, при копировании данных из одного массива в другой адреса и источника и получателя могут быть увеличены или уменьшены после каждого доступа к байту.
    Режимы адресации настраиваются в битовых полях режима адреса источника и получателя (SRCDIR и DESTDIR) по каждому каналу отдельно в регистре управления адресацией (ADDRCTRL).
    Примеры различных режимов адресации показаны на следующем рисунке:
    Перезагрузка адреса
    При использовании режима увеличения или уменьшения адреса должно происходить обновление адреса после каждого доступа. Однако, во многих применениях указатель адреса источника или получателя сбрасывается в начало массива в определенные моменты времени. В течение DMA посылки первичные адреса источника и получателя сохраняются в контроллере DMA и могут быть индивидуально настроены на перезагрузку по следующим условиям:
- конец каждой передачи;
- конец каждой блочной передачи;
- конец посылки;
- никогда не перезагружать.
     Например, перезагрузка адреса после каждой передачи данных может быть использована совместно с 8-битным пакетным режимом для повторяющегося чтения всех четырех результатов преобразования АЦП микропроцессора XMEGA и записи данных в массив. 8-битный пакетный режим гарантирует, что все четыре результата преобразования АЦП будут прочитаны разом и без использования центрального процессора, а указатель на адрес источника перезагрузится в начальное положение (на первый регистр результата АЦП) по завершению придачи данных.
    Отметим, что при использовании перезагрузки адреса после передачи пакета и общего количества байтов передачи некратного размеру пакета, передача последнего пакета будет остановлена по передаче последнего байта из общего количества байтов передачи, после чего также произойдет перезагрузка адреса. Например, используя 4-битную пакетную передачу с 17-байтным блоком, перезагрузка будет происходить после 4-го, 8-го, 12-го, 16-го и 17-го байтов.
    Настройка перезагрузки адреса для источника и получателя осуществляется в битовых полях SRCRELOAD и DESTRELOAD по каждому каналу отдельно в регистре управления адресом (ADDRCTRL).
    Запуск передачи и режим однократного запуска
    Возможные источник запуска передачи могут меняться в зависимости от устройства и пользователь должен изучить спецификацию на каждое устройство для получения полного перечня источников запуска DMA передачи.
    В дополнение к внешним источникам запуска DMA передачи возможен ручной запуск, по каждому каналу отдельно, установкой бита требования передачи (TRFREQ) в регистре управления каналом (CTRL).
    По умолчанию запуск передачи настроен на старт по началу блочной передачи. Посылка прекратится по завершению передачи одного блока, даже если включен повторный режим. Когда блок передан, канал ждет появления следующего запуска.
    Для некоторых применений такой режим запуска передачи является не пригодным. Установка бита режима однократного запуска (SINGLE) в регистре управления каналом (CTRL) будет осуществлять одну передачу данных при каждом запуске, а не целый блок. Остальные настройки каналов и режимов работы не меняются при включении режима однократного запуска.
    Режим однократного запуска обычно используется совместно с доступом к многобайтным периферийным регистрам, где адреса перезагружаются после каждой передачи данных.
    Обработка прерываний
    Каждый DMA канал может быть настроен на формирование прерываний после следующих действий:
- Завершение передачи;
- Ошибка передачи.
    По умолчанию прерывание по завершению передачи формируется после каждой блочной передачи. При включенном режиме повторной передачи прерывание не формируется, пока не будут переданы все блоки, и счетчик повторений не станет равным нулю. Исключением является режим бесконечной повторной передачи, в этом случае прерывание формируется после передачи каждого блока.
    Прерывание ошибки передачи формируется, если процесс передачи был прерван по какой-то причине. Такое может произойти, например, если один канал контроллера DMA или весь модуль был отключен в процессе передачи. Передача также может быть прервана попыткой записи или чтения пространства EEPROM, если центральный процессор находится в каком-либо из спящих режимов.
    Отметим, что на два прерывания используется лишь один вектор прерывания – вектор по DMA каналу. Поэтому в процедуре обработки прерываний необходимо проверить флаги, выполнить соответствующие действия и очистить флаги вручную.
    Доступ контроллера DMA к многобайтным регистрам
    Несколько регистров модуля DMA являются двух- или трехбайтными. Для того, чтобы гарантировать, что все байты многобайтного регистра прочитаны или записаны совместно – начинайте запись или чтение с самого младшего байта.
    В процессе чтения, регистр завершения устанавливается, когда первый байт записан и следующие один или два байта помещены во временные регистры до их непосредственного чтения.
    В процессе записи, первые один или два байта помещаются во временные регистры, до тех пор, пока последний байт не будет записан, что запустит процесс записи всего регистра.
    Важно отметить, что временные регистры являются общими для всех многобайтных регистров модуля DMA. Поэтому необходимо закончить операцию чтения или записи многобайтного регистра, прежде чем получать доступ к другому, иначе данные будут испорчены. Для приложений использующих многопоточную передачу или использующих доступ к контроллеру DMA посредствам процедуры обработки прерываний, пользователь должен программно осуществить механизмы получения ручного доступа к многобайтовым регистрам модуля DMA.
    Многобайтовыми регистрами являются:
- счетчик переданных блоков;
- адрес источника;
- адрес получателя.
Дополнительные возможности
    1. Двойная буферизация.
    Для осуществления продолжительных передач, два канала могут быть связаны так, что второй начинает принимать передачу сразу же, как первый закончил прием и наоборот. При этом у приложения остается время на обработку данных переданных по первому каналу, подготовка новых буферов данных и установка регистров канала начинается в то время, пока второй канал еще работает. Такой режим работы называется двойной буферизацией или цепочной передачей.
    При работе в режиме двойной буферизации для двух задействованных каналов важно, чтобы оба они были настроены на одинаковое количество повторений.
    Отметим, что парными каналами для совместной работы в режиме двойной буферизации могут быт только 0 и 1 или 2 и 3. Также существует возможность, когда одна пара работает в режиме двойной буферизации, в то время как другая не используется или работает независимо друг от друга.
    2. Приоритет канала.
    Если более одного канала ждут очереди на передачу, то для гарантии надежной работы необходимо использовать схему учета приоритета при захвате шины DMA канала.
    Модуль DMA микропроцессора XMEGA может осуществлять следующие приоритетные схемы:
- циклический алгоритм переключения по всем каналам;
- наивысший приоритет по 0 каналу и циклический алгоритм переключения по остальным;
- наивысший приоритет по 0 каналу, следующий по приоритету – канал 1 и циклический алгоритм переключения по остальным;
- все каналы имеют разный приоритет, наивысший у канала 0 и далее по убыванию приоритета.
    При работе каналов с циклическим алгоритмом переключения они чередуются при каждом захвате шины модулем DMA. Каналы с фиксированным приоритетом всегда будут получать доступ к обмену данными раньше каналов с циклическим алгоритмом переключения. Однако какой бы не был приоритет у канала, передача не может быть прервана, если она уже началась. Отметим, что модуль DMA может осуществлять одновременно передачу данных только по одному каналу.
Для быстродействующих применений с частым использованием модуля DMA важно тщательно спланировать приоритетную очередность работы каналов для достижения необходимой временной дискретизации.
    С чего начать
    1. Копирование блока памяти.
    Задача: Копировать массив размером 1 Кб от источника к передатчику, используя канал 0 модуля DMA настроенный на 8-байтовый пакетный режим и ручной запуск передачи.
- Установите бит включения (ENABLE) в регистре управления DMA (CTRL), тем самым, включив DMA с настройками по умолчанию.
- Установите битовое поле режима передачи (BURSTLEN) в регистре управления каналом 0 (CTRL) в значение 0x03 для выбора восьмибайтного пакетного режима передачи.
- Установите битовое поле режима адреса источника (SRCDIR) в регистре управления адресом канала 0 (ADDRCTRL) в значение 0x01 для выбора увеличения адреса источника после каждого доступа к байту.
- Установите битовое поле режима адреса приемника (DESTDIR) в регистре управления адресом канала 0 (ADDRCTRL) в значение 0x01 для выбора увеличения адреса приемника после каждого доступа к байту.
- Установите регистр запуска источника (TRIGSRC) по каналу 0 в значение 0x00 для выбора ручного режима запуска.
- Установите регистр размера блочной передачи (TRFCNT) по каналу 0 в значение 0x0400 для выбора размера блока в 1 Кб.
- Установите регистр адреса источника (SRCADDR) по каналу 0 на указатель начала массива источника.
- Установите регистр адреса приемника (DESTADDR) по каналу 0 на указатель начала массива приемника.
- Установите бит разрешения работы (ENABLE) в регистре управления каналом 0 (CTRL) для включения канала 0 модуля DMA.
- Установите бит требования передачи (TRFREQ) в регистре управления каналом 0 (CTRL) для запуска передачи.
- Дождитесь установки бита флага прерывания завершения передачи по каналу 0 (CH0TRNIF) в регистре состояний прерываний передачи (INTFLAGS) указывающего на окончание передачи. Очистите его записью логической единицы в него.
2. Однократный запуск копирования байта данных из массива SRAM в периферийное устройство.
Задача: Скопировать 2 Кб данных из массива в регистры ввода-вывода периферийного устройства, используя канал 2 модуля DMA в режиме захвата цикла и ручном запуске передачи каждого байта.
- Установите бит включения (ENABLE) в регистре управления DMA (CTRL), тем самым, включив DMA с настройками по умолчанию.
- Установите бит однократного запуска (SINGLE) в регистре управления (CTRL) по каналу 2 для выбора режима однократного запуска.
- Установите битовое поле режима передачи (BURSTLEN) в регистре управления каналом 2 (CTRL) в значение 0x00 для выбора режима захвата цикла.
- Установите битовое поле режима адреса источника (SRCDIR) в регистре управления адресом канала 2 (ADDRCTRL) в значение 0x01 для выбора увеличения адреса источника после каждого доступа к байту.
- Установите битовое поле режима адреса приемника (DESTDIR) в регистре управления адресом канала 2 (ADDRCTRL) в значение 0x00 для выбора фиксированного адреса приемника между доступами к байтам.
- Установите регистр запуска источника (TRIGSRC) по каналу 2 в значение 0x00 для выбора ручного режима запуска.
- Установите регистр размера блочной передачи (TRFCNT) по каналу 2 в значение 0x0800 для выбора размера блока в 2 Кб.
- Установите регистр адреса источника (SRCADDR) по каналу 2 на указатель начала массива источника.
- Установите регистр адреса приемника (DESTADDR) по каналу 2 на указатель регистра ввода-вывода периферийного устройства.
- Установите бит разрешения работы (ENABLE) в регистре управления каналом 2 (CTRL) для включения канала 2 модуля DMA.
- Установите бит требования передачи (TRFREQ) в регистре управления каналом 2 (CTRL) для запуска передачи одного байта из массива в периферийное устройство. Повторять до тех пор, пока не будет установлен флаг прерывания завершения передачи по каналу 2 (CH2TRNIF) в регистре состояний прерываний передачи (INTFLAGS) указывающего на окончание передачи. Очистите его записью логической единицы в него.
3. Копирование 4-байтного слова из периферийного устройства в массив SRAM.
Задача: Копирование 4 Кб данных из периферийного 4-байтного регистра результата в массив с использованием канала 1 модуля DMA в 4-байтном пакетном режиме и запуском передачи от периферийного устройства.
- Установите бит включения (ENABLE) в регистре управления DMA (CTRL), тем самым, включив DMA с настройками по умолчанию.
- Установите бит однократного запуска (SINGLE) в регистре управления (CTRL) по каналу 1 для выбора режима однократного запуска.
- Установите битовое поле режима передачи (BURSTLEN) в регистре управления каналом 1 (CTRL) в значение 0x02 для выбора 4-байтного пакетного режима передачи.
- Установите битовое поле режима перезагрузки адреса источника (SRCRELOAD) в регистре управления адресом канала 1 (ADDRCTRL) в значение 0x02 для выбора перезагрузки адреса источника после передачи каждых 4 байтов данных.
- Установите битовое поле режима адреса источника (SRCDIR) в регистре управления адресом канала 1 (ADDRCTRL) в значение 0x01 для выбора увеличения адреса источника после каждого доступа к байту.
- Установите битовое поле режима адреса приемника (DESTDIR) в регистре управления адресом канала 1 (ADDRCTRL) в значение 0x01 для выбора увеличения адреса приемника после каждого доступа к байту.
- Установите регистр запуска источника (TRIGSRC) по каналу 1 в режим запуска наиболее подходящий под используемое периферийное устройство.
- Установите регистр размера блочной передачи (TRFCNT) по каналу 1 в значение 0x1000 для выбора размера блока в 4 Кб.
- Установите регистр адреса источника (SRCADDR) по каналу 1 на первый регистр результата периферийного устройства.
- Установите регистр адреса приемника (DESTADDR) по каналу 1 на начало массива приемника.
- Установите бит разрешения работы (ENABLE) в регистре управления каналом 1 (CTRL) для включения канала 1 модуля DMA.
- Дождитесь установки бита флага прерывания завершения передачи по каналу 1 (CH1TRNIF) в регистре состояний прерываний передачи (INTFLAGS) указывающего на окончание передачи. Очистите его записью логической единицы в него.
    Пример 1.
   Задача: Написать программу опроса АЦП и выдачи полученных значений на ЦАП посредствам передачи данных через DMA.
   Так как процессор в данной передаче участие не принимает, то будем использовать настройки частоты по умолчанию. В качестве опрашиваемого канала АЦП возьмем ADCA.CH0, это ножка 3 порта A. АЦП настроим на беззнаковый автоматический режим. Более подробную информацию о использовании АЦП можно найти в уроке «Использование АЦП в микропроцессорах XMega А». В качестве выходного канала ЦАП возьмем канал 0 DACB. Более подробную информацию о использовании ЦАП можно найти в уроке «Использование ЦАП в микропроцессорах XMega А». Для осуществления передачи данных будем использовать канал 0 модуля DMA. Модуль DMA настроим на повторяющуюся передачу двухбайтными пакетами в режиме одиночной передачи с инкрементацией адресов после каждой передачи и перезагрузкой адресов после передачи пакета.
   Код работающей программы на языке C для процессора ATXmega 128A1 имеет следующий вид:
#define ENABLE_BIT_DEFINITIONS // разрешение использования групповых битовых имен
/* Объявление используемых библиотек */
#include <ioxm128a1.h>
#include <ina90.h>
void InitADC(void) // Настройка АЦП
{
/* беззнаковый режим, автоматический режим, 12-битный результат с правым выравниванием */
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc | 0x08;
/* разрешение работы бэндгап-элемента, внутреннее опорное напряжение 1В */
ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | 0x02;
/* периферийная частота = clk/16 (48MHz/16)*/
ADCA.PRESCALER = ADC_PRESCALER_DIV16_gc;
/* канал 0 ADCA настроен на внешний несимметричных вход */
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
/* Ножка 3 порта А настроена как положительный вход */
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN3_gc;
/* Разрешение работы АЦП */
ADCA.CTRLA|=ADC_ENABLE_bm;
}
void InitDAC(void) // Настройка ЦАП
{
DACB.CTRLB = 0; // однаканальная работа канала 0
DACB.CTRLA = 0x05; // Разрешение работы DACB и канала 0
DACB.TIMCTRL = 0x50; // минимум 48 CLK между преобразованиями
}
void InitDMA(void) // Настройка DMA
{
DMA.CTRL = DMA_ENABLE_bm; // Включение DMA
DMA.CH0.CTRLA = DMA_CH_SINGLE_bm | DMA_CH_BURSTLEN1_bm | DMA_CH_REPEAT_bm; // Настройка на повторяющуюся передачу 2 байтными пакетами в одиночном режиме
DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD1_bm | DMA_CH_DESTRELOAD1_bm | DMA_CH_SRCDIR0_bm |
DMA_CH_DESTDIR0_bm; // Установка инкрементации адресов после каждой передачи и перезагрузка после пакета
DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC4_bm; // Запуск передачи от канала 0 АЦП
DMA.CH0.TRFCNT=2; // Установка счетчика передачи в 2 байта
DMA.CH0.SRCADDR0 = (int)&ADCA.CH0RES; // Настройка адреса источника на данные с канала 0 АЦП
DMA.CH0.SRCADDR1 = (int)&ADCA.CH0RES>>8;
DMA.CH0.SRCADDR2 = 0;
DMA.CH0.DESTADDR0 = (int)&DACB.CH0DATA;// Настройка адреса приемника на данные канала 1 ЦАП
DMA.CH0.DESTADDR1 = (int)&DACB.CH0DATA>>8;
DMA.CH0.DESTADDR2 = 0;
DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; // разрешение работы канала 0 DMA
}
int main(void)
{
__disable_interrupt(); // Запрещение прерываний
InitADC(); // Запуск процедуры инициализации АЦП
InitDAC(); // Запуск процедуры инициализации ЦАП
InitDMA(); // Запуск процедуры инициализации DMA
__enable_interrupt(); // Разрешение прерываний
while(1) {} // Пустой бесконечный цикл
}
    Пример 2.
   Задача: Написать программу отправки данных из одного массива в другой через DMA канал, отправку инициировать по появлению определенного уровня сигнала на какой-либо ножке (например, при нажатии кнопки),каналем однократной передачейива в другой через мсов после каждой передачи и перезагрузкой адресов после передачи блока.,,,.б причем при одном нажатии массив передавался только один раз.
   Так как процессор в данной передаче участие не принимает, то будем использовать настройки частоты по умолчанию. Будем использовать ножку 2 порта K в качестве входа для запуска режима вычисления смещения (на нее, например, можно повесить кнопку), причем она будет подтянута к питанию. Более подробную информацию о настройке ножек можно найти в уроке «Настройка и использование ножек Xmega A». Для осуществления передачи данных будем использовать канал 0 модуля DMA. Модуль DMA настроим на повторяющуюся передачу однобайтными пакетами с инкрементацией адресов после каждой передачи и перезагрузкой адресов после окончания передачи. Будем передавать массив величиной в 20 двухбайтных слов. Для наглядности передачи информации будем в основном цикле бесконечно инкрементировать первый элемент массива источника до достижения значения 100 с последующим сбросом в ноль.
   Код работающей программы на языке C для процессора ATXmega 128A1 имеет следующий вид:
#define ENABLE_BIT_DEFINITIONS // разрешение использования групповых битовых имен 

/* Объявление используемых библиотек */
#include <ioxm128a1.h>
#include <ina90.h>
int massIn[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; // массив источника
int massOut[20]; // массив приемника
int DMAtrans=0; // флаг передача по DMA произведена
void InitDMA(void) // Настройка DMA
{
DMA.CTRL = DMA_ENABLE_bm; // Включение DMA
DMA.CH0.CTRLA = DMA_CH_BURSTLEN0_bm | DMA_CH_REPEAT_bm; // Настройка на повторяющуюся передачу 1 байтными пакетами
DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_gm |DMA_CH_SRCDIR0_bm | DMA_CH_DESTRELOAD_gm |
DMA_CH_DESTDIR0_bm; // Установка инкрементации адресов после каждой передачи и обновление адресов по окончанию передачи
DMA.CH0.TRFCNT=40; // Установка счетчика передачи на 40 байтов (т.к. int = 2 байтом)
DMA.CH0.SRCADDR0 = (int)&massIn; // Настройка адреса источника на массив massIn
DMA.CH0.SRCADDR1 = (int)&massIn>>8;
DMA.CH0.SRCADDR2 = 0;
DMA.CH0.DESTADDR0 = (int)&massOut; // Настройка адреса приемника на массив massOut
DMA.CH0.DESTADDR1 = (int)&massOut>>8;
DMA.CH0.DESTADDR2 = 0;
DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; // разрешение работы канала 0 DMA
}
void main(void)
{
__disable_interrupt(); // Запрещение прерываний
PORTK.PIN2CTRL = PORT_OPC_PULLUP_gc; // Установка подятнутого входа порта K ножки 2
InitDMA(); // Запуск процедуры инициализации DMA
__enable_interrupt(); // Разрешение прерываний
while(1) // Основной бесконечный цикл
{
if (massIn[0]<100) // постоянное изменение перового элемента массива massIn от 0 до 100
massIn[0]++;
else
massIn[0]=0;
if (!(PORTK.IN & 0x04)) // Если на ножке 2 порта К низкий уровень
{
if (!(DMA.INTFLAGS&0x01)) // и передача не по DMA не производилась
DMA.CH0.CTRLA |= DMA_CH_TRFREQ_bm; // запуск DMA передачи
}
else // Если на ножке 2 порта К высокий уровень
if (DMA.INTFLAGS&0x01) // Если передача завершена
DMA.INTFLAGS|=1; // очищение флага DMA передачи
}
}
    Blogger Comment
    Facebook Comment

0 коммент.:

Отправить комментарий