RTO1/UE/u01/src/BSP/Adc.c
2026-10-08 11:21:04 +02:00

103 lines
2.7 KiB
C

/**
******************************************************************************
* @file Adc.h
* @author Julian Grasböck
* @version V1.0.0
* @date 05.12.2017
* @brief Abstracts Adc handling.
* @copyright
* Copyright (c) FH OÖ Forschungs und Entwicklungs GmbH,
******************************************************************************
*/
#include "Adc.h"
#include "stm32f0xx_adc.h"
/****************************************************************
* User functions
***************************************************************/
/**
* Initializes the Adc in single conversion mode using the given channel
*/
int32_t Adc_Init(uint8_t const channel)
{
ADC_InitTypeDef adcInitStr;
/* Enable Adc peripheral clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* Initialize Adc configuration structure */
adcInitStr.ADC_Resolution = ADC_Resolution_12b;
adcInitStr.ADC_ContinuousConvMode = DISABLE;
adcInitStr.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
adcInitStr.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
adcInitStr.ADC_DataAlign = ADC_DataAlign_Right;
adcInitStr.ADC_ScanDirection = ADC_ScanDirection_Upward;
/* Initialize the Adc and the given channel */
ADC_Init(ADC1, &adcInitStr);
/* Enable Adc */
ADC_Cmd(ADC1, ENABLE);
return Adc_SetChannel(channel);
}
/**
* Function that triggers a conversion and returns the result
*/
int32_t Adc_GetValue(uint32_t const timeout)
{
int32_t const adcResolution = 12;
int32_t const adcReferenceVoltage = 3300;
int32_t ret = 0;
uint32_t cnt = 0;
/* Check if ADC is currently busy */
if (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADSTART) == SET)
{
return ADC_RETURN_BUSY;
}
/* Trigger conversion */
ADC_StartOfConversion(ADC1);
/* Wait until conversion is finished or timeout appears*/
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != SET)
{
cnt++;
/* Check if timout is reached */
if((timeout != 0) &&
(timeout == cnt))
{
return ADC_RETURN_TIMEOUT;
}
}
/* Get ADC value */
ret = (int32_t)(ADC_GetConversionValue(ADC1));
/* convert to milli voltage and return result */
return (ret * adcReferenceVoltage) / ((1 << adcResolution) - 1);
}
/**
* Function to set the Adc hardware channel that should be used
*/
int32_t Adc_SetChannel(uint8_t const channel)
{
uint8_t const numOfHardwareChannels = 19;
/* Check if vaild channel given */
if(channel > numOfHardwareChannels)
{
return ADC_RETURN_BAD_CHANNEL;
}
/* Set the conversion channel */
ADC1->CHSELR = (uint32_t)(1 << channel);
return ADC_RETURN_OK;
}