在测试
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中断。