This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

msp430f5438A的DMA在code比较少时一切正常,但是当code较大时,DMA死活不触发,怎么办???????????????

如题,下面的程序测试数据正常,中断正常。但是把这些语句放到我的一个code量较大的工程中,DMA怎么也不工作了。


我用ADC的ifg触发一次DMA,但是ADC的各个参数正常,DMA的初始化也都正常,但DMA就是不触发。

当我删除这个大code的工程中的许多代码后,DMA就可以工作了,这是哪里的问题呢?code太大会影响dma???

__no_init static uint16_t DMA_DST_AD0[2048];
__no_init static uint16_t DMA_DST_AD1[2048];
__no_init static uint16_t DMA_DST_AD2[512];

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

  SFRIE1 |= OFIE;        // Enable global oscillator fault flag
  __bis_SR_register(GIE);//enable interrupts


  //ADC设置
  P6SEL |=BIT0 + BIT1 + BIT2;               // Enable VeREF+ & A/D channel A0
  ADC12CTL0 = ADC12ON                       // 打开ADC内核
             +ADC12MSC                      // 连续采样
             +ADC12SHT0_2;                  // 保持时间为16个cycles

  ADC12CTL1 = ADC12SSEL_2                   // 时钟选择为:MCLK
              +ADC12DIV_4                   // 时钟分频为:4+1=5,即25M/5=5MHz
              +ADC12SHP                     // 采样信号源自采样定时器
              +ADC12CONSEQ_3;               // 序列通道多次采样
  ADC12MCTL0 = ADC12INCH_0;                 // ref+=AVcc, channel = A0
  ADC12MCTL1 = ADC12INCH_1;                 // ref+=AVcc, channel = A1
  ADC12MCTL2 = ADC12INCH_2+ADC12EOS;        // ref+=AVcc, channel = A2, end seq.

  ADC12CTL0 |= ADC12ENC;                    // Enable conversions
  ADC12CTL0 |= ADC12SC;                     // Start conversion - software trigger

  //DMA0、1、2设置
  //触发源选择
  DMACTL0 = DMA0TSEL_24        // 通道0 ADC12IFGx triggered
           +DMA1TSEL_24;       // 通道1 ADC12IFGx triggered
  DMACTL1 = DMA2TSEL_24;       // 通道2 ADC12IFGx triggered
  //公共参数设置
  DMACTL4 = DMARMWDIS;         // CPU读写操作时禁止DMA传输

  //DMA0通道参数设置
  DMA0CTL = 0;                 // 寄存器清零
  DMA0CTL = DMADT_4            // 单次重复传输模式
           +DMAEN              // 使能DMA
           +DMADSTINCR_3       // 目标地址自增,源地址不变
           +DMAIE;             // 使能DMA传输完成中断
  DMA0SZ = 2048;               // DMA0传输大小

  //DMA1通道参数设置
  DMA1CTL = 0;                 // 寄存器清零
  DMA1CTL = DMADT_4            // 单次重复传输模式
           +DMAEN              // 使能DMA
           +DMADSTINCR_3       // 目标地址自增,源地址不变
           +DMAIE;             // 使能DMA传输完成中断
  DMA1SZ = 2048;               // DMA0传输大小

  //DMA2通道参数设置
  DMA2CTL = 0;                 // 寄存器清零
  DMA2CTL = DMADT_4            // 单次重复传输模式
           +DMAEN              // 使能DMA
           +DMADSTINCR_3       // 目标地址自增,源地址不变
           +DMAIE;             // 使能DMA传输完成中断
  DMA2SZ = 512;               // DMA0传输大小

  __data16_write_addr((uint16_t) &DMA0SA,(uint32_t) &ADC12MEM0);  //源地址:ADC12MEM0
  __data16_write_addr((uint16_t) &DMA0DA,(uint32_t) &DMA_DST_AD0);//目的地址:DMA_DST[]

  __data16_write_addr((uint16_t) &DMA1SA,(uint32_t) &ADC12MEM1);  //源地址:ADC12MEM1
  __data16_write_addr((uint16_t) &DMA1DA,(uint32_t) &DMA_DST_AD1);//目的地址:DMA_DST[]

  __data16_write_addr((uint16_t) &DMA2SA,(uint32_t) &ADC12MEM2);  //源地址:ADC12MEM2
  __data16_write_addr((uint16_t) &DMA2DA,(uint32_t) &DMA_DST_AD2);//目的地址:DMA_DST[]

  while(1)
  {
    Open_Beep;
    delay_nms(30);
    Close_Beep;
    delay_nms(100);
  }
}

//------------------------------------------------------------------------------
// DMA Interrupt Service Routine
//------------------------------------------------------------------------------
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
  switch(__even_in_range(DMAIV,16))
  {
    case 0: break;
    case 2:                                 // DMA0IFG = DMA Channel 0
      Close_Beep;                        // Toggle P1.0
      break;
    case 4:                                 // DMA1IFG = DMA Channel 1
      Close_Beep;                        // Toggle P1.0
      break;
    case 6:                                 // DMA2IFG = DMA Channel 2
      Close_Beep;                        // Toggle P1.0
      break;
    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;
  }
}

附件:仿真截图

  • 错误的地方已经找到了。但是不知道为啥会这样?

    我在dma初始化前进行过一次AD3的采样,程序如下。我只要将下面的语句屏蔽掉后,dma工作就正常了。

     

      ADC12CTL0 |= ADC12ENC;//使能转换
      ADC12CTL0 |= ADC12SC;
      
      for(j=0;j<BatteryBuffer_Lenght;j++)
      {
        while(!(ADC12IFG & BIT2))//等待采样结束
        {
          Feed_Dog;        //喂外部狗CAT1023,2013-12-24
        }
      
        temp = ADC12MEM2;// Move A1 results, IFG is cleared
        Battery[j]=temp;
      }
      
      ADC12IFG =0;
      ADC12CTL0 &=~ADC12ENC;//停止转换
      ADC12CTL0 &=~ADC12SC;

x 出现错误。请重试或与管理员联系。