EFM32目前ADC的工作方式有两种,一种是single模式,一种是Scan模式。
Single模式是单通道转换模式,Scan是多通道转换模式。
在Single模式中,由于是单通道应用,因此就会遇到如何切换ADC通道的问题。
以下是一个在ADC Single 模式下切换ADC通道的例程。
硬件准备:TG STK, 会将ADC转换的值显示在LCD段码屏上。
软件例程:
#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_TimebaseCalc(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_PrescaleCalc(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 should be safe for all ADC clock frequencies */
singleInit.acqTime = adcAcqTime32;
ADC_InitSingle(ADC0, &singleInit);
}
//ADC通道切换函数
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; //假设Vdd=3.2V
/* Write to LCD */
char buffer[10];
sprintf(buffer, "%1.4f", voltage);
SegmentLCD_Write(buffer);
/* wait 100ms 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; //假设Vdd=3.2V
/* Write to LCD */
buffer[10];
sprintf(buffer, "%1.4f", voltage);
SegmentLCD_Write(buffer);
/* wait 100ms in EM2 before next conversion */
RTC_Trigger(1000, NULL);
EMU_EnterEM2(true);
}
}