Below is a code example showing the configuration of the ADC as an event
generator and an event user:
- Event user: ADC conversion triggered by
RTC overflow event
- RTC is configured to
generate an RTC overflow event at the desired ADC sampling rate. The
sampling rate in the example is 100 Hz.
- ADC conversion is
triggered at a rate of 100 Hz and the result is read when the Result
Ready (RESRDY) bit in the Interrupt Flags (ADCn.INTFLAGS) register is
set.
- Event generator: Pin PB2 outputs an event
(Pulse) when the ADC result is ready
#define F_CPU 3333333ul
#include <avr/io.h>
#include <math.h>
#define TIMEBASE_VALUE ((uint8_t) ceil(F_CPU*0.000001))
#define ADC_MAX_VALUE (((1 << 12) / 2) - 1)
#define ADC_SAMPLING_FREQ 100
#define RTC_CLOCK 32768
#define RTC_PERIOD (RTC_CLOCK / ADC_SAMPLING_FREQ)
static volatile int32_t adc_reading;
static volatile float voltage;
void event_system_init(void)
{
PORTB.DIRSET = PIN2_bm;
EVSYS.CHANNEL0 = EVSYS_CHANNEL0_RTC_OVF_gc;
EVSYS.USERADC0START = EVSYS_USER_CHANNEL0_gc;
EVSYS.CHANNEL1 = EVSYS_CHANNEL1_ADC0_RES_gc;
EVSYS.USEREVSYSEVOUTB = EVSYS_USER_CHANNEL1_gc;
}
void rtc_init(void)
{
while(RTC.STATUS > 0);
RTC.CTRLA = RTC_PRESCALER_DIV1_gc | RTC_RTCEN_bm;
RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;
RTC.PER = RTC_PERIOD;
while(RTC.STATUS > 0);
}
void adc_init()
{
ADC0.CTRLA = ADC_ENABLE_bm;
ADC0.CTRLB = ADC_PRESC_DIV2_gc;
ADC0.CTRLC = ADC_REFSEL_VDD_gc | (TIMEBASE_VALUE << ADC_TIMEBASE_gp);
ADC0.CTRLE = 17;
ADC0.MUXPOS = ADC_MUXPOS_AIN6_gc;
ADC0.MUXNEG = ADC_MUXNEG_AIN7_gc;
ADC0.COMMAND = ADC_DIFF_bm | ADC_MODE_SINGLE_12BIT_gc | ADC_START_EVENT_TRIGGER_gc;
}
int main(void)
{
event_system_init();
rtc_init();
adc_init();
while(1)
{
if(ADC0.INTFLAGS & ADC_RESRDY_bm)
{
adc_reading = ADC0.RESULT;
voltage = (float)((adc_reading * 3.3) / ADC_MAX_VALUE);
}
}
}