[STM32F4] 大声的问一句关于STM32F407 DMA重启的问题解决了么,快疯了。

[复制链接]
 楼主| lee_hwa 发表于 2013-12-17 16:27 | 显示全部楼层 |阅读模式
碰到DMA关闭后重新开启DMA不能产生中断的问题。
DMA_Mode_Circular,DMA_Mode_Normal两个模式都不行,

DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
然后
DMA_Cmd(DMA2_Stream0, DISABLE);  
DMA_Cmd(DMA2_Stream0, ENABLE);
第二次还是进不了中断。
dirtwillfly 发表于 2013-12-17 20:37 | 显示全部楼层
你试试:先把你用DMA的外设关闭,后重新配置DMA,然后开启DMA和外设
feilusia 发表于 2013-12-17 20:59 | 显示全部楼层
DMA不能随便关的吧,要先查询一些标志位,比如传输是否结束等,判断是否可关才关。
 楼主| lee_hwa 发表于 2013-12-18 09:06 | 显示全部楼层
dirtwillfly 发表于 2013-12-17 20:37
你试试:先把你用DMA的外设关闭,后重新配置DMA,然后开启DMA和外设

我把AD先关闭了,然后再关闭DMA。也不行。
 楼主| lee_hwa 发表于 2013-12-18 09:07 | 显示全部楼层
feilusia 发表于 2013-12-17 20:59
DMA不能随便关的吧,要先查询一些标志位,比如传输是否结束等,判断是否可关才关。 ...

哦,你是试过么?我试了试,等传输结束后再关闭,还是不行。
qzwx741 发表于 2013-12-18 09:09 | 显示全部楼层
看2L,先把你用DMA的外设关闭,后重新配置DMA,然后开启DMA和外设,应该是这个问题
ticomi 发表于 2013-12-18 09:12 | 显示全部楼层
我的一段关闭DMA的代码,使用正常:实在DMA接收完成的中断里关闭的
  1. DMA_Cmd(DMA2_Stream0, DISABLE);        //Disable DMA2 Stream0
  2.         DMA_Cmd(DMA2_Stream3, DISABLE);        //Disable DMA2 STream3

  3.         DMA_ClearFlag(DMA2_Stream3, DMA_FLAG_TCIF3);        //Clear DMA2 STream3 Transfer Complete Flag
  4.         DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0);        //Clear DMA2 STream0 Transfer Complete Flag       
  5.        
  6.        
  7.        
  8.         DMA_SetCurrDataCounter(DMA2_Stream3, ADC_TX_SIZE);        //Enable DMA2 Stream3
  9.         DMA_SetCurrDataCounter(DMA2_Stream0, ADC_RX_SIZE);        //Enable DMA2 Stream0       
 楼主| lee_hwa 发表于 2013-12-18 09:49 | 显示全部楼层
ticomi 发表于 2013-12-18 09:12
我的一段关闭DMA的代码,使用正常:实在DMA接收完成的中断里关闭的

你的是STM32F407么
 楼主| lee_hwa 发表于 2013-12-18 09:54 | 显示全部楼层
ticomi 发表于 2013-12-18 09:12
我的一段关闭DMA的代码,使用正常:实在DMA接收完成的中断里关闭的

据说STM32F103没有问题
 楼主| lee_hwa 发表于 2013-12-18 09:56 | 显示全部楼层
DMA_SetCurrDataCounter(DMA2_Stream0, ADC_RX_SIZE)可以  Enable DMA2 Stream0     是什么道理? ADC_RX_SIZE是多少
 楼主| lee_hwa 发表于 2013-12-18 10:18 | 显示全部楼层
