DMA传输时可以在中断中更改地址吗?????
zhifang yang1:
可以啊,但是不会实时生效。
DMA工作的时候会先把size ,source address, dest address 先load到DMA内部缓存中去,实际运行时按缓存运行的。
所以你修改DMAxSA,DMAxDA 并不会影响到已经在进行的DMA动作中。会在下一次启动DMA的时候生效。
PS:DMA一般5个MCLK周期就完成了,很难通过中断正好卡到DMA周期内吧,你这样的应用的目的介绍一下呢?
xue liu1:
回复 zhifang yang1:
我想实现对信号的实时处理 通过两个buffer实现乒乓缓存 想在中断中更改地址 让下一次数据存储在另一个数据中 但是在实现过程中 经过DMA传输之后 数据并没有出现在正确数组中 例如 我配置的地址是buffer1 但是数据会存储在buffer2中 这个是为什么 谢谢
灰小子:
回复 xue liu1:
建议提供下程序。
另外,你的实时性要求最大多少延迟?
xue liu1:
回复 灰小子:
程序是这样的
#include "msp430f5529.h"
#include "HAL_PMM.h"
#include "variable.h"
#include "user.h"
unsigned int voice_data[256];
volatile int DMAdone=0;
void main()
{
WDTCTL = WDTPW + WDTHOLD;
P6SEL |= BIT4;
P5SEL |= BIT2+BIT3; //P5.2 P5.3 选择XT2晶振功能
P5SEL |= BIT7; //P5.7设定为TB1定时器输
P5DIR |= BIT7; //P5.7设为输出
P2DIR |= BIT2; //SMCLK 从P2.2输出
P2SEL |= BIT2;
P7DIR |= BIT7; //MCLK 从P7.7输出
P7SEL |= BIT7;
P7SEL |= BIT6; //定时器输出
P7DIR |= BIT6;
UCSCTL6 &= ~(XT2OFF);
SetVCore(3);
__bis_SR_register(SCG0);
UCSCTL0 = DCO1+DCO2+DCO3+DCO4;
UCSCTL1 = DCORSEL_5;
UCSCTL2 = FLLD_3 + 5;
UCSCTL3 = SELREF_5 + FLLREFDIV_3;
UCSCTL4 = SELA_4 + SELS_3 + SELM_3;
UCSCTL5 = DIVA_5 + DIVS_1;
__bic_SR_register(SCG0);
__delay_cycles(8192);
do
{
UCSCTL7 &= ~XT1LFOFFG;
}while (UCSCTL7&XT1LFOFFG);
ADC12CTL0 = ADC12ON;
ADC12MCTL0 = ADC12INCH_4;
ADC12IFG = 0;
ADC12CTL0 |= ADC12SHT0_6;
ADC12CTL1 = ADC12SHS_3 + ADC12CONSEQ_2 + ADC12CSTARTADD_0 + ADC12SHP + ADC12SSEL_2 + ADC12DIV_5;
ADC12CTL0 |= ADC12ENC;
TBCCR0 = 1200;
TBCCR1 = 200;
TBCCTL1 = OUTMOD_7;
TBCTL = TBSSEL_2 + MC_1 + TBCLR + ID_0;
DMACTL0 = DMA0TSEL_24;
DMACTL4 = DMARMWDIS;
DMA0CTL &= ~DMAIFG;
DMA0CTL = DMADT_4+DMAEN+DMADSTINCR_3+DMAIE;
DMA0SZ = 256;
__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) &ADC12MEM0);
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) buffer);
__bis_SR_register(GIE); //使能全局中断
__delay_cycles(380000);
while(1)
{
__delay_cycles(374400);
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(DMA_VECTOR))) DMA_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(DMAIV,16))
{
case 0: break;
case 2: // DMA0IFG = DMA Channel 0
//__delay_cycles(2048);
if(DMAnum%2==1)
{
__no_operation();
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &buffer);
__no_operation();
}
if(DMAnum%2==0)
{
__no_operation();
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &voice);
__no_operation();
}
DMAnum=DMAnum+1;
__no_operation();
break;
case 4: break; // DMA1IFG = DMA Channel 1
case 6: break; // DMA2IFG = DMA Channel 2
case 8: break; // DMA3IFG = DMA Channel 3
case 10: break; // DMA4IFG = DMA Channel 4
case 12: break; // DMA5IFG = DMA Channel 5
case 14: break; // DMA6IFG = DMA Channel 6
case 16: break; // DMA7IFG = DMA Channel 7
default: break;
}
}
如果我将buffer作为目的地址 数据就会存储在voic数组中 情况就是这样 数据不会存储到设置的目的地址中