How to used ADC injection in the LL library
1. Initialize the sequence table
(0) SystemClock_Config (); // 初始化外部时钟,分配总线频率和ADC频率
(1) Configure_DMA (); // 初始化 规则组DMA设置,也可以不使用DMA功能
(2) Configure_TIM_TimeBase_ADC_trigger (); // 创建ADC采样触发脉冲定时器 , 按照规定时间触发ADC采样
(3) Configure_ADC (); // 初始化ADC各类功能 例如规则组 注入组 转换周期 循环方式等
(4) Activate_ADC(); // 执行ADC激活程序 使其准备转换
2. ADC features detailed configuration
(-1) 设定基础数组
/* Init variable out of expected ADC conversion data range */
#define VAR_CONVERTED_DATA_INIT_VALUE (__LL_ADC_DIGITAL_SCALE(LL_ADC_RESOLUTION_12B) + 1)
/* ADC转换数据的变量 */
__IO uint16_t aADCxConvertedData [ADC_CONVERTED_DATA_BUFFER_SIZE]; /* ADC组规则转换数据 */
__IO uint16_t uhADCxGrpInjectedConvertedData = VAR_CONVERTED_DATA_INIT_VALUE; /* ADC组注入转换数据 */
(0) 初始化GPIO时钟和功能 例如:
/* Enable GPIO Clock */
LL_AHB1_GRP1_EnableClock (LL_AHB1_GRP1_PERIPH_GPIOA);
/* Configure GPIO in analog mode to be used as ADC input */
LL_GPIO_SetPinMode (GPIOA, LL_GPIO_PIN_4, LL_GPIO_MODE_ANALOG);
(1) 初始化ADC中断配置 DMA配置
/* Configure NVIC to enable ADC2 interruptions */
NVIC_SetPriority (ADC1_2_IRQn, 0);
NVIC_EnableIRQ (ADC1_2_IRQn);
/* 设置DMA终端优先级 使能DMA中断 */
NVIC_SetPriority (DMA1_Channel2_IRQn, 0);
NVIC_EnableIRQ (DMA1_Channel2_IRQn);
/* 使能DMA时钟 */
LL_AHB1_GRP1_EnableClock (LL_AHB1_GRP1_PERIPH_DMA1);
/* ## 配置 DMA 传输 ## */
/* - DMA传输在循环模式: */
/* DMA无限制请求。 */
/* - 从ADC的DMA传输没有地址增量。 */
/* - DMA转移到内存的地址增量。 */
/* - DMA传输从ADC半字匹配ADC配置: */
/* ADC分辨率12位。 */
/* - DMA传输方向:ADC->RAM */
/* 缓冲区变量类型:半字。 */
LL_DMA_ConfigTransfer (DMA1, LL_DMA_CHANNEL_2,
LL_DMA_DIRECTION_PERIPH_TO_MEMORY |
LL_DMA_MODE_CIRCULAR |
LL_DMA_PERIPH_NOINCREMENT |
LL_DMA_MEMORY_INCREMENT |
LL_DMA_PDATAALIGN_HALFWORD |
LL_DMA_MDATAALIGN_HALFWORD |
LL_DMA_PRIORITY_HIGH);
/* 设置源和目的的DMA传输地址 */
LL_DMA_ConfigAddresses (DMA1, LL_DMA_CHANNEL_2,
LL_ADC_DMA_GetRegAddr (ADC2, LL_ADC_DMA_REG_REGULAR_DATA),
(uint32_t) &aADCxConvertedData, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
/* 设置DMA传输数量 */
LL_DMA_SetDataLength (DMA1, LL_DMA_CHANNEL_2, ADC_CONVERTED_DATA_BUFFER_SIZE);
/* 启用DMA传输:传输完成中断 */
LL_DMA_EnableIT_TC (DMA1, LL_DMA_CHANNEL_2);
/* 启用DMA中断:传输过半中断 */
LL_DMA_EnableIT_HT (DMA1, LL_DMA_CHANNEL_2);
/* 启用DMA传输:传输错误中断 */
LL_DMA_EnableIT_TE (DMA1, LL_DMA_CHANNEL_2);
/*## Activation of DMA ## 激活DMA */
/* 使能DMA传输通道 */
LL_DMA_EnableChannel (DMA1, LL_DMA_CHANNEL_2);
(2) 初始化ADC时钟和功能
/* Enable ADC clock (core clock) */
LL_AHB1_GRP1_EnableClock (LL_AHB1_GRP1_PERIPH_ADC12);
if (__LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE() == 0)
{
LL_ADC_SetCommonClock (__LL_ADC_COMMON_INSTANCE(ADC2), LL_ADC_CLOCK_SYNC_PCLK_DIV4);
/* 设置ADC引脚到内部采样通道 */
LL_ADC_SetCommonPathInternalCh (__LL_ADC_COMMON_INSTANCE(ADC2), LL_ADC_PATH_INTERNAL_VREFINT);
}
if ((LL_ADC_IsEnabled (ADC2) == 0) || (LL_ADC_REG_IsConversionOngoing (ADC2) == 0))
{
/* 设置ADC组定时触发源 */
LL_ADC_REG_SetTriggerSource (ADC2, LL_ADC_REG_TRIG_EXT_TIM2_TRGO);
/* 设置ADC组定时触发源 参数: 上升沿/下降沿/上升沿+下降沿 */
//LL_ADC_REG_SetTriggerEdge(ADC2, LL_ADC_REG_TRIG_EXT_RISING);
/* 设置ADC组规则连续模式 参数:单次/连续 */
LL_ADC_REG_SetContinuousMode (ADC2, LL_ADC_REG_CONV_SINGLE);
/* 设定ADC组定期转换数据传输 参数: DMA模式 NONE/单次/循环 */
LL_ADC_REG_SetDMATransfer (ADC2, LL_ADC_REG_DMA_TRANSFER_UNLIMITED);
/* 设置ADC组常规溢出行为 参数: 数据覆盖*/
LL_ADC_REG_SetOverrun (ADC2, LL_ADC_REG_OVR_DATA_OVERWRITTEN);
/* 设置ADC组规则序列长度和扫描方向 */
LL_ADC_REG_SetSequencerLength (ADC2, LL_ADC_REG_SEQ_SCAN_DISABLE);
/* 设置ADC组规则序列断续模式 */
// LL_ADC_REG_SetSequencerDiscont(ADC2, LL_ADC_REG_SEQ_DISCONT_DISABLE);
/* 设置ADC组规则序列: 通道和顺序 */
LL_ADC_REG_SetSequencerRanks (ADC2, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_1);
}
if ((LL_ADC_IsEnabled (ADC2) == 0) || (LL_ADC_INJ_IsConversionOngoing (ADC2) == 0))
{
/* 设置插入组 */
LL_ADC_INJ_ConfigQueueContext (ADC2,LL_ADC_INJ_TRIG_SOFTWARE,LL_ADC_INJ_TRIG_EXT_RISING,
LL_ADC_INJ_SEQ_SCAN_DISABLE,
LL_ADC_CHANNEL_VREFINT, LL_ADC_CHANNEL_0,
LL_ADC_CHANNEL_0,LL_ADC_CHANNEL_0);
}
if ((LL_ADC_IsEnabled (ADC2) == 0)
|| ((LL_ADC_REG_IsConversionOngoing (ADC2) == 0)
&& (LL_ADC_INJ_IsConversionOngoing (ADC2) == 0)))
{
/* 设置采样通道和周期 */
LL_ADC_SetChannelSamplingTime (ADC2, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_19CYCLES_5);
LL_ADC_SetChannelSamplingTime (ADC2, LL_ADC_CHANNEL_VREFINT, LL_ADC_SAMPLINGTIME_181CYCLES_5);
}
/* 启用中断ADC组常规溢出 */
LL_ADC_EnableIT_OVR (ADC2);
/* 使中断ADC组注入转换 */
LL_ADC_EnableIT_JEOC (ADC2);
(3) 激活ADC
if (LL_ADC_IsEnabled (ADC2) == 0)
{
/* 启用ADC内部电压调整器 */
LL_ADC_EnableInternalRegulator (ADC2);
SystemCoreClock=64000000;
wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
while (wait_loop_index != 0)
{
wait_loop_index--;
}
/* 运行ADC 自校准 */
LL_ADC_StartCalibration (ADC2, LL_ADC_SINGLE_ENDED);
/* 在自校准后需要延迟一段时间 */
wait_loop_index = (ADC_DELAY_CALIB_ENABLE_CPU_CYCLES >> 1);
while (wait_loop_index != 0)
{
wait_loop_index--;
}
/* 使能 ADC */
LL_ADC_Enable (ADC2);