{"id":9952,"date":"2015-12-26T00:09:16","date_gmt":"2015-12-26T05:09:16","guid":{"rendered":"http:\/\/embedded-lab.com\/blog\/?p=9952"},"modified":"2016-12-18T19:42:12","modified_gmt":"2016-12-19T00:42:12","slug":"xmega-dac","status":"publish","type":"post","link":"https:\/\/embedded-lab.com\/blog\/xmega-dac\/","title":{"rendered":"XMega DAC"},"content":{"rendered":"<p>In embedded systems, oftentimes it is needed to generate analog outputs from a microcontroller. Examples of such include, generating audio tones, voice, music, smooth continuous waveforms, function generators, voltage reference generators, etc. Traditionally in such cases the most common techniques applied are based on <b><i>Pulse Width Modulation (PWM)<\/i><\/b>, resistor networks and external <b><i>Digital-to-Analog Converter (DAC)<\/i><\/b> chips like MCP4921. The aforementioned techniques have different individual limitations and moreover require external hardware interfacing, adding complexities and extra cost to projects.\u00a0 XMega micros are equipped with 12 bit fast DACs apart from PWM blocks and again it proves itself to be a very versatile family of microcontrollers. In this post we will have a look into this block.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/dac-internal-block-diagram\/\" rel=\"attachment wp-att-9969\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9969\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/DAC-Internal-Block-Diagram.png\" alt=\"DAC Internal Block Diagram\" width=\"590\" height=\"300\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/DAC-Internal-Block-Diagram.png 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/DAC-Internal-Block-Diagram-550x279.png 550w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/a><\/p>\n<p><!--more--><\/p>\n<h4>A brief overview<\/h4>\n<p>I used ATXMega32A4U just as always and it has only one dual channel DAC designated <b><i>DACB <\/i><\/b>but there are other XMega devices that have more than one DAC.<\/p>\n<p>The internal block diagram of the DAC block above shows its major parts. The DAC of XMega is perhaps one of the simplest block to understand. Apart from DMA and event system interfacing, the DAC can provide reference source for the analog comparator and ADC blocks. It also has the capability to directly drive both resistive and capacitive loads (check device datasheet for limits). Just like the ADC block, the DAC block itself needs a reference source and this reference source can be both internal (internal 1.0V reference) and external (AVCC or AVREF). As stated earlier there are two independent DAC channels in the XMega32A4U and so there are two separate analog outputs (PB2 and PB3) available from this micro.<\/p>\n<p>The basic formula for voltage output from the DAC is as follows:<br \/>\n<a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/formula-2\/\" rel=\"attachment wp-att-9972\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9972\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Formula.png\" alt=\"Formula\" width=\"348\" height=\"75\" \/><\/a><\/p>\n<p>The digital data value ranges from 0 \u2013 4095 (0x0000 \u2013 0x0FFF) since it is a 12 bit DAC. How fast it can operate will depend on peripheral clock\u2019s operating frequency. Just like the clock system, the DAC output can be precisely calibrated by using gain error and offset error registers. Though calibrating the DAC ensures more accurate data output, it is seldom used. If it is needed to calibrate the DAC for sensitive operations one must do so carefully and should use standard instruments that have least possible error, otherwise it is pointless to calibrate it. You can use the XMega ADC block for calibration purpose if you don\u2019t have access to good measurement instruments. In my previous post I showed how to use the XMega ADC. I, however, never calibrated the DAC block. Calibration process is well explained in the reference manual.<\/p>\n<p>Shown below are pin diagrams of both the most popular XMega A1 and A4 devices. Checkout the DAC output pin locations because these are not mentioned in the reference manual.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/xmega-a4-pin-map\/\" rel=\"attachment wp-att-9971\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9971\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A4-Pin-Map.png\" alt=\"XMega A4 Pin Map\" width=\"684\" height=\"679\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A4-Pin-Map.png 684w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A4-Pin-Map-150x150.png 150w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A4-Pin-Map-550x545.png 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A4-Pin-Map-90x90.png 90w\" sizes=\"auto, (max-width: 684px) 100vw, 684px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/xmega-a1-pin-map\/\" rel=\"attachment wp-att-9970\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9970\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A1-Pin-Map.png\" alt=\"XMega A1 Pin Map\" width=\"689\" height=\"690\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A1-Pin-Map.png 689w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A1-Pin-Map-150x150.png 150w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A1-Pin-Map-550x550.png 550w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-A1-Pin-Map-90x90.png 90w\" sizes=\"auto, (max-width: 689px) 100vw, 689px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h4>Registers<\/h4>\n<p>The simplified register map for the DAC block shows that there are only a few registers to deal with. I\u2019m not going to detail about them as the reference manuals are already doing so.<\/p>\n<p>Control registers A-C are sequentially set first. These registers are responsible for selecting reference source, channel, power mode, etc. Calibration registers have names ending with <i>\u201cCAL\u201d <\/i>and data input registers have names ending with <i>\u201cDATA\u201d<\/i>. Lastly there is event system register that select which event system channel would trigger the DAC and there is a <i>STATUS<\/i> register which flags when it is possible to write new values to a specific DAC channel.<\/p>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/xmega-dac-register-map\/\" rel=\"attachment wp-att-9963\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9963\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-DAC-Register-Map.png\" alt=\"XMega DAC Register Map\" width=\"590\" height=\"327\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-DAC-Register-Map.png 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/XMega-DAC-Register-Map-550x304.png 550w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h4>Coding<\/h4>\n<p>The code, just as in previous posts, starts with clock and I\/O configuration setups and then the DAC is setup. In this code example I coded the XMega as such that both of its outputs will give sinusoidal voltage variations or in other words the DAC output pins will output sine wave signals. I also coded a DAC header file for quick coding and less meddling with register values. The DAC block is coded to use \u00a0(3.3V) as reference source and both DAC channels are employed. One DAC channel will output sine wave output while the other at the same instance will give out phase shifted sine wave or cosine wave signal. MikroC CMath library is used for the trigonometric (sine-cosine) functions. PB2 and PB3 are set as output pins. Lastly left adjustment of DAC data is avoided to keep things simple. Please note that I didn\u2019t calibrate the DAC and still it worked good enough.<\/p>\n<pre><span style=\"color: #0000ff\"><i>#include \"clock.h\"<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>#include \"dac.h\"<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>#include \"io.h\"<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void clock_setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void io_setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void dac_Setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void dac_write(unsigned char channel, unsigned int value);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void main() <\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>{<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 signed int temp1 = 0;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 signed int temp2 = 0;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 unsigned int degree = 0;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 <\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 while(1)<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 {<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for(degree = 0; degree &lt; 360; degree++)<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 temp1 = (2047 * cos(degree * 0.0174532925));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 temp1 = (2048 - temp1);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 temp2 = (2047 * sin(degree * 0.0174532925));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 temp2 = (2048 - temp2);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dac_write(0, ((unsigned int)temp1));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dac_write(1, ((unsigned int)temp2));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 delay_us(10);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 };<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>}<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void setup()<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>{<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 clock_setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 io_setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 dac_Setup();<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>}<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void clock_setup()<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>{<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 OSC_CTRL |= OSC_RC32KEN_bm;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 while(!(OSC_STATUS &amp; OSC_RC32KRDY_bm));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 OSC_CTRL |= OSC_RC32MEN_bm;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 CPU_CCP = CCP_IOREG_gc;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 CLK_PSCTRL = ((CLK_PSCTRL &amp; (~(CLK_PSADIV_gm | CLK_PSBCDIV1_bm <\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | CLK_PSBCDIV0_bm))) | CLK_PSADIV_1_gc | CLK_PSBCDIV_2_2_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 OSC_DFLLCTRL = ((OSC_DFLLCTRL &amp; (~(OSC_RC32MCREF_gm | OSC_RC2MCREF_bm))) |<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 OSC_RC32MCREF_RC32K_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 DFLLRC32M_CTRL |= DFLL_ENABLE_bm;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 while(!(OSC_STATUS &amp; OSC_RC32MRDY_bm));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 CPU_CCP = CCP_IOREG_gc;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 CLK_CTRL = ((CLK_CTRL &amp; (~CLK_SCLKSEL_gm)) | CLK_SCLKSEL_RC32M_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 OSC_CTRL &amp;= (~(OSC_RC2MEN_bm | OSC_XOSCEN_bm | OSC_PLLEN_bm));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTCFG_CLKEVOUT = 0x00;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>}<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void io_setup()<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>{<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_OUT = 0x00;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_DIR = 0x0C;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_PIN0CTRL = (PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_PIN1CTRL = (PORT_OPC_TOTEM_gc | PORT_ISC_BOTHEDGES_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_PIN2CTRL = (PORT_OPC_TOTEM_gc | PORT_ISC_INPUT_DISABLE_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_PIN3CTRL = (PORT_OPC_TOTEM_gc | PORT_ISC_INPUT_DISABLE_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_INT0MASK = 0x00;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 PORTB_INT1MASK = 0x00;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>}<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void dac_setup()<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>{<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 DACB_CTRLA = ((DACB_CTRLA &amp; (~(DAC_IDOEN_bm | DAC_CH0EN_bm | DAC_CH1EN_bm<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | DAC_LPMODE_bm))) | DAC_CH0EN_bm | DAC_CH1EN_bm | DAC_ENABLE_bm);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 DACB_CTRLB = ((DACB_CTRLB &amp; (~(DAC_CHSEL_gm | DAC_CH0TRIG_bm <\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | DAC_CH1TRIG_bm))) | DAC_CHSEL_DUAL_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 DACB_CTRLC = ((DACB_CTRLC &amp; (~(DAC_REFSEL_gm | DAC_LEFTADJ_bm)))<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 | DAC_REFSEL_AVCC_gc);<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>}<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>void dac_write(unsigned char channel, unsigned int value)<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>{<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 switch(channel)<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 {<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case 0:<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 while(!(DACB_STATUS &amp; DAC_CH0DRE_bm));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DACB_CH0DATA = value;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 case 1:<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 while(!(DACB_STATUS &amp; DAC_CH1DRE_bm));<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DACB_CH1DATA = value;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break;<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>\u00a0\u00a0 }<\/i><\/span><\/pre>\n<pre><span style=\"color: #0000ff\"><i>}\r\n<\/i><\/span><\/pre>\n<p>&nbsp;<\/p>\n<h4>XMega DAC Demo<\/h4>\n<p><a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/demo-1-2\/\" rel=\"attachment wp-att-9964\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9964\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-1.jpg\" alt=\"Demo (1)\" width=\"590\" height=\"476\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-1.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-1-550x443.jpg 550w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/demo-2-2\/\" rel=\"attachment wp-att-9965\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9965\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-2.jpg\" alt=\"Demo (2)\" width=\"590\" height=\"473\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-2.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-2-550x440.jpg 550w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/demo-3\/\" rel=\"attachment wp-att-9966\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9966\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-3.jpg\" alt=\"Demo (3)\" width=\"590\" height=\"633\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-3.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-3-550x590.jpg 550w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/a> <a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/demo-4\/\" rel=\"attachment wp-att-9967\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9967 aligncenter\" src=\"http:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-4.jpg\" alt=\"Demo (4)\" width=\"590\" height=\"395\" srcset=\"https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-4.jpg 590w, https:\/\/embedded-lab.com\/blog\/wp-content\/uploads\/2015\/01\/Demo-4-550x368.jpg 550w\" sizes=\"auto, (max-width: 590px) 100vw, 590px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Demo video link: <a href=\"https:\/\/www.youtube.com\/watch?v=O61v0nww6vU\">https:\/\/www.youtube.com\/watch?v=O61v0nww6vU<\/a>.<\/p>\n<p>Files:\u00a0<a href=\"http:\/\/embedded-lab.com\/blog\/xmega-dac\/xmega-dac\/\" rel=\"attachment wp-att-9954\">XMega DAC<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>References: XMega AU Manual and Datasheet.<\/p>\n<p>&nbsp;<\/p>\n<p>Happy coding.<\/p>\n<address>\u00a0<\/address>\n<address><i>Author: Shawon M. Shahryiar<\/i><\/address>\n<address><a href=\"https:\/\/www.facebook.com\/groups\/microarena\/\" target=\"_blank\"><i>https:\/\/www.facebook.com\/groups\/microarena\/<\/i><i>\u00a0\u00a0 <\/i><\/a><\/address>\n<address><a href=\"https:\/\/www.facebook.com\/MicroArena\" target=\"_blank\"><i>https:\/\/www.facebook.com\/MicroArena<\/i><i>\u00a0<\/i><\/a><\/address>\n<address><i>+8801970046495 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <\/i><\/address>\n<address><i>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/i><\/address>\n<address><i>26.01.2015<\/i><\/address>\n","protected":false},"excerpt":{"rendered":"<p>In embedded systems, oftentimes it is needed to generate analog outputs from a microcontroller. Examples of such include, generating audio tones, voice, music, smooth continuous waveforms, function generators, voltage reference generators, etc. Traditionally in such cases the most common techniques applied are based on Pulse Width Modulation (PWM), resistor networks and external Digital-to-Analog Converter (DAC) chips like MCP4921. The aforementioned techniques have different individual limitations and moreover require external hardware interfacing, adding complexities and extra cost to projects.\u00a0 XMega micros are equipped with 12 bit fast DACs apart from PWM blocks and again it proves itself to be a very<\/p>\n","protected":false},"author":5,"featured_media":9963,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1466,792],"tags":[644,807,800,11,1099,312],"class_list":["post-9952","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","category-xmega","tag-atmel","tag-atxmega","tag-atxmega32a4u","tag-avr","tag-dac","tag-mikroc-for-avr"],"_links":{"self":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/9952","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/comments?post=9952"}],"version-history":[{"count":12,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/9952\/revisions"}],"predecessor-version":[{"id":12859,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/posts\/9952\/revisions\/12859"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media\/9963"}],"wp:attachment":[{"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/media?parent=9952"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/categories?post=9952"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/embedded-lab.com\/blog\/wp-json\/wp\/v2\/tags?post=9952"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}