1.在项目中配置头文件《rtconfig.h》需要添加硬件外设的使用定义
#define BSP_USING_ADC1
2.而在《adc_config.h》头文件中,针对L0系列的配置参数内容也有区别,如下调整后的ADC1_CONFIG为L0系列的,而ADC2_CONFIG则为原有L4系列的内容。
#ifdef BSP_USING_ADC1
#ifndef ADC1_CONFIG
#define ADC1_CONFIG \
{ \
.Instance = ADC1, \
.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1, \
.Init.OversamplingMode = DISABLE, \
.Init.Resolution = ADC_RESOLUTION_12B, \
.Init.SamplingTime = ADC_SAMPLETIME_12CYCLES_5, \
.Init.DataAlign = ADC_DATAALIGN_RIGHT, \
.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD, \
.Init.EOCSelection = ADC_EOC_SINGLE_CONV, \
.Init.LowPowerAutoWait = DISABLE, \
.Init.ContinuousConvMode = DISABLE, \
.Init.DiscontinuousConvMode = DISABLE, \
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
.Init.DMAContinuousRequests = DISABLE, \
.Init.Overrun = ADC_OVR_DATA_PRESERVED, \
.Init.LowPowerAutoWait = DISABLE, \
.Init.LowPowerFrequencyMode = DISABLE, \
.Init.LowPowerAutoPowerOff = DISABLE, \
}
#endif /* ADC1_CONFIG */
#endif /* BSP_USING_ADC1 */
#ifdef BSP_USING_ADC2
#ifndef ADC2_CONFIG
#define ADC2_CONFIG \
{ \
.Instance = ADC2, \
.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4, \
.Init.Resolution = ADC_RESOLUTION_12B, \
.Init.DataAlign = ADC_DATAALIGN_RIGHT, \
.Init.ScanConvMode = ADC_SCAN_DISABLE, \
.Init.EOCSelection = ADC_EOC_SINGLE_CONV, \
.Init.LowPowerAutoWait = DISABLE, \
.Init.ContinuousConvMode = DISABLE, \
.Init.NbrOfConversion = 1, \
.Init.DiscontinuousConvMode = DISABLE, \
.Init.NbrOfDiscConversion = 1, \
.Init.ExternalTrigConv = ADC_SOFTWARE_START, \
.Init.DMAContinuousRequests = DISABLE, \
.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN, \
}
#endif /* ADC2_CONFIG */
#endif /* BSP_USING_ADC2 */
3.对于《drv_adc.c》文件该文件L0系列没有,需要从L4系列中拷贝),同样有比较多的地方修改,以适应L071系列芯片
首先是通道数获取函数stm32_adc_get_channel,增加L0系列的宏定义
#if defined SOC_SERIES_STM32L0
# if defined (STM32L053xx) || defined (STM32L063xx) || defined (STM32L073xx) || defined (STM32L083xx)
case 16:
stm32_channel = ADC_CHANNEL_16;
break;
# endif
#endif
获取ADC值的函数stm32_get_adc_value需要添加L0系列预编译分支
#if defined(SOC_SERIES_STM32F1)
if (channel <= 17)
#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \
|| defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0)
if (channel <= 18)
#elif defined(SOC_SERIES_STM32L0)
if (channel <= 18)
#endif
同样在函数stm32_get_adc_value中,L0 的rank操作不一样的,需要增加L0的预编译定义
#if defined(SOC_SERIES_STM32L0)
ADC_ChanConf.Rank = ADC_RANK_CHANNEL_NUMBER;
#else
ADC_ChanConf.Rank = 1;
#endif
4.另外,注意打开hal_conf.h文件中的ADC选项
5.非常重要的一点,ST的驱动里面,关于通道channel的配置时,如果配置过一个通道,再去配置另一个通道,则会两个通道都打开,这时候,两个通道测试就会产生问题,即出现两个通道的值一样的情况(取了其中一个通道的值,取了哪个通道的值取决于采样转换是通道增序还是减序),根本原有在于驱动代码的HAL_ADC_ConfigChannel函数中,对通道的配置是采用或来取值了,如下
hadc->Instance->CHSELR |= (uint32_t)(sConfig->Channel & ADC_CHANNEL_MASK);
而实际使用时,又是一个通道一个通道来采样转换的,因此需要把“或”改成“等”,即:
hadc->Instance->CHSELR = (uint32_t)(sConfig->Channel & ADC_CHANNEL_MASK);
6.这时候如果直接使用,可能会出现实际值和ADC测量的值不准确的问题,这是由于ADC的误差造成的,ST的L071系列MCU支持了出厂校准,因此可以考虑在函数stm32_adc_init(void)中执行HAL_ADC_Init函数之后,做一次校准:
首先是在rtconfig.h头文件中添加BSP_ADC_CALIBRATION宏定义,然后在下面的HAL_ADC_Init函数成功之后执行一次校准
if (HAL_ADC_Init(&stm32_adc_obj[i].ADC_Handler) != HAL_OK)
{
LOG_E("%s init failed", name_buf);
result = -RT_ERROR;
}
else
{
#if defined(BSP_ADC_CALIBRATION) && defined(SOC_SERIES_STM32L0)
if( HAL_ADCEx_Calibration_Start( &stm32_adc_obj[i].ADC_Handler, ADC_SINGLE_ENDED ) != HAL_OK )
{
result = -RT_ERROR;
}
#endif
7.接下去就可以使用官方的ADC驱动demo的使用方式,使用ADC这部分的驱动,并且校准之后的ADC值也非常准确了,棒棒哒~~