2023-05-30 03:56 AM
Hello,
I have successfully setup ADC3 to measure values on channels PC2_C, PC3_C, temperature, ... on STM32H753ZIT6
And now I want to add ADC1 to measure other channels. But the program waits for the LL_ADC_IsActiveFlag_ADRDY flag. My init function for ADC1 is here:
void init_adc1(void) {
LL_ADC_InitTypeDef ADC_InitStruct = { 0 };
LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = { 0 };
LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = { 0 };
LL_GPIO_InitTypeDef GPIO_InitStruct = { 0 };
// PA0 is input ADC
GPIO_InitStruct.Pin = LL_GPIO_PIN_0;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_3 | LL_GPIO_PIN_4 | LL_GPIO_PIN_5 | LL_GPIO_PIN_6;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Common config */
ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_16B;
ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS;
ADC_REG_InitStruct.SequencerDiscont = DISABLE;
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;
ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);
ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV2;
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
/* Disable ADC deep power down (enabled by default after reset state) */
LL_ADC_DisableDeepPowerDown(ADC1);
/* Enable ADC internal voltage regulator */
LL_ADC_EnableInternalRegulator(ADC1);
/* Delay for ADC internal voltage regulator stabilization. */
/* Compute number of CPU cycles to wait for, from delay in us. */
/* Note: Variable divided by 2 to compensate partially */
/* CPU processing cycles (depends on compilation optimization). */
/* Note: If system core clock frequency is below 200kHz, wait time */
/* is only a few CPU processing cycles. */
BSP_Wait_USec(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US + 1);
/* channel 10 - PC0
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_10);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_387CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_10, LL_ADC_SINGLE_ENDED);
/* channel 15 - PA3
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_15);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_387CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED);
/* channel 18 - PA4
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_18);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_18, LL_ADC_SAMPLINGTIME_387CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_18, LL_ADC_SINGLE_ENDED);
/* channel 19 - PA5
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_19);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_19, LL_ADC_SAMPLINGTIME_387CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_19, LL_ADC_SINGLE_ENDED);
/* channel 3 - PA6
*/
LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_3);
LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SAMPLINGTIME_387CYCLES_5);
LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SINGLE_ENDED);
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_CLOCK_ASYNC_DIV1);
LL_ADC_SetBoostMode(ADC1, LL_ADC_BOOST_MODE_25MHZ); // 20..25 MHz
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_VREFINT);
LL_ADC_StartCalibration(ADC1, LL_ADC_CALIB_OFFSET, LL_ADC_SINGLE_ENDED);
while (LL_ADC_IsCalibrationOnGoing(ADC1) != RESET)
;
/* Set ADC Channel, this is important */
LL_ADC_SetChannelPreSelection(ADC1, LL_ADC_CHANNEL_10); // PC0
LL_ADC_SetChannelPreSelection(ADC1, LL_ADC_CHANNEL_15); // PA3
LL_ADC_SetChannelPreSelection(ADC1, LL_ADC_CHANNEL_18); // PA4
LL_ADC_SetChannelPreSelection(ADC1, LL_ADC_CHANNEL_19); // PA5
LL_ADC_SetChannelPreSelection(ADC1, LL_ADC_CHANNEL_3); // PA6
LL_ADC_Enable(ADC1);
}
And for measure:
void ADC1_Measure_Values(uint32_t Voltages[]) {
while (LL_ADC_IsActiveFlag_ADRDY(ADC1) == 0){
// todo some timeout
}
LL_ADC_REG_StartConversion(ADC1);
// TODO 5 is number of n convertion.
for (uint8_t i = 0; i < 5; i++) {
while (LL_ADC_IsActiveFlag_EOC(ADC1) == 0) {
// todo some timeout
}
LL_ADC_ClearFlag_EOC(ADC1);
ADC_Val[i] = LL_ADC_REG_ReadConversionData16(ADC1);
}
LL_ADC_REG_StopConversion(ADC1);
Voltages[0] = __LL_ADC_CALC_DATA_TO_VOLTAGE(VRefInt, ADC_Val[0], LL_ADC_GetResolution(ADC1));
Voltages[1] = __LL_ADC_CALC_DATA_TO_VOLTAGE(VRefInt, ADC_Val[1], LL_ADC_GetResolution(ADC1));
Voltages[2] = __LL_ADC_CALC_DATA_TO_VOLTAGE(VRefInt, ADC_Val[2], LL_ADC_GetResolution(ADC1));
Voltages[3] = __LL_ADC_CALC_DATA_TO_VOLTAGE(VRefInt, ADC_Val[3], LL_ADC_GetResolution(ADC1));
Voltages[4] = __LL_ADC_CALC_DATA_TO_VOLTAGE(VRefInt, ADC_Val[4], LL_ADC_GetResolution(ADC1));
}
Init clock. For ADC1 and ADC3 I set 24MHz pherip speed.
void init_clock(void) {
LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_ADC12);
LL_AHB4_GRP1_ForceReset(LL_AHB4_GRP1_PERIPH_ADC3);
__NOP();
__NOP();
__NOP();
__NOP();
LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_ADC12);
LL_AHB4_GRP1_ReleaseReset(LL_AHB4_GRP1_PERIPH_ADC3);
// enable
LL_AHB4_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_ADC12);
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_ADC3);
}
I'm looking into the registries now, but the setup is already quite complicated. Any idea, what is wrong?