Microchip® Advanced Software Framework

Quick Start Guide for AC - Basic

In this use case, the Analog Comparator module is configured for:

  • Comparator peripheral in manually triggered (e.g. "Single Shot" mode)
  • One comparator channel connected to input MUX pin 0 and compared to a scaled VCC/2 voltage

This use case sets up the Analog Comparator to compare an input voltage fed into a GPIO pin of the device against a scaled voltage of the microcontroller's VCC power rail. The comparisons are made on-demand in single-shot mode, and the result stored into a local variable which is then output to the board LED to visually show the comparison state.

Setup

Prerequisites

There are no special setup requirements for this use-case.

Code

Copy-paste the following setup code to your user application:

/* AC module software instance (must not go out of scope while in use) */
static struct ac_module ac_instance;
/* Comparator channel that will be used */
#define AC_COMPARATOR_CHANNEL AC_CHAN_CHANNEL_0
void configure_ac(void)
{
/* Create a new configuration structure for the Analog Comparator settings
* and fill with the default module settings. */
struct ac_config config_ac;
/* Alter any Analog Comparator configuration settings here if required */
/* Initialize and enable the Analog Comparator with the user settings */
ac_init(&ac_instance, AC, &config_ac);
}
void configure_ac_channel(void)
{
/* Create a new configuration structure for the Analog Comparator channel
* settings and fill with the default module channel settings. */
struct ac_chan_config ac_chan_conf;
/* Set the Analog Comparator channel configuration settings */
ac_chan_conf.sample_mode = AC_CHAN_MODE_SINGLE_SHOT;
#if (SAMR30E)
ac_chan_conf.positive_input = AC_CHAN_POS_MUX_PIN2;
#else
ac_chan_conf.positive_input = AC_CHAN_POS_MUX_PIN0;
#endif
ac_chan_conf.negative_input = AC_CHAN_NEG_MUX_SCALED_VCC;
ac_chan_conf.vcc_scale_factor = 32;
/* Set up a pin as an AC channel input */
struct system_pinmux_config ac0_pin_conf;
ac0_pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
ac0_pin_conf.mux_position = CONF_AC_MUX;
system_pinmux_pin_set_config(CONF_AC_PIN, &ac0_pin_conf);
/* Initialize and enable the Analog Comparator channel with the user
* settings */
ac_chan_set_config(&ac_instance, AC_COMPARATOR_CHANNEL, &ac_chan_conf);
ac_chan_enable(&ac_instance, AC_COMPARATOR_CHANNEL);
}

Add to user application initialization (typically the start of main()):

configure_ac();
configure_ac_channel();
ac_enable(&ac_instance);

Workflow

  1. Create an AC device instance struct, which will be associated with an Analog Comparator peripheral hardware instance.
    static struct ac_module ac_instance;
    Note
    Device instance structures shall never go out of scope when in use.
  2. Define a macro to select the comparator channel that will be sampled, for convenience.
    #define AC_COMPARATOR_CHANNEL AC_CHAN_CHANNEL_0
  3. Create a new function configure_ac(), which will be used to configure the overall Analog Comparator peripheral.
    void configure_ac(void)
  4. Create an Analog Comparator peripheral configuration structure that will be filled out to set the module configuration.
    struct ac_config config_ac;
  5. Fill the Analog Comparator peripheral configuration structure with the default module configuration values.
  6. Initialize the Analog Comparator peripheral and associate it with the software instance structure that was defined previously.
    ac_init(&ac_instance, AC, &config_ac);
  7. Create a new function configure_ac_channel(), which will be used to configure the overall Analog Comparator peripheral.
    void configure_ac_channel(void)
  8. Create an Analog Comparator channel configuration structure that will be filled out to set the channel configuration.
    struct ac_chan_config ac_chan_conf;
  9. Fill the Analog Comparator channel configuration structure with the default channel configuration values.
  10. Alter the channel configuration parameters to set the channel to one-shot mode, with the correct negative and positive MUX selections and the desired voltage scaler.
    ac_chan_conf.sample_mode = AC_CHAN_MODE_SINGLE_SHOT;
    #if (SAMR30E)
    ac_chan_conf.positive_input = AC_CHAN_POS_MUX_PIN2;
    #else
    ac_chan_conf.positive_input = AC_CHAN_POS_MUX_PIN0;
    #endif
    ac_chan_conf.negative_input = AC_CHAN_NEG_MUX_SCALED_VCC;
    ac_chan_conf.vcc_scale_factor = 32;
    Note
    The voltage scalar formula is documented in description for ac_chan_config::vcc_scale_factor.
  11. Configure the physical pin that will be routed to the AC module channel 0.
    struct system_pinmux_config ac0_pin_conf;
    ac0_pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
    ac0_pin_conf.mux_position = CONF_AC_MUX;
    system_pinmux_pin_set_config(CONF_AC_PIN, &ac0_pin_conf);
  12. Initialize the Analog Comparator channel and configure it with the desired settings.
    ac_chan_set_config(&ac_instance, AC_COMPARATOR_CHANNEL, &ac_chan_conf);
  13. Enable the now initialized Analog Comparator channel.
    ac_chan_enable(&ac_instance, AC_COMPARATOR_CHANNEL);
  14. Enable the now initialized Analog Comparator peripheral.
    ac_enable(&ac_instance);

Implementation

Code

Copy-paste the following code to your user application:

ac_chan_trigger_single_shot(&ac_instance, AC_COMPARATOR_CHANNEL);
uint8_t last_comparison = AC_CHAN_STATUS_UNKNOWN;
while (true) {
if (ac_chan_is_ready(&ac_instance, AC_COMPARATOR_CHANNEL)) {
do {
last_comparison = ac_chan_get_status(&ac_instance,
AC_COMPARATOR_CHANNEL);
} while (last_comparison & AC_CHAN_STATUS_UNKNOWN);
(last_comparison & AC_CHAN_STATUS_NEG_ABOVE_POS));
ac_chan_trigger_single_shot(&ac_instance, AC_COMPARATOR_CHANNEL);
}
}

Workflow

  1. Trigger the first comparison on the comparator channel.
    ac_chan_trigger_single_shot(&ac_instance, AC_COMPARATOR_CHANNEL);
  2. Create a local variable to maintain the current comparator state. Since no comparison has taken place, it is initialized to AC_CHAN_STATUS_UNKNOWN.
    uint8_t last_comparison = AC_CHAN_STATUS_UNKNOWN;
  3. Make the application loop infinitely, while performing triggered comparisons.
    while (true) {
  4. Check if the comparator is ready for the last triggered comparison result to be read.
    if (ac_chan_is_ready(&ac_instance, AC_COMPARATOR_CHANNEL)) {
  5. Read the comparator output state into the local variable for application use, re-trying until the comparison state is ready.
    do {
    last_comparison = ac_chan_get_status(&ac_instance,
    AC_COMPARATOR_CHANNEL);
    } while (last_comparison & AC_CHAN_STATUS_UNKNOWN);
  6. Set the board LED state to mirror the last comparison state.
    (last_comparison & AC_CHAN_STATUS_NEG_ABOVE_POS));
  7. Trigger the next conversion on the Analog Comparator channel.
    ac_chan_trigger_single_shot(&ac_instance, AC_COMPARATOR_CHANNEL);