Alex_Golubev 0 9 мая, 2018 Опубликовано 9 мая, 2018 · Жалоба Привет. Столкнулся с проблемой калибровки 12 битного АЦП stm32f373. Делаю как написано в rm0313. При выключенном бите ADON = 0; Пишу следующий код: Код ADC1->CR2 |= ADC_CR2_CAL; // устанавливаю CAL в 1 while (ADC1->CR2 & ADC_CR2_CAL); // жду сброса CAL в 0 Программа зависает на строчки while (ADC1->CR2 & ADC_CR2_CAL); CAL в нуль не переходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 9 мая, 2018 Опубликовано 9 мая, 2018 · Жалоба В других чипах такой же АЦП рекомендуют во включенном состоянии калибровать, что более логично. Ну какая калибровка может быть, если АЦП в power down находится при ADON=0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex_Golubev 0 9 мая, 2018 Опубликовано 9 мая, 2018 · Жалоба Тогда не ясно почему в доки сказано: Note: It is recommended to perform a calibration after each power-up. Before starting a calibration the ADC must have been in power-off state (ADON bit = ‘0’) for at least two ADC clock cycles. И да при ADON = 1 все работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ataradov 0 9 мая, 2018 Опубликовано 9 мая, 2018 · Жалоба Это применимо если АЦП был включен и выполнял преобразования до этого. Калибровку нужно выполнять после выключения и включения. Ну и при калибровке при перезапуске он и так будет выключен естественно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 9 мая, 2018 Опубликовано 9 мая, 2018 · Жалоба Не поленился посмотреть как это в HAL сделано. Пробрался сквозь дебри калокуба. #if defined(STM32F373xC) || defined(STM32F378xx) /** * @brief Perform an ADC automatic self-calibration * Calibration prerequisite: ADC must be disabled (execute this * function before HAL_ADC_Start() or after HAL_ADC_Stop() ). * During calibration process, ADC is enabled. ADC is let enabled at * the completion of this function. * @param hadc ADC handle * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; uint32_t tickstart; __IO uint32_t wait_loop_index = 0U; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* 1. Calibration prerequisite: */ /* - ADC must be disabled for at least two ADC clock cycles in disable */ /* mode before ADC enable */ /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ tmp_hal_status = ADC_ConversionStop_Disable(hadc); /* Check if ADC is effectively disabled */ if (tmp_hal_status == HAL_OK) { /* Set ADC state */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_BUSY_INTERNAL); /* Wait two ADC clock cycles */ while(wait_loop_index < ADC_CYCLE_WORST_CASE_CPU_CYCLES *2U) { wait_loop_index++; } /* 2. Enable the ADC peripheral */ ADC_Enable(hadc); /* 3. Resets ADC calibration registers */ SET_BIT(hadc->Instance->CR2, ADC_CR2_RSTCAL); tickstart = HAL_GetTick(); /* Wait for calibration reset completion */ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL)) { if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) { /* Update ADC state machine to error */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_ERROR_INTERNAL); /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } /* 4. Start ADC calibration */ SET_BIT(hadc->Instance->CR2, ADC_CR2_CAL); tickstart = HAL_GetTick(); /* Wait for calibration completion */ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL)) { if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) { /* Update ADC state machine to error */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_ERROR_INTERNAL); /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } /* Set ADC state */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL, HAL_ADC_STATE_READY); } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; } /** * @brief Enable the selected ADC. * @note Prerequisite condition to use this function: ADC must be disabled * and voltage regulator must be enabled (done into HAL_ADC_Init()). * @param hadc ADC handle * @retval HAL status. */ static HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc) { uint32_t tickstart = 0U; __IO uint32_t wait_loop_index = 0U; /* ADC enable and wait for ADC ready (in case of ADC is disabled or */ /* enabling phase not yet completed: flag ADC ready not yet set). */ /* Timeout implemented to not be stuck if ADC cannot be enabled (possible */ /* causes: ADC clock not running, ...). */ if (ADC_IS_ENABLE(hadc) == RESET) { /* Enable the Peripheral */ __HAL_ADC_ENABLE(hadc); /* Delay for ADC stabilization time */ /* Compute number of CPU cycles to wait for */ wait_loop_index = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); while(wait_loop_index != 0U) { wait_loop_index--; } /* Get tick count */ tickstart = HAL_GetTick(); /* Wait for ADC effectively enabled */ while(ADC_IS_ENABLE(hadc) == RESET) { if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT) { /* Update ADC state machine to error */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); /* Set ADC error code to ADC IP internal error */ SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } } /* Return HAL status */ return HAL_OK; } /** * @brief Enable the ADC peripheral * @note ADC enable requires a delay for ADC stabilization time * (refer to device datasheet, parameter tSTAB) * @note On STM32F37x devices, if ADC is already enabled this macro trigs * a conversion SW start on regular group. * @param __HANDLE__ ADC handle * @retval None */ #define __HAL_ADC_ENABLE(__HANDLE__) \ (SET_BIT((__HANDLE__)->Instance->CR2, (ADC_CR2_ADON))) #endif /* STM32F373xC || STM32F378xx */ Включают они его, естественно, перед калибровкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба Тогда не ясно почему в доки сказано: Note: It is recommended to perform a calibration after each power-up. Before starting a calibration the ADC must have been in power-off state (ADON bit = ‘0’) for at least two ADC clock cycles. И да при ADON = 1 все работает. В доке всё чётко сказано. have been - это форма глагола Present Perfect, которая обозначает действие, полностью завершившееся к настоящему времени, то есть во время калибровки АЦП уже не должен быть в power-off. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба В доке всё чётко сказано. have been - это форма глагола Present Perfect, которая обозначает действие, полностью завершившееся к настоящему времени, то есть во время калибровки АЦП уже не должен быть в power-off. Сказано, что АЦП должен пробыть в выключенном состоянии, как минимум, два такта. Но не сказано, что уже надо включить. Хотя, похоже, надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба Сказано, что АЦП должен пробыть в выключенном состоянии, как минимум, два такта. Но не сказано, что уже надо включить. Хотя, похоже, надо. Да, здесь наверное более уместно было бы Past Perfect, надо у лингвистов спросить:). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 10 мая, 2018 Опубликовано 10 мая, 2018 · Жалоба Для STM32F303 я запускал калибровку перед включением АЦП. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andy_F 0 13 мая, 2018 Опубликовано 13 мая, 2018 · Жалоба У 373-го калибровка 12 битного ADC не работает (у меня, по крайней мере ) ). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 13 мая, 2018 Опубликовано 13 мая, 2018 (изменено) · Жалоба Для STM32F303 я запускал калибровку перед включением АЦП. а у меня в коде для STM32F303 /* Calibration procedure for ADC1*/ ADC_VoltageRegulatorCmd(ADC1, ENABLE); TIM_Delay_us(TIM6, 20); ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1) != RESET ); calibration_value1 = ADC_GetCalibrationValue(ADC1) /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); сначала калибруется потом включается. так неправильно? Изменено 13 мая, 2018 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 мая, 2018 Опубликовано 14 мая, 2018 · Жалоба а у меня в коде для STM32F303 ... сначала калибруется потом включается. так неправильно? А я разве не так написал? :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться