你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F302 TIM15触发ADC规则扫描 DMA连续传输ADC数据失败

[复制链接]
c_lass 提问时间:2017-8-25 15:25 /
本帖最后由 c_lass 于 2017-8-25 15:32 编辑

        在测试STM32F302RB的ADC功能的时候遇到了问题:  用TIM15 更新事件作为 TRGO源 触发ADC2转换,DMA2_Channel_1 连续模式传输ADC2的数据,开DMA2_TC1中断,发现只进一次TC中断后就再也不进TC1中断了。 通过后续测试发现如果只用TIM15触发ADC转换,不开DMA 正常, 如果不用TIM15,用软件触发ADC转换,开DMA,正常 。  同时 用TIM15触发ADC、开DMA则出问题。      
        ADC初始化如下:
   ADC_DeInit(ADC2);
    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div6);                                 //72M/6=12M
    ADC_StructInit(&ADC_InitStructure);
   
    ADC_VoltageRegulatorCmd(ADC2, ENABLE);
  delay_us(10);
  ADC_SelectCalibrationMode(ADC2, ADC_CalibrationMode_Single);
  ADC_StartCalibration(ADC2);
  while(ADC_GetCalibrationStatus(ADC2) != RESET );
  calibration_value = ADC_GetCalibrationValue(ADC2);
   
    ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Clock=ADC_Clock_AsynClkMode;//ADC_Clock_SynClkModeDiv4;                //ʹÓÃͬ²½Ê±ÖÓ
    ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_1;             //12/10bitDMAģʽʹÄÜ
    ADC_CommonInitStructure.ADC_DMAMode=ADC_DMAMode_Circular;                  //Á¬Ðøģʽ
    ADC_CommonInitStructure.ADC_TwoSamplingDelay=0;                            //Á½´Î²ÉÑùÑÓʱ
    ADC_CommonInit(ADC2,&ADC_CommonInitStructure);
   
    ADC_InitStructure.ADC_ContinuousConvMode=ADC_ContinuousConvMode_Disable;//ADC_ContinuousConvMode_Enable;;
    ADC_InitStructure.ADC_AutoInjMode=ADC_AutoInjec_Disable;
    ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
  ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_14;//ADC_ExternalTrigConvEvent_0;//ADC_ExternalTrigConvEvent_0;   
    ADC_InitStructure.ADC_ExternalTrigEventEdge=ADC_ExternalTrigEventEdge_RisingEdge;//ADC_ExternalTrigEventEdge_None;
    ADC_InitStructure.ADC_NbrOfRegChannel=2;
    ADC_InitStructure.ADC_OverrunMode=ADC_OverrunMode_Disable;
    ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;
    ADC_Init(ADC2,&ADC_InitStructure);
   
    ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 1, ADC_SampleTime_4Cycles5);     
    ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_4Cycles5);   

    DMA_DeInit(DMA2_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&ADC2->DR);
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCBuffer;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                    //´ÓÍâÉè¶Á
  DMA_InitStructure.DMA_BufferSize = 2;                                //16
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                       //Á¬Ðø´«Êä
  DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA2_Channel1, &DMA_InitStructure);
   
    DMA_ITConfig(DMA2_Channel1,DMA2_IT_TC1,ENABLE);
    NVIC_InitStructure.NVIC_IRQChannel=DMA2_Channel1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
   
    ADC_ITConfig(ADC2,ADC_IT_EOC,ENABLE);
    NVIC_InitStructure.NVIC_IRQChannel=ADC1_2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);
   
    DMA_Cmd(DMA2_Channel1, ENABLE);
    ADC_DMACmd(ADC2, ENABLE);

    ADC_Cmd(ADC2, ENABLE);
    while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_RDY));
  ADC_StartConversion(ADC2);


中断如下: void DMA2_Channel1_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA2_IT_TC1) != RESET)
    {
        DMA_ClearITPendingBit(DMA2_IT_TC1);
    }
}

TIM15初始化如下:
  TIM_DeInit(TIM15);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE );//TIM1ʱÖÓʹÄÜ
   
   
    PrescalerValue = (uint16_t)( 7200 )- 1;             //Fcnt=1M

  TIM_TimeBaseStructure.TIM_Period = 10000;             //  500usת»»Ò»´Î
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
  TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure);
  TIM_PrescalerConfig(TIM15, PrescalerValue, TIM_PSCReloadMode_Immediate);
    TIM_SelectOutputTrigger(TIM15,TIM_TRGOSource_Update);
   
  TIM_ITConfig(TIM15,TIM_IT_Update, ENABLE);
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_TIM15_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  TIM_Cmd(TIM15, ENABLE);
我是使用TIM15 更新作为TRGO事件触发ADC2转换, TIM15 1秒钟更新一次,开 ADC EOC中断的debug的时候
是1秒钟进一次中断,然后使能DMA后就并开DMA中断后就只进一次中断了, 后续我又测试500ms软件触发一次ADC转换,并且开DMA,DMA中断符合预期结果。 然后我同时使用TIM15,DMA则 只进一次DMA中断。  我后续又修改了DMA_BUF_SIZE  改成8,以此来排除ADC初始化的那一次软件使能ADC转换, 就是要发生8次 ADC->EOC 才算一次 DMA_TC,结果还是只有一次DMA中断。




收藏 2 评论0 发布时间:2017-8-25 15:25

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版