4 AC Signal Frequency Detection
The AVR DA family features an Event System (EVSYS), enabling inter-peripheral communication without using interrupts or CPU. It allows a change in one peripheral (the event generator) to trigger actions in other peripherals (the event users) through event channels. The EVSYS provides short latency-free and predictable communication between peripherals and can reduce the complexity, size, and execution time of the software, to save power.
The next application example shows an implementation of duration/frequency measurement for an AC input signal, with minimal usage of microcontroller power. It uses the EVSYS to route the signals from the ZCD output through an event channel to Timer Counter B (TCB) event input. To do this, the EVSYS must be configured properly. This measurement can be done only with ZCD, as the Analog Comparator does not allow negative voltages on its inputs.
The first step in the EVSYS configuration is to set the ZCD output as an event generator for channel 0:
For EVSYS channel 0, the Channel Generator Selection register must be loaded
with 0x30
to enable ZCD0 as event generator:
EVSYS.CHANNEL0 = EVSYS_CHANNEL0_ZCD0_gc;
To trigger events on the TCB input, the TCB event user must be connected to channel 0:
EVSYS.USERTCB0CAPT = EVSYS_CHANNEL00_bm;
To enable frequency measurement, the TCB is configured in Frequency Measurement mode, having the EVSYS as input, which is used to route the ZCD0 output through event channel 0 to the TCB event input. In the Input Capture Frequency Measurement mode, the TCB captures the counter value and restarts on either a positive or negative edge of the event input signal. The CAPT Interrupt flag is automatically cleared after the low byte of the Compare/Capture (TCBn.CCMP) register has been read. An OVF interrupt and event is generated when the CNT reaches maximum value.
The following code provides a basic initialization for the TCB in Frequency Measurement mode with EVSYS as input:
void TCB_Init (void) { TCB0.CTRLB = TCB_CNTMODE_FRQ_gc; TCB0.EVCTRL = TCB_CAPTEI_bm; TCB0.INTCTRL = TCB_CAPT_bm; TCB0.CTRLA = TCB_CLKSEL_DIV2_gc | TCB_ENABLE_bm | TCB_RUNSTDBY_bm; }
For this example, the MCU internal clock is set to 4 MHz, and the clock select of the TCB is divided by 2 to be able to count until 40 Hz without having an overflow. If the same result is needed with a 20 MHz internal clock, then Timer Counter A (TCA) can be used to divide the clock further with its prescaler and use the TCA clock as a clock source to the TCB.