我们在使用F4的ADC功能是遇到如下问题:
1.我们使用ADC进行外部数据采集,启用ADC的DMA功能。
2.我们期望ADC的频率可控,采用TIM8作为ADC的触发,进行操作。
3.现在遇到如下问题:
当开启ADC、DMA和TIM8后,设备能够正确采样,但当我停止TIM8时,ADC和DMA并没有停止,还在不停的采集数据,TIM8没法控制ADC的采样。
初始化程序如下:
GPIO_InitTypeDef GPIO_InitStruct;
ADC_ChannelConfTypeDef sConfig;
xSemaphoreDataRdyIRQ = xSemaphoreCreateBinary ();
/* Create the queues used to hold Rx/Tx characters. */
if (xSemaphoreDataRdyIRQ == NULL)
{
Error_Handler ();
}
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable GPIO clock */
ADCx_CHANNEL_GPIO_CLK_ENABLE();
/* ADC3 Periph clock enable */
ADCx_CLK_ENABLE();
/* Enable DMA2 clock */
_DMAx_CLK_ENABLE()
;
/*##-2- Configure peripheral GPIO ##########################################*/
/* ADC3 Channel8 GPIO pin configuration */
GPIO_InitStruct.Pin = ADCx_CHANNEL_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init (ADCx_CHANNEL_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the DMA streams ##########################################*/
/* Set the parameters to be configured */
rxDmaHandle.Instance =ADCx_DMA_STREAM;
rxDmaHandle.Init.Channel = ADCx_DMA_CHANNEL;
rxDmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
rxDmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
rxDmaHandle.Init.MemInc = DMA_MINC_ENABLE;
rxDmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
rxDmaHandle.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD;
rxDmaHandle.Init.Mode = DMA_CIRCULAR;
rxDmaHandle.Init.Priority = DMA_PRIORITY_HIGH;
rxDmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
rxDmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
rxDmaHandle.Init.MemBurst = DMA_MBURST_SINGLE;
rxDmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init (&rxDmaHandle);
/* Associate the initialized DMA handle to the the ADC handle */
__HAL_LINKDMA(&rxHwAdc, DMA_Handle, rxDmaHandle);
/*##-4- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority (ADCx_DMA_IRQn, 2, 2);
HAL_NVIC_EnableIRQ (ADCx_DMA_IRQn);
/*##-1- Configure the ADC peripheral #######################################*/
rxHwAdc.Instance = ADCx;
rxHwAdc.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
rxHwAdc.Init.Resolution = ADC_RESOLUTION_12B;
rxHwAdc.Init.ScanConvMode = DISABLE;
rxHwAdc.Init.ContinuousConvMode = ENABLE;
rxHwAdc.Init.DiscontinuousConvMode = DISABLE;
rxHwAdc.Init.NbrOfDiscConversion = 0;
rxHwAdc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
rxHwAdc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T8_TRGO;
rxHwAdc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
rxHwAdc.Init.NbrOfConversion = 1;
rxHwAdc.Init.DMAContinuousRequests = ENABLE;
rxHwAdc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if (HAL_ADC_Init (&rxHwAdc) != HAL_OK)
{
/* Initialization Error */
Error_Handler ();
}
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADCx_CHANNEL;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel (&rxHwAdc, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
Error_Handler ();
}
#if USE_RING_BUFF
ringBufferInit (&adcBufRing);
#endif
/*TIMER Trigger*/
TIM_MasterConfigTypeDef sMasterConfig;
__HAL_RCC_TIM8_CLK_ENABLE();
/* Time Base configuration TIM8 APB2*/
adcTriggerTm.Instance = TIM8;
adcTriggerTm.Init.Period = P0_ADC_RATE;
adcTriggerTm.Init.Prescaler = PSC_REG_ADCT-1;
adcTriggerTm.Init.ClockDivision = 0;
adcTriggerTm.Init.CounterMode = TIM_COUNTERMODE_UP;
adcTriggerTm.Init.RepetitionCounter = 0;
if(HAL_TIM_Base_Init(&adcTriggerTm) != HAL_OK)
{
/* TIM8 Initialization Error */
Error_Handler();
}
/* TIM8 TRGO selection */
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if(HAL_TIMEx_MasterConfigSynchronization(&adcTriggerTm, &sMasterConfig) != HAL_OK)
{
/* TIM8 TRGO selection Error */
Error_Handler();
} |