O7/Core/Src/adc_if.c

226 lines
6.5 KiB
C
Raw Normal View History

2024-04-08 14:23:48 +08:00
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc_if.c
* @author MCD Application Team
* @brief Read status related to the chip (battery level, VREF, chip temperature)
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "adc_if.h"
#include "sys_app.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* External variables ---------------------------------------------------------*/
/**
* @brief ADC handle
*/
extern ADC_HandleTypeDef hadc;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
#define TEMPSENSOR_TYP_CAL1_V (( int32_t) 760) /*!< Internal temperature sensor, parameter V30 (unit: mV). Refer to device datasheet for min/typ/max values. */
#define TEMPSENSOR_TYP_AVGSLOPE (( int32_t) 2500) /*!< Internal temperature sensor, parameter Avg_Slope (unit: uV/DegCelsius). Refer to device datasheet for min/typ/max values. */
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/**
* @brief This function reads the ADC channel
* @param channel channel number to read
* @return adc measured level value
*/
static uint32_t ADC_ReadChannels(uint32_t channel);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Exported functions --------------------------------------------------------*/
/* USER CODE BEGIN EF */
/* USER CODE END EF */
void SYS_InitMeasurement(void)
{
/* USER CODE BEGIN SYS_InitMeasurement_1 */
/* USER CODE END SYS_InitMeasurement_1 */
hadc.Instance = ADC;
/* USER CODE BEGIN SYS_InitMeasurement_2 */
/* USER CODE END SYS_InitMeasurement_2 */
}
void SYS_DeInitMeasurement(void)
{
/* USER CODE BEGIN SYS_DeInitMeasurement_1 */
/* USER CODE END SYS_DeInitMeasurement_1 */
}
int16_t SYS_GetTemperatureLevel(void)
{
/* USER CODE BEGIN SYS_GetTemperatureLevel_1 */
/* USER CODE END SYS_GetTemperatureLevel_1 */
__IO int16_t temperatureDegreeC = 0;
uint32_t measuredLevel = 0;
uint16_t batteryLevelmV = SYS_GetBatteryLevel();
measuredLevel = ADC_ReadChannels(ADC_CHANNEL_TEMPSENSOR);
/* convert ADC level to temperature */
/* check whether device has temperature sensor calibrated in production */
if (((int32_t)*TEMPSENSOR_CAL2_ADDR - (int32_t)*TEMPSENSOR_CAL1_ADDR) != 0)
{
/* Device with temperature sensor calibrated in production:
use device optimized parameters */
temperatureDegreeC = __LL_ADC_CALC_TEMPERATURE(batteryLevelmV,
measuredLevel,
LL_ADC_RESOLUTION_12B);
}
else
{
/* Device with temperature sensor not calibrated in production:
use generic parameters */
temperatureDegreeC = __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(TEMPSENSOR_TYP_AVGSLOPE,
TEMPSENSOR_TYP_CAL1_V,
TEMPSENSOR_CAL1_TEMP,
batteryLevelmV,
measuredLevel,
LL_ADC_RESOLUTION_12B);
}
/* from int16 to q8.7*/
temperatureDegreeC <<= 8;
return (int16_t) temperatureDegreeC;
/* USER CODE BEGIN SYS_GetTemperatureLevel_2 */
/* USER CODE END SYS_GetTemperatureLevel_2 */
}
uint16_t SYS_GetBatteryLevel(void)
{
/* USER CODE BEGIN SYS_GetBatteryLevel_1 */
/* USER CODE END SYS_GetBatteryLevel_1 */
uint16_t batteryLevelmV = 0;
uint32_t measuredLevel = 0;
measuredLevel = ADC_ReadChannels(ADC_CHANNEL_VREFINT);
if (measuredLevel == 0)
{
batteryLevelmV = 0;
}
else
{
if ((uint32_t)*VREFINT_CAL_ADDR != (uint32_t)0xFFFFU)
{
/* Device with Reference voltage calibrated in production:
use device optimized parameters */
batteryLevelmV = __LL_ADC_CALC_VREFANALOG_VOLTAGE(measuredLevel,
ADC_RESOLUTION_12B);
}
else
{
/* Device with Reference voltage not calibrated in production:
use generic parameters */
batteryLevelmV = (VREFINT_CAL_VREF * 1510) / measuredLevel;
}
}
return batteryLevelmV;
/* USER CODE BEGIN SYS_GetBatteryLevel_2 */
/* USER CODE END SYS_GetBatteryLevel_2 */
}
/* Private Functions Definition -----------------------------------------------*/
/* USER CODE BEGIN PrFD */
/* USER CODE END PrFD */
static uint32_t ADC_ReadChannels(uint32_t channel)
{
/* USER CODE BEGIN ADC_ReadChannels_1 */
/* USER CODE END ADC_ReadChannels_1 */
uint32_t ADCxConvertedValues = 0;
ADC_ChannelConfTypeDef sConfig = {0};
MX_ADC_Init();
/* Start Calibration */
if (HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK)
{
Error_Handler();
}
/* Configure Regular Channel */
sConfig.Channel = channel;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start(&hadc) != HAL_OK)
{
/* Start Error */
Error_Handler();
}
/** Wait for end of conversion */
HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
/** Wait for end of conversion */
HAL_ADC_Stop(&hadc); /* it calls also ADC_Disable() */
ADCxConvertedValues = HAL_ADC_GetValue(&hadc);
HAL_ADC_DeInit(&hadc);
return ADCxConvertedValues;
/* USER CODE BEGIN ADC_ReadChannels_2 */
/* USER CODE END ADC_ReadChannels_2 */
}