请各位专家指点一下:
  1. DMA_InitTypeDef DMA_InitStructure;        //DMA³õʼ»¯½á¹¹ÌåÉùÃ÷
  2. void DMA_Config(void)
  3. {
  4.   //ADC_InitTypeDef       ADC_InitStructure;
  5.   //ADC_CommonInitTypeDef ADC_CommonInitStructure;
  6.   //DMA_InitTypeDef       DMA_InitStructure;
  7.   //GPIO_InitTypeDef      GPIO_InitStructure;

  8.   /* Enable ADC1, DMA2 and GPIO clocks ****************************************/
  9.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
  10.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  11.   
  12.   DMA_DeInit(DMA2_Stream0);
  13.        
  14.          
  15.   /* DMA2 Stream0 channel2 configuration **************************************/
  16.   DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
  17.   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
  18.   DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
  19.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  20.   DMA_InitStructure.DMA_BufferSize = SAMPLEING_POINTS;
  21.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  22.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//DMA_MemoryInc_Disable;
  23.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  24.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  25.   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA_Mode_Normal;//
  26.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  27.   DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  28.   DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  29.   DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  30.   DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  31.   DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  32.   DMA_Cmd(DMA2_Stream0, ENABLE);
  33.         DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
  34. }
  35. void DMA2_Stream0_IRQHandler(void)
  36. {
  37.    
  38. //if (DMA_GetFlagStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET)
  39. if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET)
  40. {
  41.   DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
  42.   //DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF0);
  43.         //DMA_Cmd(DMA2_Stream0, DISABLE);
  44.         ADC_SoftwareStartConvCmd(ADC1,DISABLE);
  45.   DMA_Cmd(DMA2_Stream0, DISABLE);

  46.         DMARecFlag=1;
  47.        
  48. }
  49.        
  50. }
  51. void DMAReConfig(void)
  52. {
  53. DMA_DeInit(DMA2_Stream0);
  54. DMA_InitStructure.DMA_BufferSize = SAMPLEING_POINTS;
  55. DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  56. DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
  57. DMA_Cmd(DMA2_Stream0, ENABLE);
  58. }
  1. while (1)
  2.   {
  3.     #ifdef PRINT_ON_LCD
  4.     /* Display ADC converted value on LCD */
  5.         Display(max,max_position);
  6.     #endif
  7.                 //ADC_Cmd(ADC1, ENABLE);
  8.                 if (ADCStartFlag==1)
  9.     {
  10.                  //DMA_Config();
  11.                  //DMA2_Stream0->CNDTR = 0x00000064;
  12.                  //ADC_Config();       
  13.            //DMA_Cmd(DMA2_Stream0, ENABLE);         
  14.                  //ADC_DMACmd(ADC1, ENABLE);
  15.                  //ADC_Cmd(ADC1, ENABLE);
  16.                  ADC_SoftwareStartConvCmd(ADC1,ENABLE);//¿ªÊ¼²É¼¯
  17.                
  18.                  ADCStartFlag=0;
  19.            while(DMARecFlag==1) //´«Êä½áÊø£¬½øÐмÆËã
  20.      {
  21.                          DMARecFlag=0;
  22.                         //ADC_Cmd(ADC1, DISABLE);
  23.                          //ADC_SoftwareStartConvCmd(ADC1,DISABLE);
  24.                          //DMA_Cmd(DMA2_Stream0, DISABLE);
  25.                          DMAReConfig();
  26.                         // DMA_Config();
  27.                        
  28.                    max=0;
  29.                      for(i=0;i<SAMPLEING_POINTS ;i++)
  30.                        {
  31.                                      if (ADC1ConvertedValue[i]>max)
  32.                                    {  max=ADC1ConvertedValue[i];
  33.                                             max_position=i;
  34.                                    }
  35.                        }
  36.                   j=max;
  37.                         //break;
  38.       }      
  39.     }
  40.         }
 楼主| lee_hwa 发表于 2013-12-18 10:19 | 显示全部楼层
lee_hwa 发表于 2013-12-18 10:18
请各位专家指点一下:

while里break没有注释掉。代码里是错的。
ticomi 发表于 2013-12-18 12:30 | 显示全部楼层
lee_hwa 发表于 2013-12-18 09:49
你的是STM32F407么

是的407
ticomi 发表于 2013-12-18 12:32 | 显示全部楼层
lee_hwa 发表于 2013-12-18 09:56
DMA_SetCurrDataCounter(DMA2_Stream0, ADC_RX_SIZE)可以  Enable DMA2 Stream0     是什么道理? ADC_RX_S ...

这个是每次启动DMA接收数据前需要设置的接收量,ADC_RX_SIZE是DMA的读取数据量,如果每次都是读取一样的数据量,可以不用每次设置一次。
//YZC 发表于 2013-12-18 13:33 | 显示全部楼层
每次开启DMA之前,先关闭下DMA,重新写下传输地址和传输长度
 楼主| lee_hwa 发表于 2013-12-19 09:10 | 显示全部楼层
ticomi 发表于 2013-12-18 12:32
这个是每次启动DMA接收数据前需要设置的接收量,ADC_RX_SIZE是DMA的读取数据量,如果每次都是读取一样的 ...

1.DMA_SetCurrDataCounter(DMA2_Stream0, ADC_RX_SIZE)后使用DMA_Cmd(DMA2_Stream0, ENABLE)么?
2.你的外设是AD么,不是的话,是什么呀?
 楼主| lee_hwa 发表于 2013-12-19 09:10 | 显示全部楼层
//YZC 发表于 2013-12-18 13:33
每次开启DMA之前,先关闭下DMA,重新写下传输地址和传输长度

我每次都关闭,然后重新congfig都不行。
ticomi 发表于 2013-12-19 09:24 | 显示全部楼层
lee_hwa 发表于 2013-12-19 09:10
1.DMA_SetCurrDataCounter(DMA2_Stream0, ADC_RX_SIZE)后使用DMA_Cmd(DMA2_Stream0, ENABLE)么?
2.你的 ...

外设是ADC,高速ADC。这段代码是在DMA采集完成的中断里实现的。
先关闭DMA的接收和发送通道,然后清除对应的中断

做相应的工作后决定再次启动DMA前,需要重新配置和使能DMA的,如代码段。

这里我想说明下的是,如果你使用DMA配合SPI读取ADC数据的话,一定是要采用DMA来通过SPI发送数据,否则是读取不到数据的,也会出现各种莫名其妙的问题。所以一定要配置两个DMA Stream,一个属于发送数据,一个属于接收SPI的数据。
//YZC 发表于 2013-12-19 13:52 | 显示全部楼层
lee_hwa 发表于 2013-12-19 09:10
我每次都关闭,然后重新congfig都不行。

DMA没问题那就是外设的问题了,外设不工作DMA当然无法完成,为啥DMA完成中断里会有“ADC_SoftwareStartConvCmd(ADC1,DISABLE);”这一句?你的代码结构没怎么看清,或许是你对ADC的配置出了问题,根据我的经验,ADC初始化好后,启动和关闭DMA不需要再去配置ADC,楼主不妨找找外设上的原因
 楼主| lee_hwa 发表于 2013-12-19 17:28 | 显示全部楼层
//YZC 发表于 2013-12-19 13:52
DMA没问题那就是外设的问题了,外设不工作DMA当然无法完成,为啥DMA完成中断里会有“ADC_SoftwareStartCo ...

是呀,有的人不是说要先disable外设,在disable dma么。我觉得也有问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

147

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部