|
1、自动连续采集 dma多通道
static FunctionalState bContinueConvert = ENABLE;
/*******************************************************************************
* 函数名 : Bsp_Adc1Init
* 描 述 : ADC1采样初始化
* 输 入 : 无
* 输 出 : 无
* 返回值 : OSA_SOK : 成功
* OSA_EFAIL: 失败
*******************************************************************************/
Int32 Bsp_Adc1Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
__HAL_RCC_ADC12_CLK_ENABLE();
/* ADC Periph interface clock configuration */
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);
s_adc1Handle.Instance = ADC1;
if (HAL_ADC_DeInit(&s_adc1Handle) != HAL_OK)
{
/* ADC de-initialization Error */
printf("Adc1Init DeInit error!!!\r\n");
}
memset((void*)&s_ADC1ConvertedData[0],0xff,sizeof(s_ADC1ConvertedData));
if (s_ValidAdc1ChnNum <= 0)
{
printf("Adc1Init adc chn no config error!!!\r\n");
return OSA_EFAIL;
}
__HAL_RCC_DMA1_CLK_ENABLE();
s_hdma_adc1.Instance = DMA1_Stream1;
s_hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
s_hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
s_hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
s_hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
s_hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
s_hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
//连续转换模式需要开启循环模式
if (ENABLE == bContinueConvert)
{
s_hdma_adc1.Init.Mode = DMA_CIRCULAR;
}
else
{
s_hdma_adc1.Init.Mode = DMA_NORMAL;
}
s_hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
s_hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
/* Deinitialize & Initialize the DMA for new transfer */
HAL_DMA_DeInit(&s_hdma_adc1);
if (HAL_DMA_Init(&s_hdma_adc1)!= HAL_OK)
{
printf("Adc1Init adc DMA init error!!!\r\n");
return OSA_EFAIL;
}
__HAL_LINKDMA(&s_adc1Handle,DMA_Handle,s_hdma_adc1);
/* NVIC configuration for DMA Input data interrupt */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
s_adc1Handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; /* Asynchronous clock mode, input ADC clock divided by 2*/
s_adc1Handle.Init.Resolution = ADC_RESOLUTION_12B; /* 16-bit resolution for converted data */
s_adc1Handle.Init.ScanConvMode = ENABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
s_adc1Handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */
s_adc1Handle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
s_adc1Handle.Init.ContinuousConvMode = bContinueConvert; /* Continuous mode enabled (automatic conversion restart after each conversion) */
s_adc1Handle.Init.NbrOfConversion = s_ValidAdc1ChnNum; /* Parameter discarded because sequencer is disabled */
s_adc1Handle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
s_adc1Handle.Init.NbrOfDiscConversion = s_ValidAdc1ChnNum; /* Parameter discarded because sequencer is disabled */
s_adc1Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
s_adc1Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
if (ENABLE == bContinueConvert)
{
s_adc1Handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; /* DMA circular mode selected */
}
else
{
s_adc1Handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT; /* DMA one shot mode selected */
}
s_adc1Handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */
s_adc1Handle.Init.OversamplingMode = DISABLE; /* No oversampling */
/* Initialize ADC peripheral according to the passed parameters */
if (HAL_ADC_Init(&s_adc1Handle) != HAL_OK)
{
printf("Adc1Init error!!!\r\n");
return OSA_EFAIL;
}
/* ### - 2 - Start calibration ############################################ */
if (HAL_ADCEx_Calibration_Start(&s_adc1Handle, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED) != HAL_OK)
{
printf("Adc1Init Calibration error!!!\r\n");
}
/* ### - 3 - Channel configuration ######################################## */
for (Int32 chn = 0; chn < BSP_ADC_MAX_CHN && chn < s_ValidAdc1ChnNum; chn++)
{
if (s_LogicMapAdc1Chn[chn] == 0xFFFFFFFF)
{
continue;
}
sConfig.Channel = s_LogicMapAdc1Chn[chn]; /* Sampled channel number */
sConfig.Rank = s_LogicMapAdc1RankNo[chn]; /* Rank of sampled channel number ADCx_CHANNEL */
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5; /* Sampling time (number of clock cycles unit) */
sConfig.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */
sConfig.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */
sConfig.Offset = 0; /* Parameter discarded because offset correction is disabled */
if (HAL_ADC_ConfigChannel(&s_adc1Handle, &sConfig) != HAL_OK)
{
printf("Adc1Init Calibration logicchn:%d,adcChn:%d,error!!!\r\n",chn,s_LogicMapAdc1Chn[chn]);
}
}
//使能ADC1
ADC_Enable(&s_adc1Handle);
if (ENABLE == bContinueConvert)
{
HAL_ADC_Start_DMA(&s_adc1Handle, (Uint32 *)s_ADC1ConvertedData, s_ValidAdc1ChnNum);
}
printf("Adc1Init ChnNum=%d ok!!!\r\n",s_ValidAdc1ChnNum);
return OSA_SOK;
}
采集的值
[16_35_07_982]adc1 chn0 adcVaule:00072,0.052368 V
[16_35_07_993]adc1 chn1 adcVaule:00078,0.057202 V
[16_35_07_993]adc1 chn2 adcVaule:00133,0.097485 V
[16_35_07_993]adc1 chn3 adcVaule:00004,0.000000 V
2、单次采集 dma 多通道
static FunctionalState bContinueConvert = DISABLE;
/*******************************************************************************
* 函数名 : Bsp_Adc1Init
* 描 述 : ADC1采样初始化
* 输 入 : 无
* 输 出 : 无
* 返回值 : OSA_SOK : 成功
* OSA_EFAIL: 失败
*******************************************************************************/
Int32 Bsp_Adc1Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
__HAL_RCC_ADC12_CLK_ENABLE();
/* ADC Periph interface clock configuration */
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);
s_adc1Handle.Instance = ADC1;
if (HAL_ADC_DeInit(&s_adc1Handle) != HAL_OK)
{
/* ADC de-initialization Error */
printf("Adc1Init DeInit error!!!\r\n");
}
memset((void*)&s_ADC1ConvertedData[0],0xff,sizeof(s_ADC1ConvertedData));
if (s_ValidAdc1ChnNum <= 0)
{
printf("Adc1Init adc chn no config error!!!\r\n");
return OSA_EFAIL;
}
__HAL_RCC_DMA1_CLK_ENABLE();
s_hdma_adc1.Instance = DMA1_Stream1;
s_hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
s_hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
s_hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
s_hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
s_hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
s_hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
//连续转换模式需要开启循环模式
if (ENABLE == bContinueConvert)
{
s_hdma_adc1.Init.Mode = DMA_CIRCULAR;
}
else
{
s_hdma_adc1.Init.Mode = DMA_NORMAL;
}
s_hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
s_hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
/* Deinitialize & Initialize the DMA for new transfer */
HAL_DMA_DeInit(&s_hdma_adc1);
if (HAL_DMA_Init(&s_hdma_adc1)!= HAL_OK)
{
printf("Adc1Init adc DMA init error!!!\r\n");
return OSA_EFAIL;
}
__HAL_LINKDMA(&s_adc1Handle,DMA_Handle,s_hdma_adc1);
/* NVIC configuration for DMA Input data interrupt */
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
s_adc1Handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; /* Asynchronous clock mode, input ADC clock divided by 2*/
s_adc1Handle.Init.Resolution = ADC_RESOLUTION_12B; /* 16-bit resolution for converted data */
s_adc1Handle.Init.ScanConvMode = ENABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
s_adc1Handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; /* EOC flag picked-up to indicate conversion end */
s_adc1Handle.Init.LowPowerAutoWait = DISABLE; /* Auto-delayed conversion feature disabled */
s_adc1Handle.Init.ContinuousConvMode = bContinueConvert; /* Continuous mode enabled (automatic conversion restart after each conversion) */
s_adc1Handle.Init.NbrOfConversion = s_ValidAdc1ChnNum; /* Parameter discarded because sequencer is disabled */
s_adc1Handle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
s_adc1Handle.Init.NbrOfDiscConversion = s_ValidAdc1ChnNum; /* Parameter discarded because sequencer is disabled */
s_adc1Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
s_adc1Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because software trigger chosen */
if (ENABLE == bContinueConvert)
{
s_adc1Handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR; /* DMA circular mode selected */
}
else
{
s_adc1Handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT; /* DMA one shot mode selected */
}
s_adc1Handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; /* DR register is overwritten with the last conversion result in case of overrun */
s_adc1Handle.Init.OversamplingMode = DISABLE; /* No oversampling */
/* Initialize ADC peripheral according to the passed parameters */
if (HAL_ADC_Init(&s_adc1Handle) != HAL_OK)
{
printf("Adc1Init error!!!\r\n");
return OSA_EFAIL;
}
/* ### - 2 - Start calibration ############################################ */
if (HAL_ADCEx_Calibration_Start(&s_adc1Handle, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED) != HAL_OK)
{
printf("Adc1Init Calibration error!!!\r\n");
}
/* ### - 3 - Channel configuration ######################################## */
for (Int32 chn = 0; chn < BSP_ADC_MAX_CHN && chn < s_ValidAdc1ChnNum; chn++)
{
if (s_LogicMapAdc1Chn[chn] == 0xFFFFFFFF)
{
continue;
}
sConfig.Channel = s_LogicMapAdc1Chn[chn]; /* Sampled channel number */
sConfig.Rank = s_LogicMapAdc1RankNo[chn]; /* Rank of sampled channel number ADCx_CHANNEL */
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5; /* Sampling time (number of clock cycles unit) */
sConfig.SingleDiff = ADC_SINGLE_ENDED; /* Single-ended input channel */
sConfig.OffsetNumber = ADC_OFFSET_NONE; /* No offset subtraction */
sConfig.Offset = 0; /* Parameter discarded because offset correction is disabled */
if (HAL_ADC_ConfigChannel(&s_adc1Handle, &sConfig) != HAL_OK)
{
printf("Adc1Init Calibration logicchn:%d,adcChn:%d,error!!!\r\n",chn,s_LogicMapAdc1Chn[chn]);
}
}
//使能ADC1
ADC_Enable(&s_adc1Handle);
if (ENABLE == bContinueConvert)
{
HAL_ADC_Start_DMA(&s_adc1Handle, (Uint32 *)s_ADC1ConvertedData, s_ValidAdc1ChnNum);
}
printf("Adc1Init ChnNum=%d ok!!!\r\n",s_ValidAdc1ChnNum);
return OSA_SOK;
}
任务重 1秒执行一次 转换
/*******************************************************************************
* 函数名 : Bsp_Adc1StartConvert
* 描 述 : ADC1 转化 (软件手动执行转换)
* 输 入 : 无
* 输 出 : 无
* 返回值 : OSA_SOK : 成功
* OSA_EFAIL: 失败
*******************************************************************************/
Int32 Bsp_Adc1StartConvert(void)
{
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
static Int32 convertFlag = 0;
if (s_ValidAdc1ChnNum <= 0)
{
printf("Adc1 no Init!!!\r\n");
return OSA_EFAIL;
}
/*自动连续模式 直接退出*/
if (ENABLE == bContinueConvert)
{
return OSA_SOK;
}
Bsp_Adc1DebugInfo();
//软件触发ADC采样
tmp_hal_status = HAL_ADC_Start_DMA(&s_adc1Handle, (Uint32 *)s_ADC1ConvertedData, s_ValidAdc1ChnNum);
printf("Adc1 Convert ret=%d!!!\r\n",tmp_hal_status);
return OSA_SOK;
}
转换结果
[16_32_08_201]adc1 chn0 adcVaule:00355,0.286011 V
[16_32_08_201]adc1 chn1 adcVaule:00352,0.283594 V
[16_32_08_212]adc1 chn2 adcVaule:00820,0.660645 V
[16_32_08_212]adc1 chn3 adcVaule:00000,0.000000 V
两种方式的结果 差别比较大 不知道为什么?
|
|