Перейти к содержанию

STM32F373 ADC 12 BIT калибровка

Привет.
Столкнулся с проблемой калибровки 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 в нуль не переходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В других чипах такой же АЦП рекомендуют во включенном состоянии калибровать, что более логично. Ну какая калибровка может быть, если АЦП в power down находится при ADON=0.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Тогда не ясно почему в доки сказано:
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 все работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Это применимо если АЦП был включен и выполнял преобразования до этого. Калибровку нужно выполнять после выключения и включения. Ну и при калибровке при перезапуске он и так будет выключен естественно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Не поленился посмотреть как это в HAL сделано. Пробрался сквозь дебри калокуба.

CODE
#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 */


Включают они его, естественно, перед калибровкой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Alex_Golubev @ May 9 2018, 06:27) <{POST_SNAPBACK}>
Тогда не ясно почему в доки сказано:
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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Timmy @ May 10 2018, 09:21) <{POST_SNAPBACK}>
В доке всё чётко сказано. have been - это форма глагола Present Perfect, которая обозначает действие, полностью завершившееся к настоящему времени, то есть во время калибровки АЦП уже не должен быть в power-off.

Сказано, что АЦП должен пробыть в выключенном состоянии, как минимум, два такта. Но не сказано, что уже надо включить. Хотя, похоже, надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(ViKo @ May 10 2018, 10:15) <{POST_SNAPBACK}>
Сказано, что АЦП должен пробыть в выключенном состоянии, как минимум, два такта. Но не сказано, что уже надо включить. Хотя, похоже, надо.

Да, здесь наверное более уместно было бы Past Perfect, надо у лингвистов спроситьsm.gif.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Для STM32F303 я запускал калибровку перед включением АЦП.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
У 373-го калибровка 12 битного ADC не работает (у меня, по крайней мере ) ).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(ViKo @ May 10 2018, 16:49) <{POST_SNAPBACK}>
Для 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);
сначала калибруется потом включается. так неправильно?
Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Jenya7 @ May 13 2018, 23:24) <{POST_SNAPBACK}>
а у меня в коде для STM32F303
...
сначала калибруется потом включается. так неправильно?

А я разве не так написал? rolleyes.gif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти