Microchip® Advanced Software Framework

Quick start guide for XMEGA DAC

This is the quick start guide for the Digital to Analog Converter (DAC), with step-by-step instructions on how to configure and use the driver in a selection of use cases.

The use cases contain several code fragments. The code fragments in the steps for setup can be copied into a custom initialization function, while the steps for usage can be copied into, e.g., the main application function.

DAC use cases

Basic use case - DA conversion on one channel

In this use case, the DAC is configured for:

  • Using DAC on port B, channel 0
  • 1V from bandgap as reference, left adjusted channel value
  • one active DAC channel, no internal output
  • conversions triggered by event channel 0
  • 1 us conversion intervals

This use case sets up the DAC to perform DA conversions on one channel, with output to a pin, every time it receives events in event channel 0. The output pin may, e.g., be connected to an oscilloscope or an amplifier and speaker.

Setup steps

Prerequisites

  1. System Clock Management
  2. Timer/Counter Driver

Example code

The following configuration must be added to the project (typically to a conf_dac.h file, but it can also be added to your main application file):

#define SPEAKER_DAC DACB
#define SPEAKER_DAC_CHANNEL DAC_CH0
#define RATE_OF_CONVERSION 22050
#define NR_OF_SAMPLES 32

A static const sample buffer with one period of a sine wave must be added:

static const uint16_t sine[NR_OF_SAMPLES] = {
32768, 35325, 37784, 40050, 42036, 43666, 44877, 45623,
45875, 45623, 44877, 43666, 42036, 40050, 37784, 35325,
32768, 30211, 27752, 25486, 23500, 21870, 20659, 19913,
19661, 19913, 20659, 21870, 23500, 25486, 27752, 30211,
};

Add to application initialization:

static void evsys_init(void)
{
EVSYS.CH3MUX = EVSYS_CHMUX_TCC0_OVF_gc;
}
void tc_init(void)
{
tc_enable(&TCC0);
tc_set_wgm(&TCC0, TC_WG_NORMAL);
tc_write_period(&TCC0, (sysclk_get_per_hz() / RATE_OF_CONVERSION) - 1);
tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc);
}
void dac_init(void)
{
struct dac_config conf;
#ifdef XMEGA_DAC_VERSION_1
#endif
}

Add to main():

evsys_init();
tc_init();
dac_init();

Workflow

  1. Create a function evsys_init() to intialize the event system clocks and to link the conversion timer to the correct event channel:
    • static void evsys_init(void)
      {
      // ...
      }
  2. Use the sysclk service to enable the clock to the event system:
  3. Connect the TCC0 overflow event to event channel 3:
    • EVSYS.CH3MUX = EVSYS_CHMUX_TCC0_OVF_gc;
      Note
      If the DAC trigger timer is changed from TCC0, the EVSYS_CHMUX_* mask here will also need to be altered.
  4. Create a function tc_init() to intialize the DAC trigger timer:
    • static void tc_init(void)
      {
      // ...
      }
  5. Enable the clock to the DAC trigger timer:
    • tc_enable(&TCC0);
  6. Configure the DAC trigger timer in normal Waveform Generation mode:
    • tc_set_wgm(&TCC0, TC_WG_NORMAL);
  7. Configure the DAC trigger timer period to overflow at at the specified rate of conversion in Hz:
  8. Configure the DAC trigger timer clock source to use the peripheral bus frequency:
    • tc_write_clock_source(&TCC0, TC_CLKSEL_DIV1_gc);
  9. Create a function dac_init() to intialize the DAC:
    • static void dac_init(void)
      {
      // ...
      }
  10. Config struct for the DAC:
  11. Initialize the dac configuration by reading back the configuration from the peripheral:
  12. Create and set configuration:
  13. Enable DAC:
  14. Initialize the clock system, event system, DAC trigger timer, and the DAC:

Usage steps

Example code

Add to application C-file:

Workflow

  1. Create a local variable to hold the current sine wave lookup table index:
    • uint8_t i = 0;
  2. Wait for DAC channel to be ready for new data:
  3. Set the current sine wave table element as new channel value:
  4. Get next index in sine wave array to convert, wrapping around at NR_OF_SAMPLES: