目的:通过DMA实现ADC1的通道1、2、3电压采集,对三个通道连续采集10次,采集的数据储存于一个二维数组中u16 uhADCxConvertedValue[10][3]。
现象:实际采集时,数组的前4个元素仅更新一次后不再更新,后面的数据可以正常更新,仿真结果如图:
DMA设置的memaddr跟数组地址是一致的,但是前4个数据不会更新。如果用一维数组u16 uhADCxConvertedValue[3]储存三个通道的数据就完全不更新了。贴出代码,求大佬们解答。
ADC配置代码如下:
/* ADC handler declaration */
ADC_HandleTypeDef AdcHandle;
/* Variable used to get converted value */
u16 uhADCxConvertedValue[10][3] = {0};
void bsp_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/*##-1- Configure the ADC peripheral #######################################*/
AdcHandle.Instance = ADC1;
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.ScanConvMode = ENABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.ContinuousConvMode = ENABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.NbrOfDiscConversion = 0;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Conversion start trigged at each external event */
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 3;
AdcHandle.Init.DMAContinuousRequests = ENABLE;
AdcHandle.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&AdcHandle);
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 2;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = 3;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
HAL_ADC_Start_DMA(&AdcHandle,(u32*)uhADCxConvertedValue,30);
}
/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example:
* - Peripheral's clock enable
* - Peripheral's GPIO Configuration
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
static DMA_HandleTypeDef hdma_adc;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* ADC1 Periph clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
/* Enable GPIO clock ****************************************/
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Enable DMA2 clock */
__HAL_RCC_DMA2_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* ADC Channel GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
/*##-3- Configure the DMA streams ##########################################*/
/* Set the parameters to be configured */
hdma_adc.Instance = DMA2_Stream0;
hdma_adc.Init.Channel = DMA_CHANNEL_0;
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc.Init.Mode = DMA_CIRCULAR;
hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&hdma_adc);
/* Associate the initialized DMA handle to the ADC handle */
__HAL_LINKDMA(hadc, DMA_Handle, hdma_adc);
/*##-4- Configure the NVIC for DMA #########################################*/
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 8);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
void DMA2_Stream0_IRQHandler(void)
{
HAL_DMA_IRQHandler(AdcHandle.DMA_Handle);
}
第二个问题在论坛里找到解决办法,需要关闭Cache再去读取,读取后再打开。
http://www.openedv.com/forum.php?mod=viewthread&tid=94381&extra=
一周热门 更多>