搜索
bottom↓
回复: 8

msp430f5438A的DMA在code比较少时一切正常,但是当code较大时...

[复制链接]

出0入0汤圆

发表于 2014-6-17 09:29:27 | 显示全部楼层 |阅读模式
msp430f5438A的DMA在code比较少时一切正常,但是当code较大时,DMA死活不触发,这是怎么回事你?

下面的程序单独测试没有问题,dma数据传输正常,中断正常。

但是把下面的语句放到我的一个code量较大的工程中时,dma死活不工程啊。dma不放到此工程中时,此工程工作一切正常。

当我删除此工程中的大量代码后,dma工作正常了。

现在的现象好像是code量太大,dma不工作了????

难道程序跑飞了?


  1. __no_init static uint16_t DMA_DST_AD0[2048];
  2. __no_init static uint16_t DMA_DST_AD1[2048];
  3. __no_init static uint16_t DMA_DST_AD2[512];

  4. int main(void)
  5. {
  6.   WDTCTL = WDTPW + WDTHOLD; // Stop WDT

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


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

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

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

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

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

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

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

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

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

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

  57.   while(1)
  58.   {
  59.     Open_Beep;
  60.     delay_nms(30);
  61.     Close_Beep;
  62.     delay_nms(100);
  63.   }
  64. }

  65. //------------------------------------------------------------------------------
  66. // DMA Interrupt Service Routine
  67. //------------------------------------------------------------------------------
  68. #pragma vector=DMA_VECTOR
  69. __interrupt void DMA_ISR(void)
  70. {
  71.   switch(__even_in_range(DMAIV,16))
  72.   {
  73.     case 0: break;
  74.     case 2:                                 // DMA0IFG = DMA Channel 0
  75.       Close_Beep;                        // Toggle P1.0
  76.       break;
  77.     case 4:                                 // DMA1IFG = DMA Channel 1
  78.       Close_Beep;                        // Toggle P1.0
  79.       break;
  80.     case 6:                                 // DMA2IFG = DMA Channel 2
  81.       Close_Beep;                        // Toggle P1.0
  82.       break;
  83.     case 8: break;                          // DMA3IFG = DMA Channel 3
  84.     case 10: break;                         // DMA4IFG = DMA Channel 4
  85.     case 12: break;                         // DMA5IFG = DMA Channel 5
  86.     case 14: break;                         // DMA6IFG = DMA Channel 6
  87.     case 16: break;                         // DMA7IFG = DMA Channel 7
  88.     default: break;
  89.   }
  90. }
复制代码



附件:我的调试仿真图,adc的参数都是正确的,数据也是正确的,但是dma就是不触发。我单独测试dma时,adc,dma各个寄存器的参数和把dma程序放到code量较大工程中是一样的。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2014-6-17 09:34:22 | 显示全部楼层
方法就是慢慢隐藏  直到能工作, 再找你那块程序的问题,DMA 应该是不受CPU 及中断的影响的,  反正我试了 PWM 是会受中断的影响,根本不是硬件PWM. 所以能用ARM就用ARM,用起来很顺手.

出0入0汤圆

 楼主| 发表于 2014-6-17 09:41:03 | 显示全部楼层
wind2100 发表于 2014-6-17 09:34
方法就是慢慢隐藏  直到能工作, 再找你那块程序的问题,DMA 应该是不受CPU 及中断的影响的,  反正我试了 PWM ...

早就想换arm了,但是板子一大堆,仍不起啊。

两个工程单独测试都没有问题,合在一起,dam不触发,但是其他功能正常,堆栈我设置了10KB,还剩2KB,应该不是堆栈溢出的问题


出0入0汤圆

 楼主| 发表于 2014-6-17 18:06:25 | 显示全部楼层
wind2100 发表于 2014-6-17 09:34
方法就是慢慢隐藏  直到能工作, 再找你那块程序的问题,DMA 应该是不受CPU 及中断的影响的,  反正我试了 PWM ...

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

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

  1.   ADC12CTL0 |= ADC12ENC;//使能转换
  2.   ADC12CTL0 |= ADC12SC;
  3.   
  4.   for(j=0;j<BatteryBuffer_Lenght;j++)
  5.   {
  6.     while(!(ADC12IFG & BIT2))//等待采样结束
  7.     {
  8.       Feed_Dog;        //喂外部狗CAT1023,2013-12-24
  9.     }
  10.   
  11.     temp = ADC12MEM2;// Move A1 results, IFG is cleared
  12.     Battery[j]=temp;
  13.   }
  14.   
  15.   ADC12IFG =0;
  16.   ADC12CTL0 &=~ADC12ENC;//停止转换
  17.   ADC12CTL0 &=~ADC12SC;
