DMA для dsPIC. Контроллер Прямого доступа к памяти (DMA). DMA контроллер. Регистр Смещения Адреса Начала A DPSRAM Канала DMA x, страница 12

IFS3bits.DMA5IF = 0;              //Clear the DMA interrupt flag bit

IEC3bits.DMA5IE = 1;                         //Set the DMA interrupt enable bit

DMA5CONbits.CHEN=1;                    // Enable DMA

установка DMA channel 5 Interrupt handler:

unsigned int DmaBuffer = 0;

void __attribute__((__interrupt__)) _DMA5Interrupt(void)

{

// Switch between Primary and Secondary Ping-Pong buffers

if(DmaBuffer == 0)

{

ProcessADCSamples(BufferA);

}

else

{

ProcessADCSamples(BufferB);

}

DmaBuffer ^= 1;

IFS3bits.DMA5IF = 0; //Clear the DMA5 Interrupt Flag

}

установка ADC1 for DMA operation:

AD1CON1bits.ADDMABM = 0; // Don't Care: ADC address generation is

// ignored by DMA

AD1CON2bits.SMPI = 3; // Don't Care

AD1CON4bits.DMABL = 3; // Don't Care

IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit

IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt

AD1CON1bits.ADON = 1; // Turn on the A/D converter

Типичный алгоритм оперирующий с данными ADC, нуждается в сортировке этих переданных данных или их индексирования, перескакивая ненужные данные. Любой из этих методов требует большего количества кода и потребляет много времени выполнения. При Способе Периферийной Косвенный адресации устройство ADC определяет специальную методику адресации, когда данные для каждого канала ADC помещаются в его собственный буфер. Для примера выше, если канал DMA конфигурирован для Способа Периферийной Косвенной адресации, передача DMA перемещает данные ADC в отдельные буфера, как показано в Рисунке 22-12.

Figure 22-12: Data Transfer from ADC with Peripheral Indirect Addressing

Чтобы разрешить этот вид адресации ADC, бит Режима Формирования Буфера DMA (ADDMABM) в регистре Управлении ADCx 1 (ADxCON1), должен быть 0. Если этот бит 1, ADC генерирует адреса в порядке преобразования (то же самое как режим DMA с Регистровой Косвенной Адресацией с Post-Increment).

Как упомянуто ранее, Вы должны обратить особое внимание на число младших битов, которые резервируются для периферийного устройства, когда регистры Смещения Адреса Начала DPSRAM (DMAxSTA и DMAxSTB) инициализируются приложением. Для ADC, число битов будет зависеть от размера и числа буферов ADC.

Число буферов ADC инициализируется с Нормой{Разрядом;Скоростью} Приращения для адреса DMA, биты SMPI <3:0> в регистре Управлении ADCx 2 (ADxCON2). Размер каждого буфера ADC инициализируется числом адресов Буфера DMA на Аналоговый Вход биты DMABL <2:0> в регистре Управлении ADCx 4 (ADCxCON4).

Например, если SMPI <3:0> = 3, и DMABL <2:0> = 3, будут 4 буфера ADC (SMPI <3:0> + 1), каждый с 8 словами (2 DMABL <2:0>), для общего количества 32 слов (64 байта). Это означает, что адрес смещения, который записывается в DMAxSTA, и DMAxSTB должен иметь 6 (26 битов = 64 байта) установленных на нуль младших битов.

Если используется MPLAB®C30 компилятор для инициализации регистров DMAxSTA и DMAxSTAB, надлежащее выравнивание данных должно быть определено через атрибуты данных. Для вышеупомянутых условий код, показанный в Примере 22-6 должным образом инициализирует регистры DMAxSTB и DMAxSTA.

Пример 22-6: DMA buffer alignment with MPLAB® C30

int BufferA[4][8] __attribute__((space(dma),aligned(64)));

int BufferB[4][8] __attribute__((space(dma),aligned(64)));

DMA0STA = __builtin_dmaoffset(&BufferA[0][0]);

DMA0STB = __builtin_dmaoffset(&BufferB[0][0]);

Example 22-7 illustrates the code for this configuration.

Пример 22-7: Code for ADC and DMA with Peripheral Indirect Addressing

установка ADC1 for channel 0-3 sampling:

AD1CON1bits.FORM = 3;                   // Data Output Format: Signed Fraction (Q15 format)

AD1CON1bits.SSRC = 2;                    // Sample Clock Source: GP Timer starts conversion

AD1CON1bits.ASAM = 1;                   // Sampling begins immediately after conversion

AD1CON1bits.AD12B = 0;                  // 10-bit ADC operation

AD1CON1bits.SIMSAM = 0;   // Samples multiple channels sequentially