STM32F407 ADC双通道同时采样

#include "stm32f4xx.h"
#define ADC_CDR_ADDRESS ((uint32_t)0x40012308)
#define ADC12_BUFFER_SIZE  16380
#define ADC_SAMPLE_FREQUENCY 10 //10HZ  这个采样频率的意思是 100ms采样完16380个点
uint32_t SampleSuccessFlag   = 0;   //采样成功标志位
__IO uint32_t ADC12ConvertedValue[ADC12_BUFFER_SIZE];//高16位保存ADC2的值,低16位保存低ADC1的值

//我的开发板的时钟频率为144M,而TIM3的频率为72M
static void TIM3_Config(void) 
{  
    TIM_TimeBaseInitTypeDef timer_init_structure;
	  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);            //使能TIM3时钟    
    TIM_DeInit(TIM3);                                               //复位TIM3    
    timer_init_structure.TIM_ClockDivision = TIM_CKD_DIV1;          //系统时钟
    timer_init_structure.TIM_CounterMode = TIM_CounterMode_Up;      //向上计数模式  
    timer_init_structure.TIM_Period = ( 2000000/(ADC_SAMPLE_FREQUENCY*ADC12_BUFFER_SIZE) )-1;                        
    timer_init_structure.TIM_Prescaler = 36 - 1;                      //计数时钟预分频
    TIM_TimeBaseInit(TIM3, &timer_init_structure);
  	
    TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
    TIM_Cmd(TIM3, ENABLE);                                          //使能TIM3  
}
/*******************************************************************************
 * Function Name  : ADC12_Init
 * Description    : 
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
void ADC12_Init(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;
  NVIC_InitTypeDef      NVIC_InitStructure;

  /* Enable ADC1, DMA2 and GPIO clocks ****************************************/
  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);

  /* DMA2 Stream0 channel0 configuration **************************************/
  DMA_DeInit(DMA2_Stream0);
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC12ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = ADC12_BUFFER_SIZE;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;         
  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);
  DMA_Cmd(DMA2_Stream0, ENABLE);

  /* Enable DMA2_Stream0 Transfer complete interrupt */
  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);

  /* Enable DMA2_Stream0 IRQn Interrupt ***************************************/
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Configure ADC1 Channel0 pin as analog input ******************************/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* Configure ADC2 Channel5 pin as analog input ******************************/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* ADC Common Init **********************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_InjecSimult; //双通道注入模式
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;	// ( 12 + 5 + 3 ) = 20
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC1 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;//ADC_ExternalTrigConv_T3_TRGO;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_Init(ADC2, &ADC_InitStructure);

  /* ADC1 regular channel8 configuration *************************************/
  ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_3Cycles);

  /* ADC2 regular channel5 configuration *************************************/
  ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);


  /* Enable DMA request after last transfer (multi-ADC mode) ******************/
  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE); 

  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);

}

/*******************************************************************************
 * Function Name  : adc_init
 * Description    : 
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
void adc_init(void)
{
	ADC12_Init();		
	TIM3_Config();		
}
/*******************************************************************************
 * Function Name  : DMA2_Stream0_IRQHandler
 * Description    : 
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
void DMA2_Stream0_IRQHandler(void)
{
  if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
  { 
        TIM_Cmd(TIM3, DISABLE);
        SampleSuccessFlag = 1;	
  }
}



解释-----------------------------
调用函数adc_init后,将开始采样,当采样完ADC12_BUFFER_SIZE(16380)个点后,进入DMA2_Stream0_IRQHandler中断函数,然后失能定时器3也就停止采样了,将采样成功标志位SampleSuccessFlag置1,我们可以在主函数while循环中判断SampleSuccessFlag是否为1,为1后就可以对采样值ADC12ConvertedValue[ADC12_BUFFER_SIZE]进行相应的处理了。若要再次采样,调用TIM_Cmd(TIM3, ENABLE)即可。


这是我们使用wpf做的上位机软件,显示采样到的双通道波形:

STM32F407 ADC双通道同时采样_第1张图片



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