Microchip® Advanced Software Framework

Quick start guide for the XMEGA AC driver

This is the quick start guide for the AC Driver, with step-by-step instructions on how to configure and use the driver for specific use cases.

The section described below can be compiled into e.g. the main application loop or any other function that might use the AC functionality.

Basic use case of the AC driver

In the basic use case, the Analog Comparator driver is set up to compare an input voltage to the voltage VCC/2. If the voltage is below VCC/2, LED0 is lit up. If it is above VCC/2, LED 1 is lit.

Prerequisites

This basic example uses the XMEGA interrupt functionality, and therefore the Programmable Multilevel Interrupt Controller PMIC driver must be included. The General Purpose Input/Output driver must also be included to be able to control the LEDs.

You must also enable the AC pins, this is done by defining:

#define CONF_BOARD_ENABLE_AC_PINS

in your source code.

The memset() function used to zero out our configuration structure is located in string.h, so we must include it:

#include <string.h>

Setup

Code

#define VOLTAGE_SCALED_VALUE 32
void ac_init()
{
struct ac_config aca_config;
memset(&aca_config, 0, sizeof(struct ac_config));
ac_set_mode(&aca_config, AC_MODE_SINGLE);
ac_set_voltage_scaler(&aca_config, VOLTAGE_SCALED_VALUE);
ac_set_hysteresis(&aca_config, AC_HYSMODE_LARGE_gc);
ac_set_negative_reference(&aca_config, AC_MUXNEG_SCALER_gc);
ac_set_positive_reference(&aca_config, AC_MUXPOS_PIN1_gc);
ac_set_interrupt_callback(&ACA, example_ac_window_interrupt);
ac_write_config(&ACA, 0, &aca_config);
ac_enable(&ACA, 0);
}

Add to main():

ac_init();

Workflow

We define how much we wish to scale the voltage:

#define VOLTAGE_SCALED_VALUE 32

We create a structure to store the configuration data for the AC:

struct ac_config aca_config;

We zero out the aca_config struct:

memset(&aca_config, 0, sizeof(struct ac_config));
Attention
This step is important, as uninitialized values in the struct may cause strange and unwanted behavior.

First, we set the AC mode for the ACA comparator to single operation.

We set the reference voltage to VCC/2 (scaler 32/64):

ac_set_voltage_scaler(&aca_config, VOLTAGE_SCALED_VALUE-1);

We enable hysteresis, to avoid flickering due to disturbances:

ac_set_hysteresis(&aca_config, AC_HYSMODE_LARGE_gc);

We set the negative reference to be our scaled voltage, and the positive reference to be the positive reference:

ac_set_negative_reference(&aca_config, AC_MUXNEG_SCALER_gc);
ac_set_positive_reference(&aca_config, AC_MUXPOS_PIN1_gc);

We set the interrupt mode to call the interrupt function on both edges, the interrupt level to medium, and set the callback function:

ac_set_interrupt_callback(&ACA, example_ac_window_interrupt);

We write the configuration to the AC A channel 0, and enable it:

ac_write_config(&ACA, 0, &aca_config);
ac_enable(&ACA, 0);

Finally, we must enable interrupts:

Use case

The example itself is handled by the interrupt callback, which switches the LEDS according to the AC status:

Example code

* static void example_ac_window_interrupt(AC_t *ac, uint8_t channel,
* enum ac_status_t status)
* {
* gpio_set_pin_high(LED0_GPIO);
* gpio_set_pin_high(LED1_GPIO);
* switch (status) {
* gpio_set_pin_low(LED0_GPIO);
* break;
* gpio_set_pin_low(LED1_GPIO);
* break;
* default: break;
* }
* }

Workflow

We switch the LEDS off:

gpio_set_pin_high(LED0_GPIO);
gpio_set_pin_high(LED1_GPIO);

We turn on LEDS according to where the AC reads our PIN to be in relation to the reference.

switch (status) {
gpio_set_pin_low(LED0_GPIO);
break;
gpio_set_pin_low(LED1_GPIO);
break;
default: break;
}
Note
This interrupt function is called every time the AC sees a change on the AC output (rising or falling).