EFM32 currently supports two ADC modes: single mode and Scan mode.
Single mode is a Single-channel conversion mode, while Scan is a multi-channel conversion mode.
In Single mode, because it is a Single-channel application, you will encounter the problem of how to switch the ADC channel.
The following is a routine for switching the ADC channel in ADC Single mode.
Hardware preparation: tg stk. The ADC conversion value is displayed on the LCD screen.
Software routine:
# Include <stdio. h>
# Include "efm32.h"
# Include "em_chip.h"
# Include "em_emu.h"
# Include "em_cmu.h"
# Include "em_adc.h"
# Include "em_ LCD .h"
# Include "segmentlcd. h"
# Include "rtc. h"
/*************************************** ************************************//**
* @ Brief
* Configure ADC usage for this application.
**************************************** ***************************************/
Static void ADCConfig (void)
{
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
/* Init common settings for both single conversion and scan mode */
Init. timebase = adc_timebasec1c (0 );
/* Might as well finish conversion as quickly as possibly since polling */
/* For completion .*/
/* Set ADC clock to 7 MHz, use default HFPERCLK */
Init. prescale = adc_prescalec1c (200000, 0 );
/* WARMUPMODE must be set to Normal according to ref manual before */
/* Entering EM2. In this example, the warmup time is not a big problem */
/* Due to relatively infrequent polling. Leave at default NORMAL ,*/
ADC_Init (ADC0, & init );
/* Init for single conversion use, measure VDD/3 with 1.25 reference .*/
SingleInit. reference = adcRefVDD;
SingleInit. input = adcSingleInpVDDDiv3;
SingleInit. resolution = adcRes12Bit;
/* The datasheet specifies a minimum aquisition time when sampling vdd/3 */
/* 32 cycles shoshould be safe for all ADC clock frequencies */
SingleInit. acqTime = adcAcqTime32;
ADC_InitSingle (ADC0, & singleInit );
}
// ADC channel switching function
Void ADC_Switch_Channel (ADC_SingleInput_TypeDef input)
{
/* Make sure single conversion is not in progress */
ADC0-> CMD = ADC_CMD_SINGLESTOP;
/* Clear the input channel */
Adc0-> singlectrl & = ~ _ Adc_singlectrl_inputsel_mask;
/* Update the input channel */
Adc0-> singlectrl | = input <_ adc_singlectrl_inputsel_shift;
}
/*************************************** ***************************************
* @ Brief Main Function
* The ADC is set up in single conversion mode and samples VDD/3 10 times each
* Second, it sleeps in EM2 between samples. The supply voltage (VDD) is then
* Calculated.
**************************************** *************************************/
Int main (void)
{
/* Initialize chip */
Chip_init ();
Segmentlcd_init (false );
Uint32_t sample;
Double voltage;
/* Enable clocks required */
CMU_ClockEnable (cmuClock_HFPER, true );
CMU_ClockEnable (cmuClock_ADC0, true );
ADCConfig ();
/* Stay in this loop forever at end of program */
While (1)
{
ADC_Switch_Channel (adcSingleInpVDDDiv3 );
ADC_Start (ADC0, adcStartSingle );
/* Wait while conversion is active */
While (ADC0-> STATUS & ADC_STATUS_SINGLEACT );
/* Get ADC result */
Sample = ADC_DataSingleGet (ADC0 );
/* Calculate supply voltage */
Voltage = (sample * 3.2)/4096; // assume Vdd = 3.2 V
/* Write to LCD */
Char buffer [10];
Sprintf (buffer, "% 1.4f", voltage );
SegmentLCD_Write (buffer );
/* Wait 100 ms in EM2 before next conversion */
RTC_Trigger (1000, NULL );
EMU_EnterEM2 (true );
ADC_Switch_Channel (adcSingleInpVDD );
ADC_Start (ADC0, adcStartSingle );
/* Wait while conversion is active */
While (ADC0-> STATUS & ADC_STATUS_SINGLEACT );
/* Get ADC result */
Sample = ADC_DataSingleGet (ADC0 );
/* Calculate supply voltage */
Voltage = (sample * 3.2)/4096; // assume Vdd = 3.2 V
/* Write to LCD */
Buffer [10];
Sprintf (buffer, "% 1.4f", voltage );
SegmentLCD_Write (buffer );
/* Wait 100 ms in EM2 before next conversion */
RTC_Trigger (1000, NULL );
EMU_EnterEM2 (true );
}
}