复制代码

出0入0汤圆

发表于 2014-6-18 13:33:22 | 显示全部楼层
不会是 Feed_Dog 吧

出0入0汤圆

 楼主| 发表于 2014-6-18 14:02:27 | 显示全部楼层
wind2100 发表于 2014-6-18 13:33
不会是 Feed_Dog 吧

不是的

好像dma有问题?

出0入0汤圆

 楼主| 发表于 2014-6-18 14:05:30 | 显示全部楼层
wind2100 发表于 2014-6-18 13:33
不会是 Feed_Dog 吧

在新测试结果:

如果把下面的语句屏蔽掉,则dma工作正常,如果不屏蔽,则dma就死了,永远不中断了。

  
  //uint8_t j=0;
  //for(j=0;j<128;j++)
  //{
  //  while(!(ADC12IFG & BIT0))//等待采样结束
  //  {
  //    ;
  //  }
  //  DMA_DST_AD0[j] = ADC12MEM0;// Move A1 results, IFG is cleared
  //}



  1. __no_init uint16_t DMA_DST_AD0[2048];

  2. int main(void)
  3. {
  4.   WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT

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

  10.   ADC12CTL1 = ADC12SSEL_2                   // 时钟选择为:MCLK
  11.               +ADC12DIV_4                   // 时钟分频为:4+1=5,即25M/5=5MHz
  12.               +ADC12SHP                     // 采样信号源自采样定时器
  13.               +ADC12CONSEQ_2;               // 单通道多次采样
  14.   ADC12MCTL0 = ADC12INCH_0+ADC12EOS;        // ref+=AVcc, channel = A0

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

  17.   //////////////////////////////////////////////////////////////////////////////
  18.   //////////////////////////////////////////////////////////////////////////////
  19.   //如果把下面的这些语句屏蔽掉,dma读取ad值正常,但是放开这些语句,即先
  20.   //直接读一次ad值后再用dma读,此时dma就永远不触发了,这是怎么回事?
  21.   //////////////////////////////////////////////////////////////////////////////
  22.   //////////////////////////////////////////////////////////////////////////////
  23.   
  24.   //uint8_t j=0;
  25.   //for(j=0;j<128;j++)
  26.   //{
  27.   //  while(!(ADC12IFG & BIT0))//等待采样结束
  28.   //  {
  29.   //    ;
  30.   //  }
  31.   //  DMA_DST_AD0[j] = ADC12MEM0;// Move A1 results, IFG is cleared
  32.   //}

  33.   //DMA0设置
  34.   //触发源选择
  35.   DMACTL0 = DMA0TSEL_24;       // 通道0 ADC12IFGx triggered

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

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

  45.   __bis_SR_register(GIE);//enable interrupts
  46.   while(1);
  47. }

  48. //------------------------------------------------------------------------------
  49. // DMA Interrupt Service Routine
  50. //------------------------------------------------------------------------------
  51. #pragma vector=DMA_VECTOR
  52. __interrupt void DMA_ISR(void)
  53. {
  54.   switch(__even_in_range(DMAIV,16))
  55.   {
  56.     case 0: break;
  57.     case 2:                                 // DMA0IFG = DMA Channel 0
  58.       __no_operation();
  59.       break;
  60.     case 4: break;                          // DMA1IFG = DMA Channel 1
  61.     case 6: break;                          // DMA2IFG = DMA Channel 2
  62.     case 8: break;                          // DMA3IFG = DMA Channel 3
  63.     case 10: break;                         // DMA4IFG = DMA Channel 4
  64.     case 12: break;                         // DMA5IFG = DMA Channel 5
  65.     case 14: break;                         // DMA6IFG = DMA Channel 6
  66.     case 16: break;                         // DMA7IFG = DMA Channel 7
  67.     default: break;
  68.   }
  69. }
复制代码

出0入0汤圆

发表于 2014-6-18 15:57:16 | 显示全部楼层
看起来像ADC中断标志位出问题了,设断点跟踪一下,可能中断标志位一直没清零,触发不了DMA。

出0入0汤圆

 楼主| 发表于 2014-6-19 14:15:09 | 显示全部楼层
ringan865 发表于 2014-6-18 15:57
看起来像ADC中断标志位出问题了,设断点跟踪一下,可能中断标志位一直没清零,触发不了DMA。 ...

嗯,我单步都看了dma和adc的寄存器

先读一次adc后ifg标志确实置位了,但是我清除了dma还是不中断
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 11:05

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表