Hi friends!!
After a some period of using the EFM32 boards, I changed my work and moved to another interesting things.
So it’s my last article about the EFM32.

ADC (Analog-to-Digital Converter) converts voltage on the one or more of its input pins and return the corresponding value.
Little explanation:
Lets say, our Vref is 3.3V, and we have 12 bit ADC.
Lets calculate how many values ADC can return: 2 ^ 12 = 4096.
It means, that ADC can return values from 0 to 4095.
Lets calculate what the meaning of the each value: Vref (mV) / 4096 => 3300 / 4096 = 0.806 mV
Each value is corresponding to 0.806 mV.

Here, a real simple code, that you can use if you want to measure something simple.
For this example I’m using for EFM32G890F128 MCU.
File main.c:

#include "autogen_adc0.h"

volatile uint32_t adc_value;
volatile uint8_t adc_measurement_ready=0;

int main(void)
{
  /* Initialize chip */
  // For quick chip initialization I use for eDesigner from Silicon Labs.
  // You can find it in Simplicity Studio (free Silicon Labs Ide)
  // Full configuration you'll find below
  eADesigner_Init();

  while(1) {
      ADC_Start(ADC0, adcStartSingle); // Make ADC measure once
      while(adc_measurement_ready==0) {__NOP();} // Wait until ADC interrupt
      /* !!! here measurement is ready and you can use it !!! */
      for(uint32_t i=0; i< 2000000; i++) {__NOP();} // delay
      adc_measurement_ready=0; // resets flag
  }
  return 0; 
}

void ADC0_IRQHandler() {
    uint32_t flags = ADC_IntGet(ADC0); // get all interrupt flags
    if(ADC_IntGet(ADC0) & ADC_IF_SINGLE) { // if interrupt is for single measurement
        ADC_IntClear(ADC0, flags); // clear the interrupt
        adc_value = ADC_DataSingleGet(ADC0); // get the measured value
        adc_measurement_ready=1; // set ready flag
    }
}

File autogen_adc0.h:

#include "em_adc.h"

#ifndef ADC0_H
#define ADC0_H

void ADC0_setup(void);
void eADesigner_Init(void);

#endif

File autogen_adc0.c:

#include "em_cmu.h"
#include "autogen_adc0.h"

void ADC0_setup(void)
{
  // ADC was initialized in eDesigner from Silicon Labs.
  // If will be any questions about the values, please write it into comments and I'll answer you :)
  ADC_Init_TypeDef init = ADC_INIT_DEFAULT; //set variable to default values
  init.ovsRateSel = adcOvsRateSel2;
  init.lpfMode    = adcLPFilterBypass;
  init.warmUpMode = adcWarmupKeepADCWarm; //keep adc warm - high power consumption
  init.timebase   = ADC_TimebaseCalc(0);
  init.prescale   = ADC_PrescaleCalc(7000000, 0);
  init.tailgate   = 0;
  ADC_Init(ADC0, &init);

  // !!! Initialize a single sample conversion. !!!
  // To start a conversion, use ADC_Start().
  // Conversion result can be read with ADC_DataSingleGet().
  ADC_InitSingle_TypeDef initSingle = ADC_INITSINGLE_DEFAULT;
  initSingle.prsSel     = adcPRSSELCh0;
  initSingle.acqTime    = adcAcqTime8;
  initSingle.reference  = adcRef1V25;
  initSingle.resolution = adcRes12Bit;
  initSingle.input      = adcSingleInpCh1;
  initSingle.diff       = 0;
  initSingle.prsEnable  = 0;
  initSingle.leftAdjust = 0;
  initSingle.rep        = 0;
  ADC_InitSingle(ADC0, &initSingle);

  ADC_IntEnable(ADC0, ADC_IF_SINGLE); // Enable interrupt for single conversion

  NVIC_EnableIRQ(ADC0_IRQn); // Enable ADC0 interrupt
}

void eADesigner_Init(void)
{
  /* Using HFRCO at 14MHz as high frequency clock, HFCLK */
  CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
  /* No low frequency clock source selected */
  /* Enable clock for ADC0 */
  CMU_ClockEnable(cmuClock_ADC0, true);
  /* Custom initialization for ADC0 */
  ADC0_setup();  
}

That’s all for now!
Bye! 🙂