/******************************************************************************* * 函数名称: ADC_InjectedChannelConfig * 功能描述: 配置选中的ADC注入信道相应的音序器(sequencer)等级和采样时间。 * 输入参数: (1)ADCx:其中x可以是1、2或3,用来选择ADC外围模块. * (2)ADC_Channel: 需要配置的ADC信道. * ADC_Channel 可能的取值: * - ADC_Channel_0: ADC信道0被选择 * - ADC_Channel_1: ADC信道1被选择 * - ADC_Channel_2: ADC信道2被选择 * - ADC_Channel_3: ADC信道3被选择 * - ADC_Channel_4: ADC信道4被选择 * - ADC_Channel_5: ADC信道5被选择 * - ADC_Channel_6: ADC信道6被选择 * - ADC_Channel_7: ADC信道7被选择 * - ADC_Channel_8: ADC信道8被选择 * - ADC_Channel_9: ADC信道9被选择 * - ADC_Channel_10: ADC信道10被选择 * - ADC_Channel_11: ADC信道11被选择 * - ADC_Channel_12: ADC信道12被选择 * - ADC_Channel_13: ADC信道13被选择 * - ADC_Channel_14: ADC信道14被选择 * - ADC_Channel_15: ADC信道15被选择 * - ADC_Channel_16: ADC信道16被选择 * - ADC_Channel_17: ADC信道17被选择 * (3)Rank:注入组音序器(sequencer)的等级,选择范围必须在1-4之间 * (4)ADC_SampleTime: ADC_SampleTime:将要为选中信道设置的采样时间值 * ADC_SampleTime.取值: * - ADC_SampleTime_1Cycles5: 采样时间等于1.5个周期 * - ADC_SampleTime_7Cycles5: 采样时间等于7.5个周期 * - ADC_SampleTime_13Cycles5: 采样时间等于13.5个周期 * - ADC_SampleTime_28Cycles5: 采样时间等于28.5个周期 * - ADC_SampleTime_41Cycles5: 采样时间等于41.5个周期 * - ADC_SampleTime_55Cycles5: 采样时间等于55.5个周期 * - ADC_SampleTime_71Cycles5: 采样时间等于71.5个周期 * - ADC_SampleTime_239Cycles5: 采样时间等于239.5个周期 * 输出参数: 无 * 返回参数: 无 *******************************************************************************/ void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, u8 ADC_Channel, u8 Rank, u8 ADC_SampleTime) { u32 tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; /* Check the parameters [检查参数] */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_CHANNEL(ADC_Channel)); assert_param(IS_ADC_INJECTED_RANK(Rank)); assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); /* if ADC_Channel_10 ... ADC_Channel_17 is selected [如果ADC_Channel_10 ... ADC_Channel_17被选择]*/ if (ADC_Channel > ADC_Channel_9) { /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->SMPR1; /* Calculate the mask to clear [计算需要清除的标志]*/ tmpreg2 = SMPR1_SMP_Set << (3*(ADC_Channel - 10)); /* Clear the old discontinuous mode channel count [清除过去的不间断模式通道计数器]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set [计算需要置位的标志]*/ tmpreg2 = (u32)ADC_SampleTime << (3*(ADC_Channel - 10)); /* Set the discontinuous mode channel count [设置不间断模式通道计数器]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->SMPR1 = tmpreg1; } else /* ADC_Channel include in ADC_Channel_[0..9] [ADC_Channel 在 ADC_Channel_[0..9]之间]*/ { /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->SMPR2; /* Calculate the mask to clear [计算需要清除的标志]*/ tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel); /* Clear the old discontinuous mode channel count [清除过去的不间断模式通道计数器]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set [计算需要置位的标志]*/ tmpreg2 = (u32)ADC_SampleTime << (3 * ADC_Channel); /* Set the discontinuous mode channel count [设置不间断模式通道计数器]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->SMPR2 = tmpreg1; } /* Rank configuration [序列配置]*/ /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->JSQR; /* Get JL value[取得JL值]: Number = JL+1 */ tmpreg3 = (tmpreg1 & JSQR_JL_Set)>> 20; /* Calculate the mask to clear[计算需要清除的标志]: ((Rank-1)+(4-JL-1)) */ tmpreg2 = JSQR_JSQ_Set << (5 * (u8)((Rank + 3) - (tmpreg3 + 1))); /* Clear the old JSQx bits for the selected rank [清除选中序列旧的JSQx位]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set[计算需要置位的标志]: ((Rank-1)+(4-JL-1)) */ tmpreg2 = (u32)ADC_Channel << (5 * (u8)((Rank + 3) - (tmpreg3 + 1))); /* Set the JSQx bits for the selected rank [置位选中序列旧的JSQx位]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->JSQR = tmpreg1; }
/** * @brief Configures for the selected ADC injected channel its corresponding * rank in the sequencer and its sample time. * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. * @param ADC_Channel: the ADC channel to configure. * This parameter can be one of the following values: * @arg ADC_Channel_0: ADC Channel0 selected * @arg ADC_Channel_1: ADC Channel1 selected * @arg ADC_Channel_2: ADC Channel2 selected * @arg ADC_Channel_3: ADC Channel3 selected * @arg ADC_Channel_4: ADC Channel4 selected * @arg ADC_Channel_5: ADC Channel5 selected * @arg ADC_Channel_6: ADC Channel6 selected * @arg ADC_Channel_7: ADC Channel7 selected * @arg ADC_Channel_8: ADC Channel8 selected * @arg ADC_Channel_9: ADC Channel9 selected * @arg ADC_Channel_10: ADC Channel10 selected * @arg ADC_Channel_11: ADC Channel11 selected * @arg ADC_Channel_12: ADC Channel12 selected * @arg ADC_Channel_13: ADC Channel13 selected * @arg ADC_Channel_14: ADC Channel14 selected * @arg ADC_Channel_15: ADC Channel15 selected * @arg ADC_Channel_16: ADC Channel16 selected * @arg ADC_Channel_17: ADC Channel17 selected * @param Rank: The rank in the injected group sequencer. This parameter must be between 1 and 4. * @param ADC_SampleTime: The sample time value to be set for the selected channel. * This parameter can be one of the following values: * @arg ADC_SampleTime_1Cycles5: Sample time equal to 1.5 cycles * @arg ADC_SampleTime_7Cycles5: Sample time equal to 7.5 cycles * @arg ADC_SampleTime_13Cycles5: Sample time equal to 13.5 cycles * @arg ADC_SampleTime_28Cycles5: Sample time equal to 28.5 cycles * @arg ADC_SampleTime_41Cycles5: Sample time equal to 41.5 cycles * @arg ADC_SampleTime_55Cycles5: Sample time equal to 55.5 cycles * @arg ADC_SampleTime_71Cycles5: Sample time equal to 71.5 cycles * @arg ADC_SampleTime_239Cycles5: Sample time equal to 239.5 cycles * @retval None */ void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) { uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_CHANNEL(ADC_Channel)); assert_param(IS_ADC_INJECTED_RANK(Rank)); assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); /* if ADC_Channel_10 ... ADC_Channel_17 is selected */ if (ADC_Channel > ADC_Channel_9) { /* Get the old register value */ tmpreg1 = ADCx->SMPR1; /* Calculate the mask to clear */ tmpreg2 = SMPR1_SMP_Set << (3*(ADC_Channel - 10)); /* Clear the old channel sample time */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set */ tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10)); /* Set the new channel sample time */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->SMPR1 = tmpreg1; } else /* ADC_Channel include in ADC_Channel_[0..9] */ { /* Get the old register value */ tmpreg1 = ADCx->SMPR2; /* Calculate the mask to clear */ tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel); /* Clear the old channel sample time */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set */ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); /* Set the new channel sample time */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->SMPR2 = tmpreg1; } /* Rank configuration */ /* Get the old register value */ tmpreg1 = ADCx->JSQR; /* Get JL value: Number = JL+1 */ tmpreg3 = (tmpreg1 & JSQR_JL_Set)>> 20; /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */ tmpreg2 = JSQR_JSQ_Set << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); /* Clear the old JSQx bits for the selected rank */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set: ((Rank-1)+(4-JL-1)) */ tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1))); /* Set the JSQx bits for the selected rank */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->JSQR = tmpreg1; }
/** * \brief Set the sample time (in cycles of the ADC) of a channel. * \param channel The analog channel number. * \param time The amount of time for sampling, should be one of the defines * from the ST library, such as ADC_SampleTime_15Cycles. */ int setSampleTime(const uint16_t channel, const uint16_t time) { if (!IS_ADC_SAMPLE_TIME(time)) return -1; if (channel > 18) return -1; if (channel > 9) { reinterpret_cast<ADC_TypeDef*>(ADCx)->CR1 &= (0xffffffff - (0x7 << ((channel-9)*3))); reinterpret_cast<ADC_TypeDef*>(ADCx)->CR1 |= time << ((channel-9)*3); } else { reinterpret_cast<ADC_TypeDef*>(ADCx)->CR2 &= (0xffffffff - (0x7 << (channel*3))); reinterpret_cast<ADC_TypeDef*>(ADCx)->CR2 |= time << (channel*3); } return 0; }
/** * @brief Configures for the selected ADC channel its corresponding * rank in the sequencer and its sample time. * @param ADCx: where x can be 1, 2 to select the ADC peripheral. * @param ADC_Channel: the ADC channel to configure. * This parameter can be one of the following values: * @arg ADC_Channel_0: ADC Channel0 selected * @arg ADC_Channel_1: ADC Channel1 selected * @arg ADC_Channel_2: ADC Channel2 selected * @arg ADC_Channel_3: ADC Channel3 selected * @arg ADC_Channel_4: ADC Channel4 selected * @arg ADC_Channel_5: ADC Channel5 selected * @arg ADC_Channel_6: ADC Channel6 selected * @arg ADC_Channel_7: ADC Channel7 selected * @arg ADC_Channel_8: ADC Channel8 selected * @retval : None */ void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_CHANNEL(ADC_Channel)); assert_param(IS_ADC_REGULAR_RANK(Rank)); assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); tmpreg = ADCx->ADCFG; tmpreg &= ~(ADC_SMPR_SMP<<10); ADCx->ADCFG = tmpreg|((ADC_SampleTime&ADC_SMPR_SMP)<<10); switch(ADC_Channel) { /* set the CHEN0 bit for channel 0 enable*/ case ADC_Channel_0: ADCx->ADCHS |= CHEN0_ENABLE; break; /* set the CHEN1 bit for channel 1 enable*/ case ADC_Channel_1: ADCx->ADCHS |= CHEN1_ENABLE; break; /* set the CHEN2 bit for channel 2 enable*/ case ADC_Channel_2: ADCx->ADCHS |= CHEN2_ENABLE; break; /* set the CHEN3 bit for channel 3 enable*/ case ADC_Channel_3: ADCx->ADCHS |= CHEN3_ENABLE; break; /* set the CHEN4 bit for channel 4 enable*/ case ADC_Channel_4: ADCx->ADCHS |= CHEN4_ENABLE; break; /* set the CHEN5 bit for channel 5 enable*/ case ADC_Channel_5: ADCx->ADCHS |= CHEN5_ENABLE; break; /* set the CHEN6 bit for channel 6 enable*/ case ADC_Channel_6: ADCx->ADCHS |= CHEN6_ENABLE; break; /* set the CHEN7 bit for channel 7 enable*/ case ADC_Channel_7: ADCx->ADCHS |= CHEN7_ENABLE; break; /* set the SENSOREN bit for channel 8 enable*/ case ADC_Channel_8: ADCx->ADCHS |= CHEN8_ENABLE; //SENSOREN or VREFINT break; case ADC_Channel_All:ADCx->ADCHS |= CHALL_ENABLE; //SENSOREN or VREFINT break; default: ADCx->ADCHS &= CHEN_DISABLE; break; } }
/** * @brief Configures for the selected ADC and its sampling time. * @param ADCx: where x can be 1 to select the ADC peripheral. * @param ADC_Channel: the ADC channel to configure. * This parameter can be any combination of the following values: * @arg ADC_Channel_0: ADC Channel0 selected * @arg ADC_Channel_1: ADC Channel1 selected * @arg ADC_Channel_2: ADC Channel2 selected * @arg ADC_Channel_3: ADC Channel3 selected * @arg ADC_Channel_4: ADC Channel4 selected * @arg ADC_Channel_5: ADC Channel5 selected * @arg ADC_Channel_6: ADC Channel6 selected * @arg ADC_Channel_7: ADC Channel7 selected * @arg ADC_Channel_8: ADC Channel8 selected * @arg ADC_Channel_9: ADC Channel9 selected * @arg ADC_Channel_10: ADC Channel10 selected, not available for STM32F031 devices * @arg ADC_Channel_11: ADC Channel11 selected, not available for STM32F031 devices * @arg ADC_Channel_12: ADC Channel12 selected, not available for STM32F031 devices * @arg ADC_Channel_13: ADC Channel13 selected, not available for STM32F031 devices * @arg ADC_Channel_14: ADC Channel14 selected, not available for STM32F031 devices * @arg ADC_Channel_15: ADC Channel15 selected, not available for STM32F031 devices * @arg ADC_Channel_16: ADC Channel16 selected * @arg ADC_Channel_17: ADC Channel17 selected * @arg ADC_Channel_18: ADC Channel18 selected, not available for STM32F030 devices * @param ADC_SampleTime: The sample time value to be set for the selected channel. * This parameter can be one of the following values: * @arg ADC_SampleTime_1_5Cycles: Sample time equal to 1.5 cycles * @arg ADC_SampleTime_7_5Cycles: Sample time equal to 7.5 cycles * @arg ADC_SampleTime_13_5Cycles: Sample time equal to 13.5 cycles * @arg ADC_SampleTime_28_5Cycles: Sample time equal to 28.5 cycles * @arg ADC_SampleTime_41_5Cycles: Sample time equal to 41.5 cycles * @arg ADC_SampleTime_55_5Cycles: Sample time equal to 55.5 cycles * @arg ADC_SampleTime_71_5Cycles: Sample time equal to 71.5 cycles * @arg ADC_SampleTime_239_5Cycles: Sample time equal to 239.5 cycles * @retval None */ void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_Channel, uint32_t ADC_SampleTime) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_CHANNEL(ADC_Channel)); assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); /* Configure the ADC Channel */ ADCx->CHSELR |= (uint32_t)ADC_Channel; /* Clear the Sampling time Selection bits */ tmpreg &= ~ADC_SMPR1_SMPR; /* Set the ADC Sampling Time register */ tmpreg |= (uint32_t)ADC_SampleTime; /* Configure the ADC Sample time register */ ADCx->SMPR = tmpreg ; }
/** * @brief Configures for the selected ADC and its sampling time. * @param ADCx: where x can be 1 to select the ADC peripheral. * @param ADC_Channel: the ADC channel to configure. * This parameter can be any combination of the following values: * @arg ADC_Channel_0: ADC Channel0 selected * @arg ADC_Channel_1: ADC Channel1 selected * @arg ADC_Channel_2: ADC Channel2 selected * @arg ADC_Channel_3: ADC Channel3 selected * @arg ADC_Channel_4: ADC Channel4 selected * @arg ADC_Channel_5: ADC Channel5 selected * @arg ADC_Channel_6: ADC Channel6 selected * @arg ADC_Channel_7: ADC Channel7 selected * @arg ADC_Channel_8: ADC Channel8 selected * @arg ADC_Channel_9: ADC Channel9 selected * @arg ADC_Channel_10: ADC Channel10 selected * @arg ADC_Channel_11: ADC Channel11 selected * @arg ADC_Channel_12: ADC Channel12 selected * @arg ADC_Channel_13: ADC Channel13 selected * @arg ADC_Channel_14: ADC Channel14 selected * @arg ADC_Channel_15: ADC Channel15 selected * @arg ADC_Channel_16: ADC Channel16 selected * @arg ADC_Channel_17: ADC Channel17 selected * @arg ADC_Channel_18: ADC Channel18 selected * @param ADC_SampleTime: The sample time value to be set for the selected channel. * This parameter can be one of the following values: * @arg ADC_SampleTime_1_5Cycles: Sample time equal to 1.5 cycles * @arg ADC_SampleTime_7_5Cycles: Sample time equal to 7.5 cycles * @arg ADC_SampleTime_13_5Cycles: Sample time equal to 13.5 cycles * @arg ADC_SampleTime_28_5Cycles: Sample time equal to 28.5 cycles * @arg ADC_SampleTime_41_5Cycles: Sample time equal to 41.5 cycles * @arg ADC_SampleTime_55_5Cycles: Sample time equal to 55.5 cycles * @arg ADC_SampleTime_71_5Cycles: Sample time equal to 71.5 cycles * @arg ADC_SampleTime_239_5Cycles: Sample time equal to 239.5 cycles * @retval None */ void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_Channel, uint32_t ADC_SampleTime) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_CHANNEL(ADC_Channel)); assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); /* Configure the ADC Channel */ // ADCx->CHSELR |= (uint32_t)ADC_Channel; PbP bug fix. The STM code logic ORs the Channel. This will not clear any previous set channels ADCx->CHSELR = (uint32_t)ADC_Channel; // Our fix will clear previous set channels /* Clear the Sampling time Selection bits */ tmpreg &= ~ADC_SMPR1_SMPR; /* Set the ADC Sampling Time register */ tmpreg |= (uint32_t)ADC_SampleTime; /* Configure the ADC Sample time register */ ADCx->SMPR = tmpreg ; }
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) { uint32_t tmpreg1 = 0, tmpreg2 = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_CHANNEL(ADC_Channel)); assert_param(IS_ADC_REGULAR_RANK(Rank)); assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ if (ADC_Channel > ADC_Channel_9) { /* Get the old register value */ tmpreg1 = ADCx->SMPR1; /* Calculate the mask to clear */ tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 10)); /* Clear the old sample time */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set */ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10)); /* Set the new sample time */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->SMPR1 = tmpreg1; } else /* ADC_Channel include in ADC_Channel_[0..9] */ { /* Get the old register value */ tmpreg1 = ADCx->SMPR2; /* Calculate the mask to clear */ tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel); /* Clear the old sample time */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set */ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel); /* Set the new sample time */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->SMPR2 = tmpreg1; } /* For Rank 1 to 6 */ if (Rank < 7) { /* Get the old register value */ tmpreg1 = ADCx->SQR3; /* Calculate the mask to clear */ tmpreg2 = SQR3_SQ_SET << (5 * (Rank - 1)); /* Clear the old SQx bits for the selected rank */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set */ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1)); /* Set the SQx bits for the selected rank */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->SQR3 = tmpreg1; } /* For Rank 7 to 12 */ else if (Rank < 13) { /* Get the old register value */ tmpreg1 = ADCx->SQR2; /* Calculate the mask to clear */ tmpreg2 = SQR2_SQ_SET << (5 * (Rank - 7)); /* Clear the old SQx bits for the selected rank */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set */ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7)); /* Set the SQx bits for the selected rank */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->SQR2 = tmpreg1; } /* For Rank 13 to 16 */ else { /* Get the old register value */ tmpreg1 = ADCx->SQR1; /* Calculate the mask to clear */ tmpreg2 = SQR1_SQ_SET << (5 * (Rank - 13)); /* Clear the old SQx bits for the selected rank */ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set */ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13)); /* Set the SQx bits for the selected rank */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx->SQR1 = tmpreg1; } }
/** * @brief Configures for the selected ADC regular channel its corresponding * rank in the sequencer and its sample time. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param sConfig: ADC configuration structure. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig) { __IO uint32_t counter = 0; /* Check the parameters */ assert_param(IS_ADC_CHANNEL(sConfig->Channel)); assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank)); assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime)); /* Process locked */ __HAL_LOCK(hadc); /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ if (sConfig->Channel > ADC_CHANNEL_9) { /* Clear the old sample time */ hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel); /* Set the new sample time */ hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel); } else /* ADC_Channel include in ADC_Channel_[0..9] */ { /* Clear the old sample time */ hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel); /* Set the new sample time */ hadc->Instance->SMPR2 |= ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel); } /* For Rank 1 to 6 */ if (sConfig->Rank < 7) { /* Clear the old SQx bits for the selected rank */ hadc->Instance->SQR3 &= ~ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank); /* Set the SQx bits for the selected rank */ hadc->Instance->SQR3 |= ADC_SQR3_RK(sConfig->Channel, sConfig->Rank); } /* For Rank 7 to 12 */ else if (sConfig->Rank < 13) { /* Clear the old SQx bits for the selected rank */ hadc->Instance->SQR2 &= ~ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank); /* Set the SQx bits for the selected rank */ hadc->Instance->SQR2 |= ADC_SQR2_RK(sConfig->Channel, sConfig->Rank); } /* For Rank 13 to 16 */ else { /* Clear the old SQx bits for the selected rank */ hadc->Instance->SQR1 &= ~ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank); /* Set the SQx bits for the selected rank */ hadc->Instance->SQR1 |= ADC_SQR1_RK(sConfig->Channel, sConfig->Rank); } /* if ADC1 Channel_18 is selected enable VBAT Channel */ if ((hadc->Instance == ADC1) && (sConfig->Channel == ADC_CHANNEL_VBAT)) { /* Enable the VBAT channel*/ ADC->CCR |= ADC_CCR_VBATE; } /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */ if ((hadc->Instance == ADC1) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT))) { /* Enable the TSVREFE channel*/ ADC->CCR |= ADC_CCR_TSVREFE; if((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)) { /* Delay for temperature sensor stabilization time */ /* Compute number of CPU cycles to wait for */ counter = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000)); while(counter != 0) { counter--; } } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Configures for the selected ADC injected channel its corresponding * rank in the sequencer and its sample time. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param sConfigInjected: ADC configuration structure for injected channel. * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected) { #ifdef USE_FULL_ASSERT uint32_t tmp = 0; #endif /* USE_FULL_ASSERT */ /* Check the parameters */ assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv)); assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); #ifdef USE_FULL_ASSERT tmp = ADC_GET_RESOLUTION(hadc); assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset)); #endif /* USE_FULL_ASSERT */ if(sConfigInjected->ExternalTrigInjecConvEdge != ADC_INJECTED_SOFTWARE_START) { assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge)); } /* Process locked */ __HAL_LOCK(hadc); /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ if (sConfigInjected->InjectedChannel > ADC_CHANNEL_9) { /* Clear the old sample time */ hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel); /* Set the new sample time */ hadc->Instance->SMPR1 |= ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); } else /* ADC_Channel include in ADC_Channel_[0..9] */ { /* Clear the old sample time */ hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel); /* Set the new sample time */ hadc->Instance->SMPR2 |= ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); } /*---------------------------- ADCx JSQR Configuration -----------------*/ hadc->Instance->JSQR &= ~(ADC_JSQR_JL); hadc->Instance->JSQR |= ADC_SQR1(sConfigInjected->InjectedNbrOfConversion); /* Rank configuration */ /* Clear the old SQx bits for the selected rank */ hadc->Instance->JSQR &= ~ADC_JSQR(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion); /* Set the SQx bits for the selected rank */ hadc->Instance->JSQR |= ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion); /* Enable external trigger if trigger selection is different of software */ /* start. */ /* Note: This configuration keeps the hardware feature of parameter */ /* ExternalTrigConvEdge "trigger edge none" equivalent to */ /* software start. */ if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) { /* Select external trigger to start conversion */ hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConv; /* Select external trigger polarity */ hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge; } else { /* Reset the external trigger */ hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); } if (sConfigInjected->AutoInjectedConv != DISABLE) { /* Enable the selected ADC automatic injected group conversion */ hadc->Instance->CR1 |= ADC_CR1_JAUTO; } else { /* Disable the selected ADC automatic injected group conversion */ hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO); } if (sConfigInjected->InjectedDiscontinuousConvMode != DISABLE) { /* Enable the selected ADC injected discontinuous mode */ hadc->Instance->CR1 |= ADC_CR1_JDISCEN; } else { /* Disable the selected ADC injected discontinuous mode */ hadc->Instance->CR1 &= ~(ADC_CR1_JDISCEN); } switch(sConfigInjected->InjectedRank) { case 1: /* Set injected channel 1 offset */ hadc->Instance->JOFR1 &= ~(ADC_JOFR1_JOFFSET1); hadc->Instance->JOFR1 |= sConfigInjected->InjectedOffset; break; case 2: /* Set injected channel 2 offset */ hadc->Instance->JOFR2 &= ~(ADC_JOFR2_JOFFSET2); hadc->Instance->JOFR2 |= sConfigInjected->InjectedOffset; break; case 3: /* Set injected channel 3 offset */ hadc->Instance->JOFR3 &= ~(ADC_JOFR3_JOFFSET3); hadc->Instance->JOFR3 |= sConfigInjected->InjectedOffset; break; default: /* Set injected channel 4 offset */ hadc->Instance->JOFR4 &= ~(ADC_JOFR4_JOFFSET4); hadc->Instance->JOFR4 |= sConfigInjected->InjectedOffset; break; } /* if ADC1 Channel_18 is selected enable VBAT Channel */ if ((hadc->Instance == ADC1) && (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT)) { /* Enable the VBAT channel*/ ADC->CCR |= ADC_CCR_VBATE; } /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */ if ((hadc->Instance == ADC1) && ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT))) { /* Enable the TSVREFE channel*/ ADC->CCR |= ADC_CCR_TSVREFE; } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Configures the ADC injected group and the selected channel to be * linked to the injected group. * @note Possibility to update parameters on the fly: * This function initializes injected group, following calls to this * function can be used to reconfigure some parameters of structure * "ADC_InjectionConfTypeDef" on the fly, without reseting the ADC. * The setting of these parameters is conditioned to ADC state: * this function must be called when ADC is not under conversion. * @param hadc: ADC handle * @param sConfigInjected: Structure of ADC injected group and ADC channel for * injected group. * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected) { HAL_StatusTypeDef tmpHALStatus = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); assert_param(IS_ADC_EXTTRIGINJEC(sConfigInjected->ExternalTrigInjecConv)); assert_param(IS_ADC_RANGE(sConfigInjected->InjectedOffset)); if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE) { assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); } if(sConfigInjected->ExternalTrigInjecConvEdge != ADC_INJECTED_SOFTWARE_START) { assert_param(IS_ADC_EXTTRIGINJEC_EDGE(sConfigInjected->ExternalTrigInjecConvEdge)); } /* Process locked */ __HAL_LOCK(hadc); /* Configuration of injected group sequencer: */ /* - if scan mode is disabled, injected channels sequence length is set to */ /* 0x00: 1 channel converted (channel on regular rank 1) */ /* Parameter "InjectedNbrOfConversion" is discarded. */ /* Note: Scan mode is present by hardware on this device and, if */ /* disabled, discards automatically nb of conversions. Anyway, nb of */ /* conversions is forced to 0x00 for alignment over all STM32 devices. */ /* - if scan mode is enabled, injected channels sequence length is set to */ /* parameter ""InjectedNbrOfConversion". */ if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) { if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1) { /* Clear the old SQx bits for all injected ranks */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 | ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 , __ADC_JSQR_RK(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1, 0x01) ); } /* If another injected rank than rank1 was intended to be set, and could */ /* not due to ScanConvMode disabled, error is reported. */ else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmpHALStatus = HAL_ERROR; } } else { /* Since injected channels rank conv. order depends on total number of */ /* injected conversions, selected rank must be below or equal to total */ /* number of injected conversions to be updated. */ if (sConfigInjected->InjectedRank <= sConfigInjected->InjectedNbrOfConversion) { /* Clear the old SQx bits for the selected rank */ /* Set the SQx bits for the selected rank */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | __ADC_JSQR_RK(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) , __ADC_JSQR_JL(sConfigInjected->InjectedNbrOfConversion) | __ADC_JSQR_RK(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) ); } else { /* Clear the old SQx bits for the selected rank */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | __ADC_JSQR_RK(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) , 0x00000000 ); } } /* Enable external trigger if trigger selection is different of software */ /* start. */ /* Note: This configuration keeps the hardware feature of parameter */ /* ExternalTrigConvEdge "trigger edge none" equivalent to */ /* software start. */ if (sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) { MODIFY_REG(hadc->Instance->CR2 , ADC_CR2_JEXTEN | ADC_CR2_JEXTSEL , sConfigInjected->ExternalTrigInjecConv | sConfigInjected->ExternalTrigInjecConvEdge ); } else { MODIFY_REG(hadc->Instance->CR2, ADC_CR2_JEXTEN | ADC_CR2_JEXTSEL , 0x00000000 ); } /* Configuration of injected group */ /* Parameters update conditioned to ADC state: */ /* Parameters that can be updated only when ADC is disabled: */ /* - Automatic injected conversion */ /* - Injected discontinuous mode */ if ((__HAL_ADC_IS_ENABLED(hadc) == RESET)) { hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO | ADC_CR1_JDISCEN ); /* Automatic injected conversion can be enabled if injected group */ /* external triggers are disabled. */ if (sConfigInjected->AutoInjectedConv == ENABLE) { if (sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START) { SET_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO); } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmpHALStatus = HAL_ERROR; } } /* Injected discontinuous can be enabled only if auto-injected mode is */ /* disabled. */ if (sConfigInjected->InjectedDiscontinuousConvMode == ENABLE) { if (sConfigInjected->AutoInjectedConv == DISABLE) { SET_BIT(hadc->Instance->CR1, ADC_CR1_JDISCEN); } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmpHALStatus = HAL_ERROR; } } } /* InjectedChannel sampling time configuration */ /* For InjectedChannels 0 to 9 */ if (sConfigInjected->InjectedChannel < ADC_CHANNEL_10) { MODIFY_REG(hadc->Instance->SMPR3, __ADC_SMPR3(ADC_SMPR3_SMP0, sConfigInjected->InjectedChannel), __ADC_SMPR3(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); } /* For InjectedChannels 10 to 19 */ else if (sConfigInjected->InjectedChannel < ADC_CHANNEL_20) { MODIFY_REG(hadc->Instance->SMPR2, __ADC_SMPR2(ADC_SMPR2_SMP10, sConfigInjected->InjectedChannel), __ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); } /* For InjectedChannels 20 to 26 for devices Cat.1, Cat.2, Cat.3 */ /* For InjectedChannels 20 to 29 for devices Cat4, Cat.5 */ else if (sConfigInjected->InjectedChannel <= ADC_SMPR1_CHANNEL_MAX) { MODIFY_REG(hadc->Instance->SMPR1, __ADC_SMPR1(ADC_SMPR1_SMP20, sConfigInjected->InjectedChannel), __ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); } /* For InjectedChannels 30 to 31 for devices Cat4, Cat.5 */ else { __ADC_SMPR0_CHANNEL_SET(hadc, sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); } /* Configure the offset: offset enable/disable, InjectedChannel, offset value */ switch(sConfigInjected->InjectedRank) { case 1: /* Set injected channel 1 offset */ MODIFY_REG(hadc->Instance->JOFR1, ADC_JOFR1_JOFFSET1, sConfigInjected->InjectedOffset); break; case 2: /* Set injected channel 2 offset */ MODIFY_REG(hadc->Instance->JOFR2, ADC_JOFR2_JOFFSET2, sConfigInjected->InjectedOffset); break; case 3: /* Set injected channel 3 offset */ MODIFY_REG(hadc->Instance->JOFR3, ADC_JOFR3_JOFFSET3, sConfigInjected->InjectedOffset); break; case 4: default: MODIFY_REG(hadc->Instance->JOFR4, ADC_JOFR4_JOFFSET4, sConfigInjected->InjectedOffset); break; } /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */ /* and VREFINT measurement path. */ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) ) { SET_BIT(ADC->CCR, ADC_CCR_TSVREFE); } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmpHALStatus; }
/** * @brief Configures the ADC injected group and the selected channel to be * linked to the injected group. * @note Possibility to update parameters on the fly: * This function initializes injected group, following calls to this * function can be used to reconfigure some parameters of structure * "ADC_InjectionConfTypeDef" on the fly, without reseting the ADC. * The setting of these parameters is conditioned to ADC state: * this function must be called when ADC is not under conversion. * @param hadc: ADC handle * @param sConfigInjected: Structure of ADC injected group and ADC channel for * injected group. * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; __IO uint32_t wait_loop_index = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); assert_param(IS_ADC_EXTTRIGINJEC(sConfigInjected->ExternalTrigInjecConv)); assert_param(IS_ADC_RANGE(sConfigInjected->InjectedOffset)); if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE) { assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); } /* Process locked */ __HAL_LOCK(hadc); /* Configuration of injected group sequencer: */ /* - if scan mode is disabled, injected channels sequence length is set to */ /* 0x00: 1 channel converted (channel on regular rank 1) */ /* Parameter "InjectedNbrOfConversion" is discarded. */ /* Note: Scan mode is present by hardware on this device and, if */ /* disabled, discards automatically nb of conversions. Anyway, nb of */ /* conversions is forced to 0x00 for alignment over all STM32 devices. */ /* - if scan mode is enabled, injected channels sequence length is set to */ /* parameter "InjectedNbrOfConversion". */ if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) { if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1) { /* Clear the old SQx bits for all injected ranks */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 | ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 , ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1, 0x01) ); } /* If another injected rank than rank1 was intended to be set, and could */ /* not due to ScanConvMode disabled, error is reported. */ else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } else { /* Since injected channels rank conv. order depends on total number of */ /* injected conversions, selected rank must be below or equal to total */ /* number of injected conversions to be updated. */ if (sConfigInjected->InjectedRank <= sConfigInjected->InjectedNbrOfConversion) { /* Clear the old SQx bits for the selected rank */ /* Set the SQx bits for the selected rank */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) , ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion) | ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) ); } else { /* Clear the old SQx bits for the selected rank */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) , 0x00000000 ); } } /* Configuration of injected group */ /* Parameters update conditioned to ADC state: */ /* Parameters that can be updated only when ADC is disabled: */ /* - external trigger to start conversion */ /* Parameters update not conditioned to ADC state: */ /* - Automatic injected conversion */ /* - Injected discontinuous mode */ /* Note: In case of ADC already enabled, caution to not launch an unwanted */ /* conversion while modifying register CR2 by writing 1 to bit ADON. */ if (ADC_IS_ENABLE(hadc) == RESET) { MODIFY_REG(hadc->Instance->CR2 , ADC_CR2_JEXTSEL | ADC_CR2_ADON , ADC_CFGR_JEXTSEL(hadc, sConfigInjected->ExternalTrigInjecConv) ); } /* Configuration of injected group */ /* - Automatic injected conversion */ /* - Injected discontinuous mode */ /* Automatic injected conversion can be enabled if injected group */ /* external triggers are disabled. */ if (sConfigInjected->AutoInjectedConv == ENABLE) { if (sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START) { SET_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO); } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } /* Injected discontinuous can be enabled only if auto-injected mode is */ /* disabled. */ if (sConfigInjected->InjectedDiscontinuousConvMode == ENABLE) { if (sConfigInjected->AutoInjectedConv == DISABLE) { SET_BIT(hadc->Instance->CR1, ADC_CR1_JDISCEN); } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } /* InjectedChannel sampling time configuration */ /* For channels 10 to 17 */ if (sConfigInjected->InjectedChannel >= ADC_CHANNEL_10) { MODIFY_REG(hadc->Instance->SMPR1 , ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel) , ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); } else /* For channels 0 to 9 */ { MODIFY_REG(hadc->Instance->SMPR2 , ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel) , ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); } /* If ADC1 InjectedChannel_16 or InjectedChannel_17 is selected, enable Temperature sensor */ /* and VREFINT measurement path. */ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) ) { SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE); } /* Configure the offset: offset enable/disable, InjectedChannel, offset value */ switch(sConfigInjected->InjectedRank) { case 1: /* Set injected channel 1 offset */ MODIFY_REG(hadc->Instance->JOFR1, ADC_JOFR1_JOFFSET1, sConfigInjected->InjectedOffset); break; case 2: /* Set injected channel 2 offset */ MODIFY_REG(hadc->Instance->JOFR2, ADC_JOFR2_JOFFSET2, sConfigInjected->InjectedOffset); break; case 3: /* Set injected channel 3 offset */ MODIFY_REG(hadc->Instance->JOFR3, ADC_JOFR3_JOFFSET3, sConfigInjected->InjectedOffset); break; case 4: default: MODIFY_REG(hadc->Instance->JOFR4, ADC_JOFR4_JOFFSET4, sConfigInjected->InjectedOffset); break; } /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */ /* and VREFINT measurement path. */ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) ) { /* For STM32F1 devices with several ADC: Only ADC1 can access internal */ /* measurement channels (VrefInt/TempSensor). If these channels are */ /* intended to be set on other ADC instances, an error is reported. */ if (hadc->Instance == ADC1) { if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET) { SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE); if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR)) { /* Delay for temperature sensor stabilization time */ /* Compute number of CPU cycles to wait for */ wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000)); while(wait_loop_index != 0) { wait_loop_index--; } } } } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/******************************************************************************* * 函数名称: ADC_RegularChannelConfig * 功能描述: 为选中的ADC常规组信道配置相关的音序器(sequencer)等级和采样时间。 * 输入参数: (1)ADCx:其中x可以是1、2或3,用来选择ADC外围模块. * (2)ADC_Channel:需要配置的ADC信道 * ADC_Channel 可能的取值: * - ADC_Channel_0: ADC信道0被选择 * - ADC_Channel_1: ADC信道1被选择 * - ADC_Channel_2: ADC信道2被选择 * - ADC_Channel_3: ADC信道3被选择 * - ADC_Channel_4: ADC信道4被选择 * - ADC_Channel_5: ADC信道5被选择 * - ADC_Channel_6: ADC信道6被选择 * - ADC_Channel_7: ADC信道7被选择 * - ADC_Channel_8: ADC信道8被选择 * - ADC_Channel_9: ADC信道9被选择 * - ADC_Channel_10: ADC信道10被选择 * - ADC_Channel_11: ADC信道11被选择 * - ADC_Channel_12: ADC信道12被选择 * - ADC_Channel_13: ADC信道13被选择 * - ADC_Channel_14: ADC信道14被选择 * - ADC_Channel_15: ADC信道15被选择 * - ADC_Channel_16: ADC信道16被选择 * - ADC_Channel_17: ADC信道17被选择 * (3)Rank:常规组音序器(sequencer)的等级。参数范围是1-16。 * (4)ADC_SampleTime:将要为所选的信道设置的采样时间 * ADC_SampleTime.取值: * - ADC_SampleTime_1Cycles5: 采样时间等于1.5个周期 * - ADC_SampleTime_7Cycles5: 采样时间等于7.5个周期 * - ADC_SampleTime_13Cycles5: 采样时间等于13.5个周期 * - ADC_SampleTime_28Cycles5: 采样时间等于28.5个周期 * - ADC_SampleTime_41Cycles5: 采样时间等于41.5个周期 * - ADC_SampleTime_55Cycles5: 采样时间等于55.5个周期 * - ADC_SampleTime_71Cycles5: 采样时间等于71.5个周期 * - ADC_SampleTime_239Cycles5: 采样时间等于239.5个周期 * 输出参数: 无 * 返回参数: 无 *******************************************************************************/ void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, u8 ADC_Channel, u8 Rank, u8 ADC_SampleTime) { u32 tmpreg1 = 0, tmpreg2 = 0; /* Check the parameters [检查参数] */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_CHANNEL(ADC_Channel)); assert_param(IS_ADC_REGULAR_RANK(Rank)); assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime)); /* if ADC_Channel_10 ... ADC_Channel_17 is selected [如果ADC_Channel_10 ... ADC_Channel_17被选择]*/ if (ADC_Channel > ADC_Channel_9) { /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->SMPR1; /* Calculate the mask to clear [计算需要清除的标志]*/ tmpreg2 = SMPR1_SMP_Set << (3 * (ADC_Channel - 10)); /* Clear the old discontinuous mode channel count [清除过去的不间断模式通道计数器]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set [计算需要置位的标志]*/ tmpreg2 = (u32)ADC_SampleTime << (3 * (ADC_Channel - 10)); /* Set the discontinuous mode channel count [设置不间断模式通道计数器]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->SMPR1 = tmpreg1; } else /* ADC_Channel include in ADC_Channel_[0..9] [ADC_Channel 在 ADC_Channel_[0..9]之间]*/ { /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->SMPR2; /* Calculate the mask to clear [计算需要清除的标志]*/ tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel); /* Clear the old discontinuous mode channel count [清除过去的不间断模式通道计数器]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set [计算需要置位的标志]*/ tmpreg2 = (u32)ADC_SampleTime << (3 * ADC_Channel); /* Set the discontinuous mode channel count [设置不间断模式通道计数器]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->SMPR2 = tmpreg1; } /* For Rank 1 to 6 [序列在1到6之间]*/ if (Rank < 7) { /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->SQR3; /* Calculate the mask to clear [计算需要清除的标志]*/ tmpreg2 = SQR3_SQ_Set << (5 * (Rank - 1)); /* Clear the old SQx bits for the selected rank [根据选择的序列清除旧的SQx位]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set [计算需要置位的标志]*/ tmpreg2 = (u32)ADC_Channel << (5 * (Rank - 1)); /* Set the SQx bits for the selected rank [根据选择的序列置位新的SQx位]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->SQR3 = tmpreg1; } /* For Rank 7 to 12 [序列在7到12之间]*/ else if (Rank < 13) { /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->SQR2; /* Calculate the mask to clear [计算需要清除的标志]*/ tmpreg2 = SQR2_SQ_Set << (5 * (Rank - 7)); /* Clear the old SQx bits for the selected rank [根据选择的序列清除旧的SQx位]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set [计算需要置位的标志]*/ tmpreg2 = (u32)ADC_Channel << (5 * (Rank - 7)); /* Set the SQx bits for the selected rank [根据选择的序列置位新的SQx位]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->SQR2 = tmpreg1; } /* For Rank 13 to 16 [序列在13到16之间]*/ else { /* Get the old register value [取得旧的寄存器值]*/ tmpreg1 = ADCx->SQR1; /* Calculate the mask to clear [计算需要清除的标志]*/ tmpreg2 = SQR1_SQ_Set << (5 * (Rank - 13)); /* Clear the old SQx bits for the selected rank [根据选择的序列清除旧的SQx位]*/ tmpreg1 &= ~tmpreg2; /* Calculate the mask to set [计算需要置位的标志]*/ tmpreg2 = (u32)ADC_Channel << (5 * (Rank - 13)); /* Set the SQx bits for the selected rank [根据选择的序列置位新的SQx位]*/ tmpreg1 |= tmpreg2; /* Store the new register value [存储新的寄存器值]*/ ADCx->SQR1 = tmpreg1; } }