Задача вроде простая.
#include "dma_template.h"
typedef dma_channel<'1'> adc_dma;
void DmaEnable(DMA_DBUFMODE_enum double_buffer_mode, DMA_PRIMODE_enum priority_mode)
{
DMA.CTRL=0
| (1<<DMA_ENABLE_bp)
| (0<<DMA_RESET_bp)
| ((uint8_t)double_buffer_mode)
| ((uint8_t)priority_mode)
;
}
void StartAdcDmaChannel0(uint16_t transfer_size)
{
adc_dma::SetTransferSize(transfer_size);
adc_dma::StartPeripheralTransfer(DMA_CH_BURSTLEN_2BYTE_gc, false);
}
void InitAdcDmaChannel_0()
{
adc_dma::ResetChannel();
adc_dma::SetAddressControl(DMA_CH_SRCRELOAD_BURST_gc, DMA_CH_SRCDIR_INC_gc, DMA_CH_DESTRELOAD_BLOCK_gc, DMA_CH_DESTDIR_INC_gc);
adc_dma::SetTriggerSource(DMA_CH_TRIGSRC_ADCA_CH0_gc;
adc_dma::SetInterruptLevel(DMA_CH_ERRINTLVL_OFF_gc, DMA_CH_TRNINTLVL_HI_gc);
adc_dma::SetSrcAddress((uint16_t)AdcBuffer);
adc_dma::SetDestAddress((uint16_t)&ADCA.CH0RESL);
adc_dma::SetRepeatCount(0);
}
volatile bool StartFastAdc;
void main()
{
DmaEnable();
InitAdcDmaChannel_0();
sei();
while (1) {
if (StartFastAdc) {
StartFastAdc=false;
StartAdcDmaChannel0();
}
}
}
P.S. Во вложенном файле тоже самое через регистры, если через шаблоны не понятно.
Но я бы не хотела, чтобы мой вопрос о программировании DMA вы подменяли советами, как мне надлежит программировать АЦП.Хорошо, тем более АЦП вспоминать надо (больше 3х лет не работал с АЦП - забыл почти). Настройка ДМА (настройку АЦП не привожу - сами лучше знаете как настраивать):
На вопрос о выборе двойного или стандартного канала DMA ответить не могу, т.к. не понимаю между ними разницы. Охотно приму совет, как сделать между ними выбор.Если у Вас режимоднократного запуска, то буферизация не нужна. Она могла бы быть нужна, если бы измерения велись непрерывно и время между двумя измерениями настолько мало, что перезапустить ДМА МК может не успеть, если успевает, то достаточно стандартного канала (в Double Buffering режиме два канала работают поочереди, причём запуск второго канала происходит автоматически, при завершении работы первого).