stm32f4 ADC DMA 模式 中断进不去解决

RT,分情况讨论 单ADC可以连续低速均匀采样数据处理、截断式高速均匀采样(高达36M/(3+6)),多ADC可以高速截断式高速均匀采样(高达36M/5)

参考资料:

http://download.csdn.net/detail/laoylhuli/4420045

http://www.fx114.net/qa-15-78897.aspx

应用笔记:STM32系列微控制器的ADC各模式说明及其应用例程  http://www.stmcu.org/document/list/index/sort-new/category-178?p=1

官方例程


单ADC 时,DMA采用normal模式,DMA进入TC中断后,需要做一下操作:

step1:关闭DMA

  step2: 重新初始化,使能DMA

  step3:清状态位,软件触发ADC


代码如下:

void DMA_slow_configure(){
      
  /* DMA2 Stream0 channel0 configuration */
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_CDR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCTripleConvertedValue_slow;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = SizeOfBuffer;   //  缓存
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  // 外设 数据 大小 字
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 存储 大小
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //   若用中断,则用一般模式, 若不用中断 则循环模式 !!!!!!!!!!!!!!
  DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 优先级 
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;  // 存储 是否 突发传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 外设 是否 突发传输
  DMA_Init(DMA2_Stream0, &DMA_InitStructure); 
//MemSize /PerSize * MemoryBurst 的倍数 = PerSize * PeripheralBurst的倍数

DMA_ClearFlag(DMA2_Stream0,DMA_IT_TC);
DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE); // 中断
  //* DMA2_Stream0 enable */
  DMA_Cmd(DMA2_Stream0, ENABLE);

}

void ADC_slow_configure(){

  /* ADC Common configuration *************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // !!!!!!!!!!
// ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; // 5--20个 单个adc连续转换,此设置无效
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; // !!!!!!!!!!!  
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;  // 分频  APB2/div =72 /div   
  ADC_CommonInit(&ADC_CommonInitStructure);


  ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; //  bit
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;      // 通道扫描
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  // 是否使能 连续采样 看情况
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;  // 通道数目
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_28Cycles);// 72M /ADC_Prescaler_Div8 /(28+12)
  ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE); //源数据变化时开启DMA传输

  ADC_DMACmd(ADC1, ENABLE);
  ADC_Cmd(ADC1, ENABLE);
    
  /* Start ADC1 Software Conversion */ 
 // ADC_SoftwareStartConv(ADC1);
}

void DMA2_Stream0_IRQHandler(void) 
{

if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
  {
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);

adc_sample=1;

 

}

int main(void)  // CPU 144 Mhz
{
GPIO_configure();
NVIC_config();
  USART6_Configuration();


DMA_slow_configure();
ADC_slow_configure();


ADC_SoftwareStartConv(ADC1);


 
while (1)
  {
  if(adc_sample){
  adc_sample=0;
DMA_Cmd(DMA2_Stream0, DISABLE);// DMA 配置时,按理说应该先停止dma  实测不停止也能工作
DMA_slow_configure();
ADC1->SR=0;  // 必不可少,位置必须在启动ADC前
ADC_SoftwareStartConv(ADC1); // 必不可少  
//单ADC非循环模式,若多ADC可以不需要重新启动


}
  }

}

三重ADC模式 ,高速率均匀,难以连续采样,变通地采一段进行处理后,再去采样。

文件见:http://download.csdn.net/detail/laoylhuli/4420045

注意点:三重ADC时,DMA中断后,重新开启ADC-DMA时,可以不做软件触发ADC,单ADC时,必须软件触发ADC :ADC_SoftwareStartConv(ADC1)。具体原因,待以后在研究。


你可能感兴趣的:(嵌入式)