Using 10bit DAC For Generating Analog Signals DS90003235C
Using 10bit DAC For Generating Analog Signals DS90003235C
Introduction
Authors: Cristian Sabiuta, Marius Nicolae, Microchip Technology Inc.
The AVR® DA MCU family of microcontrollers is based on the AVR architecture and brings a DAC peripheral
equipped with 10-bit resolution and high-drive capabilities, helping the user to generate precise analog voltages and
use them internally or externally on a physical pin.
This technical brief describes how the 10-bit DAC works on the AVR DA microcontroller family, covering the following
use cases:
• Generating Constant Analog Signal Using 10-Bit DAC:
Initialize the DAC, set the voltage reference, set the DAC to output a specific constant voltage.
• Generating Sine Wave Signal Using 10-Bit DAC:
Initialize the DAC, set the voltage reference, output in a loop the samples of a sine wave.
• Reading the DAC Internally with the ADC:
Initialize the DAC and ADC, set the voltage reference, set the ADC to read the DAC, increment the DAC output
and read it with the ADC for each step.
• Generating Amplitude Modulated Signal Using 10-Bit DAC:
Initialize the DAC with external reference and link the signal that must be modulated to the external reference
pin. The AVR core will continuously change the Data (DACn.DATA) register to create a modulated signal.
Note: The code examples were developed on AVR128DA48 Curiosity Nano.
Table of Contents
Introduction.....................................................................................................................................................1
1. Relevant Devices.................................................................................................................................... 3
1.1. AVR® DA Family Overview.......................................................................................................... 3
2. Overview................................................................................................................................................. 4
7. References............................................................................................................................................14
8. Appendix............................................................................................................................................... 15
9. Revision History.................................................................................................................................... 20
Customer Support........................................................................................................................................ 21
Legal Notice................................................................................................................................................. 21
Trademarks.................................................................................................................................................. 22
1. Relevant Devices
This chapter lists the relevant devices for this document.
Flash
Pins
28 32 48 64
Devices with different Flash memory size typically also have different SRAM.
2. Overview
The DAC features a 10-bit resolution and has one continuous time output with high-drive capabilities. The DAC
conversion can be started from the application by writing to the Data (DACn.DATA) register pair.
Figure 2-1. DAC Block Diagram
Other
Peripherals
10
DATA DAC OUT
Output
Driver
VREF
ENABLE
CTRLA
OUTEN
For the purpose of this example, the 2.048V reference voltage was selected:
VREF.DAC0REF = VREF_REFSEL_2V048_gc;
_delay_us(50);
The DAC output can be used internally by other peripherals, or it can be linked to an output pin. For the
AVR128DA48, the DAC output is connected to pin PD6 (see the figure below).
Figure 3-3. PORT Function Multiplexing
Pin name (1,2)
CCL-LUTn
VQFN64/
VQFN48/
VQFN32/
USARTn
SSOP28
SOIC28/
TQFP64
TQFP48
TQFP32
TWIn(4)
Special
EVSYS
ADC0
DAC0
ZCDn
TCBn
TCDn
TCA0
TCA1
SPIn
ACn
PTC
1,AINP2
30 24 14 10 PD4 AIN4 X20/Y20 WO4(3)
2,AINP1
0,AINP3
0,AINN2
2,AINN0/AINN2
The DAC output pin needs to have the digital input buffer and the pull-up resistor disabled in order to reduce its load.
PORTD.PIN6CTRL |= PORT_ISC_INPUT_DISABLE_gc;
The DACn.DATA register is used to generate a specific analog output voltage. The value of this output voltage can be
determined using the following equation:
����.���� × ����
���� =
1024
Writing to the DACn.DATA register at initialization is optional; however, it is useful to make the DAC output a specific
voltage from the beginning. The DAC features a 10-bit resolution, therefore, the DACn.DATAL and DACn.DATAH
register pair represents the 10-bit value DACn.DATA (see Figure 3-4). The two LSbs [1:0] are accessible at the
original offset and the eight MSbs [9:2] can be accessed at offset +1.
The output will be updated after DACn.DATAH is written.
Bit 7 6 5 4 3 2 1 0
DATA[1:0]
Access R/W R/W
Reset 0 0
The desired output for the DAC in this example is 1.2V. To achieve this, the following equation is applied:
���� × 1024 1.2� × 1024
����.���� = = = 600 = 0x258
���� 2.048�
In order to enable the DAC, Output Buffer, and Run in Standby mode, use the following code:
Important: If Run in Standby mode is enabled, the DAC will continue to run when the microcontroller is in
Standby Sleep mode.
Starting a Conversion
When the DAC is enabled (ENABLE = 1 in DACn.CTRLA), a conversion starts as soon as the Data (DACn.DATA)
register is written.
When the DAC is disabled (ENABLE = 0 in DACn.CTRLA), writing to the Data registers does not trigger a
conversion. Instead, the conversion starts on writing a ‘1’ to the ENABLE bit in the DACn.CTRLA register.
����.���� × ����
After a conversion, the output keeps its value of until the next conversion, as long as the DAC is
1024
running. Any change in the VREF selection will immediately change the DAC output (if enabled and running).
The sinusoidal waveform is created using a fixed number of steps (N_SAMPLES). To create a sine wave signal with
a specific frequency (SIGNAL_FREQ), all steps are executed in one period resulting in the following sample rate:
1
������_���� = = ������_���� × �_�������
����_�����_����
while (1)
{
DAC0_setVal(sineWave[sineIndex++]);
if(sineIndex == SINE_PERIOD_STEPS)
sineIndex = 0;
_delay_us(STEP_DELAY_TIME);
}
VREFA
AIN0 VREF
Internal Reference
AIN1
.
.
.
AINn
VAINP
Internal
Inputs
ADC ACC
AIN0 VAINN
AIN1
.
. Result Result ready
.
AINn formatting RES (IRQ)
Internal
> Window compare
Inputs Control Logic < (IRQ)
VREF.DAC0REF = VREF_REFSEL_2V048_gc /* Select the 2.048V Internal Voltage Reference for DAC */
| VREF_ALWAYSON_bm; /* Set the Voltage Reference in Always On mode */
VREF.ADC0REF = VREF_REFSEL_2V048_gc /* Select the 2.048V Internal Voltage Reference for ADC */
| VREF_ALWAYSON_bm; /* Set the Voltage Reference in Always On mode */
/* Wait VREF start-up time */
_delay_us(VREF_STARTUP_TIME);
ADC0.CTRLC = ADC_PRESC_DIV2_gc;
ADC0.CTRLA = ADC_ENABLE_bm | ADC_RESSEL_12BIT_gc;
To read the DAC with the ADC, the MUXPOS register of the ADC must be set to 0x48, corresponding to DAC0.
ADC0.MUXPOS = ADC_MUXPOS_DAC0_gc;
The ADC conversion is started by writing the corresponding bit to the ADCn.COMMAND register:
ADC0.COMMAND = ADC_STCONV_bm;
When the conversion is done, the RESRDY bit in the ADCn.INTFLAGS register will be set by hardware.
The flag is cleared by either writing a ‘1’ to the RESRDY bit location or by reading the Result (ADCn.RES) register.
Writing a ‘0’ to this bit has no effect.
ADC0.INTFLAGS = ADC_RESRDY_bm;
The ADC data can be read from the Result (ADCn.RES) register.
The DAC output can be set to different values, and read with the ADC in a loop:
while (1)
{
adcVal = ADC0_read();
dacVal++;
DAC0_setVal(dacVal);
}
VREF.DAC0REF = VREF_REFSEL_VREFA_gc;
�������� × �����
���� =
1024
Therefore, the amplitude of the carrier signal will vary according to the signal that needs to be modulated.
Important: The frequency of the carrier signal must be greater than that of the information signal in order
for the resulting signal to be relevant.
Based on the carrier wave frequency (SIGNAL_FREQ), the core will use a fixed number of samples (N_SAMPLES)
to build the signal as described in “Generating Sine Wave Signal Using 10-Bit DAC”. The resulting sample rate will
be:
������_���� = �_������� * ������_����
The resulting modulated signal will be available on the DAC output external pin (PD6).
In this example, a 50 Hz sine wave is used as the carrier signal and the modulated signal is a 2 Hz sine wave from a
signal generator.
Figure 6-1. Resulting Signal Visualized on Oscilloscope
7. References
1. AVR128DA28/32/48/64 Preliminary Data Sheet.
2. AVR128DA48 Curiosity Nano User's Guide.
8. Appendix
Example 8-1. Generating Constant Analog Signal Code
#include <avr/io.h>
#include <util/delay.h>
/* DAC Value */
#define DAC_EXAMPLE_VALUE (0x258)
/* VREF start-up time */
#define VREF_STARTUP_TIME (50)
/* Mask needed to get the 2 LSb for DAC Data Register */
#define LSB_MASK (0x03)
int main(void)
{
VREF_init();
DAC0_init();
DAC0_setVal(DAC_EXAMPLE_VALUE);
while (1)
{
;
}
}
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>
int main(void)
{
uint8_t sineIndex = 0;
VREF_init();
DAC0_init();
sineWaveInit();
while (1)
{
DAC0_setVal(sineWave[sineIndex++]);
if(sineIndex == SINE_PERIOD_STEPS)
sineIndex = 0;
_delay_us(STEP_DELAY_TIME);
}
}
Example 8-3. Reading the DAC Internally with the ADC Code
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
uint16_t dacVal = 0;
volatile uint16_t adcVal = 0;
VREF_init();
DAC0_init();
ADC0_init();
while (1)
{
adcVal = ADC0_read();
dacVal++;
DAC0_setVal(dacVal);
}
}
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>
int main(void)
{
uint8_t sineIndex = 0;
PORT_init();
VREF_init();
DAC0_init();
sineWaveInit();
while (1)
{
DAC0_setVal(sineWave[sineIndex++]);
if(sineIndex == SINE_PERIOD_STEPS)
sineIndex = 0;
_delay_us(STEP_DELAY_TIME);
}
}
9. Revision History
Doc. Rev. Date Comments
C 05/2020 Updated AVR® MCU DA (AVR-DA) to AVR® DA MCU, and AVR-DA to AVR DA, per latest
trademarking.
Customer Support
Users of Microchip products can receive assistance through several channels:
• Distributor or Representative
• Local Sales Office
• Embedded Solutions Engineer (ESE)
• Technical Support
Customers should contact their distributor, representative or ESE for support. Local sales offices are also available to
help customers. A listing of sales offices and locations is included in this document.
Technical support is available through the website at: http://www.microchip.com/support
Legal Notice
Information contained in this publication regarding device applications and the like is provided only for your
convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with
Trademarks
The Microchip name and logo, the Microchip logo, Adaptec, AnyRate, AVR, AVR logo, AVR Freaks, BesTime,
BitCloud, chipKIT, chipKIT logo, CryptoMemory, CryptoRF, dsPIC, FlashFlex, flexPWR, HELDO, IGLOO, JukeBlox,
KeeLoq, Kleer, LANCheck, LinkMD, maXStylus, maXTouch, MediaLB, megaAVR, Microsemi, Microsemi logo, MOST,
MOST logo, MPLAB, OptoLyzer, PackeTime, PIC, picoPower, PICSTART, PIC32 logo, PolarFire, Prochip Designer,
QTouch, SAM-BA, SenGenuity, SpyNIC, SST, SST Logo, SuperFlash, Symmetricom, SyncServer, Tachyon,
TempTrackr, TimeSource, tinyAVR, UNI/O, Vectron, and XMEGA are registered trademarks of Microchip Technology
Incorporated in the U.S.A. and other countries.
APT, ClockWorks, The Embedded Control Solutions Company, EtherSynch, FlashTec, Hyper Speed Control,
HyperLight Load, IntelliMOS, Libero, motorBench, mTouch, Powermite 3, Precision Edge, ProASIC, ProASIC Plus,
ProASIC Plus logo, Quiet-Wire, SmartFusion, SyncWorld, Temux, TimeCesium, TimeHub, TimePictra, TimeProvider,
Vite, WinPath, and ZL are registered trademarks of Microchip Technology Incorporated in the U.S.A.
Adjacent Key Suppression, AKS, Analog-for-the-Digital Age, Any Capacitor, AnyIn, AnyOut, BlueSky, BodyCom,
CodeGuard, CryptoAuthentication, CryptoAutomotive, CryptoCompanion, CryptoController, dsPICDEM,
dsPICDEM.net, Dynamic Average Matching, DAM, ECAN, EtherGREEN, In-Circuit Serial Programming, ICSP,
INICnet, Inter-Chip Connectivity, JitterBlocker, KleerNet, KleerNet logo, memBrain, Mindi, MiWi, MPASM, MPF,
MPLAB Certified logo, MPLIB, MPLINK, MultiTRAK, NetDetach, Omniscient Code Generation, PICDEM,
PICDEM.net, PICkit, PICtail, PowerSmart, PureSilicon, QMatrix, REAL ICE, Ripple Blocker, SAM-ICE, Serial Quad
I/O, SMART-I.S., SQI, SuperSwitcher, SuperSwitcher II, Total Endurance, TSHARC, USBCheck, VariSense,
ViewSpan, WiperLock, Wireless DNA, and ZENA are trademarks of Microchip Technology Incorporated in the U.S.A.
and other countries.
SQTP is a service mark of Microchip Technology Incorporated in the U.S.A.
The Adaptec logo, Frequency on Demand, Silicon Storage Technology, and Symmcom are registered trademarks of
Microchip Technology Inc. in other countries.
GestIC is a registered trademark of Microchip Technology Germany II GmbH & Co. KG, a subsidiary of Microchip
Technology Inc., in other countries.
All other trademarks mentioned herein are property of their respective companies.
© 2020, Microchip Technology Incorporated, Printed in the U.S.A., All Rights Reserved.
ISBN: 978-1-5224-6064-0