ATxMega 128a1 ADC DAC help

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I am new to AVR programming and have a question about how to use the ADC and DAC. What I would like to do is take an input from the ADC, and based on this input, output a voltage on the DAC. However, the output on the DAC doesn't correspond directly to the ADC input.

For example lets say I have an input voltage to the ADC of 0 to 3 volts. For the range of 0 to 1.5 volts, I would like the DAC to output a respective range of 0 to 1 volts, At 1.5 volts the DAC should output 0 volts, and for the range of 1.5 to 3 volts the DAC should again output a respective range of 0 to 1 volts.

I was wondering if anyone would be so kind as to point me at any tutorials or code examples that could help me? Thanks in advance!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Welcome to the forum.

You are probably programming in C, so I can't help with the code, but I'll share a few other thoughts.

What are you using for your hardware, and programmer? Atmel has the XPlain board. It has the Analog A port available on a header, and one digital port available. Gabotronics has several XPlain boards available. Boston Android has several Xmega boards available. Others certainly exist, also.

I use the STK600 for PDI programming Xmegas. The AVRISP mkII is much less expensive, and can be used also.

Stu's Newbie? Start here! is a good place for AVR beginners to browse around for a while.

Note that the Xmega's ADC has a few quirks, and I am not sure the latest revision has fixed them all. Do look at the Errata page for the Xmega, as it may impact your project. That said, last I recall reading single ended ADC 0 V up to Vref was working. Use the Search feature at the top of this page and look for Xmega and ADC threads.

The DAC worked fine when I was doing some experimentation with it, but the audio amp on the XPlain board was a less than optimal design. If you tap off the DAC directly, however, not an issue.

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The board I am using is the one shown here: http://xmega.mattair.net/index.html
In terms of a programmer, the board has an onboard USB PDI programmer and I am using AVR Studio. Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Mchriste wrote:

For example lets say I have an input voltage to the ADC of 0 to 3 volts. For the range of 0 to 1.5 volts, I would like the DAC to output a respective range of 0 to 1 volts, At 1.5 volts the DAC should output 0 volts, and for the range of 1.5 to 3 volts the DAC should again output a respective range of 0 to 1 volts.

By using atmel libraries, this can be easily done. See AVR1300 and AVR1301 source codes.

Ozhan KD
Knowledge is POWER

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First off, I would like to thank everyone above for the helpful advice.

I've written code to read the input voltage from the ADC, but now I'm having trouble writing code to output a voltage on the DAC. As I stated in my first post, I would like to output a range of voltages on the DAC, where the voltage being output from the DAC corresponds to the value being read from the ADC.

For example, the ADC has an input voltage from 0 to 2.5 VDC. For the range of 0 to 1.25V, I would like the DAC to output a range of 0 to 1V, where 0V being read on the ADC corresponds to 0V being output on the DAC, and 1.25V being read on the ADC corresponds to 1V being output on the DAC.

Is it possible to output a range of voltages on the DAC? How would I go about writing code for this?

Also, I have read the AVR 1301 app notes and looked at the sample code, but it doesn't give me information on how to do what I want.

Again I am using the board shown here: http://xmega.mattair.net/index.html

Thanks in advance!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you good at deciphering gibberish...

One evening I wanted to make the Xplain Beep.

Here is my initial test program for generating some noise on the XPlain, written in Bascom.

Note that this was a one evening quickie project, and wasn't written for clarity or review... That said it demonstrates turning on and off the Mute bit, writing a sin tone to the DAC, and adding an offset to the Sin data.

JC

'File Name:  Xplain Speaker Test V4.bas
'10/2010
'JEC
'
'This runs on an XMega on an Atmel XPlain board.
'This uses Bascom V2.0
'
'The Xmega Has Portb.2 And Portb.0.3 For L & R Channels Feeding An Audio Amp
'to a small speaker on the board.
'This is designed so that the DAC can generate audio.

'Hardware:
'This is using an Atmel XPlain Xmega128A1 board.
'I have a PDI ribbon cable connector from the XPlain to an STK600 to do
'PDI programming of the XPlain Xmega.

'Xplain LEDs are on PortE. They are LOW active, (lit).
'
'XMega runs at 2 MHz on startup, default.
'PDI Program this with STK600 Board.

'V1:  FAILS
'Set up Timer/Counter C0 for ISR and flash an LED to show activity.
'Work on configuring the pins for DIGITAL I/O
'This doesn't work..........

'V2:
'This Drives PortB.2 digitally, Hi/Low, into the audio amp.
'This massively overdrives it, but it does make some noise.
'Note Well: Turn ON the audio Amp chip via its Shut Down\ signal by turning
'PortQ.3 HI to enable audio.
'Feed signal via PortB.2, (B.3 doesn't drive the other channel...).
'This program works to make noise , program driven, overdriving amp.
'This program doesn't use the DAC as a DAC, (yet).

'V3: Works:
'Now working on using the DAC to drive the audio amp.
'My set up, no Bascom examples about.
'DAC B goes to Port B, which goes to the audio amp.
'Must direct DAC B to the audio amp to the spker.
'Can easily watch DAC A on the Header pins...
'Added Dac B's High and Low Data Registers to Def.Dat file.
'Must Turn ON, Enable, the Audio Amp via it's Shut Down \ pin.
'There is a lot of Background HISS on the amp & Spker.
'If turn the audio amp on & off, it needs almost 400 - 500 mSec to turn on the Audio Amp
'chip, else hear nothing.
'i.e. one can't just enable the chip, play a beep, and disable the chip...

'V4:
'Looking at Gain of XPlain amp (?4).
'Trying to scope the signals...
'XPlain seems to have lots of back-ground HISS.


'Manual says DAC feeds PB2.
'On schematic it looks like PB2 and PB3 are the L and R audio channels.
'Will try feeding both to the amp & spker.

'
'Atmel Xplain Xmega128a1 Board:
'Port F  PB Switches.  Must enable Internal Pull Up resistors.  Pressed = tied to Gnd.
'Port E  LEDs, Active Low to turn On.
'Port B
'     B.0   NTC Thermistor to ADC
'     B.1   Pot to ADC
'     B.2   Xmega DAC to Audio Amp to Spker      Just use digital 1/0 for now...
'     B.2 Does go to the Amp and Spker, B.3 does NOT make any noise...
'Note: Turn ON the audio amp to make any noise, PortQ.3 HI to enable amplfier.

'PortD   Goes to an I/O Header.
'    D.0  I'm using this for a Scope Signal / Trigger, Set up as Output.
'PortQ.3 is Audio Control, Shut Down\, to Audio Amp.
'Needs to be hi for audio.

'DAC A output goes to the XPlain Header: PortA.2


'Write a Port, Read a Pin

'-----------------------------------------------------------------------------------------

$regfile = "xm128a1def.dat"                                 ' specify the used micro
$crystal = 32000000                                         'Xmega 2MHz default Start Up Clock Freq
                                                            'But will actually run prog at 32 MHz
$hwstack = 128                                              ' default use 32 for the hardware stack
$swstack = 128                                              ' default use 10 for the SW stack
$framesize = 128                                            ' default use 40 for the frame space

$lib "xmega.lib"
$external _xmegafix_clear
$external _xmegafix_rol_r1014

'Configure the XMega Oscillator and Clock:
'Set up for 32 MHz from the Internal Osc.
   Config Osc = Enabled , 32mhzosc = Enabled                'Enable Int 2 MHz osc and 32 MHz Osc
   Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1       'Int 32 MHz Osc at 32 MHz

    Waitms 500                                              'Startup Stabilization Delay

   'Xplain LEDs on Port E:
   'Now Configure the Port's Pins for Input or Output mode.
   '0 = Input, 1 = Output
   'Mega Method:  Config Portf = &B11111111    'Now Config PORT Input/Output
   'XMega Method:
   Porte_pin0ctrl = &B00000000                              'PIN on PortF.0 Control Totem Pole
   Porte_pin1ctrl = &B00000000                              'PIN F.1 Control Totem Pole
   Porte_pin2ctrl = &B00000000                              'PIN F.2 Control Totem Pole
   Porte_pin3ctrl = &B00000000                              'PIN F.3 Control Totem Pole
   Porte_pin4ctrl = &B00000000                              'PIN F.4 Control Totem Pole
   Porte_pin5ctrl = &B00000000                              'PIN F.5 Control Totem Pole
   Porte_pin6ctrl = &B00000000                              'PIN F.6 Control Totem Pole
   Porte_pin7ctrl = &B00000000                              'PIN F.7 Control Totem Pole

   Porte_dir = 255                                          'Port F All Outputs for LEDs

   'Config XMega PortD.0 as an Output for Scope Signal / Trigger:
   Portd_pin0ctrl = &B00000000                              'PIN on PortD.0 Control Totem Pole
   Portd_dir = 1                                            'Port D Pin 0 as Output for Scope Signal

   'Config XMega PortB.2 as an Output for XPlain Speaker.  Add PB.3 Right Channel.
   'Drive it with Digital 1/0 for now, not using DAC currently.
   Portb_pin2ctrl = &B00000000                              'PIN on PortB.2 Control Totem Pole
   Portb_pin3ctrl = &B00000000                              'PIN on PortB.3 Control Totem Pole
   Portb_dir = 12                                           'Port B Pins 2 & 3 as Output to Spker

   'Config XMega PortQ.3 as an Output for Audio Amp chip's SD\ Control signal:
   Portq_pin3ctrl = &B00000000                              'PIN on PortQ.3 Control Totem Pole
   Portq_dir = 8                                            'Port Q Pin 3 as Output

   Dim B As Word                                            'Loop Counter
   Dim N As Byte                                            'Loop Counter
   Dim J As Byte
   Dim D As Byte                                            'Delay in mSec as byte (0-255)
   Dim Ls As Byte                                           'LED Status
   Dim Ticcnt As Word                                       'ISR Tic Soft Counter

   Dim Lpcnt1 As Word                                       'Loop Counter
   Dim Lpcnt2 As Word                                       'Loop Counter

   Dim Ttc As Word                                          'Tic Tock Timer Intr Counter
   Dim Psec As Word                                         'Second counter
   Dim Msdly As Word                                        'Variable for mSec Delay

   Dim Bd As Word                                           'Beep Duration Counter
   Dim Pt As Word                                           'Piezo Toggle Counter

   'Note: High byte is only 4 bits, total is 12 bits for DAC.
   Dim Avl As Byte                                          'Audio DAC Value Low Byte
   Dim Avh As Byte                                          'Audio DAC Value High Byte

   'Sin Wave:
   Dim Sindata(200) As Single                               'Sin Wave LookUp Table, full period
   Dim Sd As Single                                         'Sin Data value
   Dim Fr As Word                                           'Fractional Radian loop  index
   Dim Sdw As Word                                          'Data Conv Sig to Word

   Ls = 0                                                   'Led Status = Off
   Ticcnt = 0                                               'Init ISR Tic Soft Counter

   'Set Up TimerCounter C 0 for Timer to trigger Overflow ISR Interrupt.
   'Have to set the Prescaler manually for the XMegas.
   'Have to enable the specif interrupt, and overall interrupts.
   'For the XMega one also defines the Priority Level, Hi/Med/Low
   'for the XMega, must turn on the Priority Levels you are using.
   'Config Priority = Static , Vector = Application , Hi = Enabled , Lo = Enabled , Med = Enabled       'Ordered Vector Table
   On Tcc0_ovf Tc0isr
   Config Priority = Static , Vector = Application , Lo = Enabled
   Enable Tcc0_ovf , Lo                                     'Enable Timer/counter 0, Overflow Interrupt
   Enable Interrupts
  ' Tcc0_ctrla = &B00000011                                  'Timer/Counter C 0:  PreScaler of 4
   Tcc0_ctrla = 3                                           'Timer/Counter C 0:  PreScaler of 4

   '............................................................................
   'Set up the DAC Registers for the XPlain board.
   'Use these to test driving the amp & Spker with DAC generated audio.
   'No reference for this...

   'Enable the DAC, Enable the DAC Ch0 & 1 outputs, disable the internal dac routing.
   Daca_ctrla = &B00001101

   'Set up for Dual Channel output using S/H system.
   'Do not enable Event System triggers of Ch 0 or Ch 1.
   Daca_ctrlb = &B01000000

   'Set DAC Reference to AVcc,  Do not Left Adj the Ch0  and Ch1 data.
   Daca_ctrlc = &B00001000

   'Event System Trigger Selection Set Up
   Daca_evctrl = &B00000000

   'Conversion Interval, dual Ch mode, 192 Clk Cycles
   'Set up DAC Refresh for 2048 Clk Cycles between refreshes
   Daca_timctrl = &B01110111


   'Read this Register
   'Data Register Empty Ch 0 Ch 1
   'Set means CAN write new data value to the DAC without overwriting previous value.
   Daca_status = &B00000000

   'The Data Input Registers:  High & Low Bytes, default = right justified, 12 bits.
   'ABCD = upper 4 bits of 12 bit data
   'If use L justified data, then can write 8 bit data to High register alone. +++
   Daca_ch0datah = &B00000000                               'High Byte 0000ABCD
   Daca_ch0datal = &B00000000                               'Low Byte of Data
   Daca_ch1datah = &B00000000                               'High Byte 0000ABCD
   Daca_ch1datal = &B00000000                               'Low Byte of Data


   'DAC Gain Calibration:    7-bit value.  I'm setting to 1 for now...
   Daca_gaincal = &B00000001
 '  Daca_gaincal = &B011111111

   'DAC Offset Calibration:   7-bit value.  I'm setting to 0 for now.
   Daca_offsetcal = &B00000000
 '  Daca_offsetcal = &B011111111


   '++++++++++++Now do the same for DAC B ++++++++++++++++++++++++++++++++++++++
   'BASCOM doesn't have individual register names in def.dat file for Ch B's
   'Ch 0 & 1 Low and High bytes...  They were present for DAC A.

   'Enable the DAC, Enable the DAC Ch0 & 1 outputs, disable the internal dac routing.
   Dacb_ctrla = &B00001101

   'Set up for Dual Channel output using S/H system.
   'Do not enable Event System triggers of Ch 0 or Ch 1.
   Dacb_ctrlb = &B01000000

   'Set DAC Reference to AVcc,  Do not Left Adj the Ch0  and Ch1 data.
   Dacb_ctrlc = &B00001000

   'Event System Trigger Selection Set Up
   Dacb_evctrl = &B00000000

   'Conversion Interval, dual Ch mode, 192 Clk Cycles
   'Set up DAC Refresh for 2048 Clk Cycles between refreshes
   Dacb_timctrl = &B01110111

   'Read this Register
   'Data Register Empty Ch 0 Ch 1
   'Set means CAN write new data value to the DAC without overwriting previous value.
   Dacb_status = &B00000000

   'The Data Input Registers:  High & Low Bytes, default = right justified, 12 bits.
   'ABCD = upper 4 bits of 12 bit data
   'If use L justified data, then can write 8 bit data to High register alone. +++
 '  Dacb_ch0datah = &B00000000                               'High Byte 0000ABCD
 '  Dacb_ch0datal = &B00000000                               'Low Byte of Data
 '  Dacb_ch1datah = &B00000000                               'High Byte 0000ABCD
 '  Dacb_ch1datal = &B00000000                               'Low Byte of Data

   Dacb_ch0data = &B00000000                                'DAC B Ch 0 12 bits
   Dacb_ch1data = &B00000000                                'DAC B Ch 1 12 bits


   'DAC Gain Calibration:    7-bit value.  I'm setting to 1 for now...
   Dacb_gaincal = &B00000001
 '  Dacb_gaincal = &B00000011

   'DAC Offset Calibration:   7-bit value.  I'm setting to 0 for now.
   Dacb_offsetcal = &B00000000
 '  Dacb_offsetcal = &B00000011


   '............................................................................

   'Turn ON Audio Amp Chip:
   Portq_out.3 = 1                                          'Set Audio Amp Control Pin Hi

   Gosub Ledflash                                           'Group Flash x 10
   Gosub Gendata                                            'Generate a Sin Data Table

Main:

   Portd_out.0 = 1                                          'Scope Signal High
   Waitms 2
   Portd_out.0 = 0                                          'Scope Signal Low

 '  Gosub Ledflash2                                          'Group Flash x 10

 '  Gosub Dacanoise2

   Waitms 1000

  'Turn ON Audio Amp Chip:
 '  Portq_out.3 = 1                                          'Set Audio Amp Control Pin Hi
  ' Waitms 500

   Gosub Dacbnoise2

  'Turn OFF Audio Amp Chip:
 '  Portq_out.3 = 0                                          'Clear Audio Amp Control Pin Hi

   Goto Main

Gendata:
   'Generate a Data Lookup Table for a sin wave for testing audio on XPlain Spker.
   'Make 200 samples for one period.
   'Ignore symmetry of sin for now, KISS.
   'Output is -1 to +1 range.
   '360 deg = 2*Pi rads.  Each sample is (2*Pi)/200 radians, = 0.031415926 radians.
   'Scale it for about 0-4095 Range for 12 bit DAC
   'Set for 2047 mid point offset.
   'I think XPlain is configured for G=4 in the audio amp...
   For Fr = 0 To 199                                        '200 Samples, Fractional Radian
      Sd = 0.031415926 * Fr                                 'Radians
      Sd = Sin(sd)

      Sd = Sd * 1000
      Sd = Sd + 2047

      Sindata(fr) = Sd

   Next Fr
   Return

Dacbnoise2:
   'Make some noise on DAC B, using a Sin Wave look up table.
   'Est 2KHz tone, 100 Samples / period.  5uS per sample.
   'Program driven.
   '12 bits, R justified.  0-4095
   'Scale the data table and add a midrange offset.
   'Midrange = 8 for upper byte of data register.

   For N = 1 To 200                                         'Repeat for a longer duration beep
      For B = 0 To 199 Step 4                               'One Period
         Sd = Sindata(b)                                    'Range -1 to +1
         Sdw = Sd                                           'Single to word
         Dacb_ch0datal = Low(sdw)                           'Audio value
         Dacb_ch0datah = High(sdw)

         Daca_ch0datal = Low(sdw)                           'Audio value
         Daca_ch0datah = High(sdw)

         Waitus 3
      Next B
   Next N

   'Reset to midpoints:
         Dacb_ch0datal = 0                                  'Audio value
         Dacb_ch0datah = 8

         Daca_ch0datal = 0                                  'Audio value
         Daca_ch0datah = 8

   Return

Dacnoise:
   'This outputs to DAC A to Header, NOT to Spker!  Works.
   'DAC A goes to Port A, etc. makes no audio output on XPlain
   'Use the XMega's DAC to Generate some audio noise / beep.
   'Program Driven for now.  Not ISR Driven.
   'For now just play with upper nibble
   'But can watch the output on PortA.2 on the XPlain Header, and this WORKS to
   'generate a series of stair steps!
   'As written here, stairs go from 0 to ~ 2.8 V.  Cool!

   For N = 1 To 5
      For J = 0 To 15
         '  Avl = J * 2
         Daca_ch0datah = J
         Daca_ch0datal = 0                                  'Audio value
       '  Waitms 10
      Next J
   Next N
   'Now reset to 0 Volts:
   Daca_ch0datah = 0
   Daca_ch0datal = 0                                        'Audio value
   Return

Dacbnoise:
   'Make some noise on DAC B
   'Program driven.
   '12 bits, R justified.  0-4095

   '++++++++++++++These registers are not in the def.dat file!!!!  +++++++

   For N = 1 To 5
      For B = 0 To 4095 Step 100
         Dacb_ch0datal = Low(b)                             'Audio value
         Dacb_ch0datah = High(b)
         Waitus 20
      Next B
   Next N
   Return

Dacanoise2:
   'Generate Scope DAC A output
   'Works.  682,500 Outputs/Sec, 32 MHz Clock.
   'Program driven.
   '12 bits, R justified.  0-4095
   'Auto-output new value when DAC data changes.
   'Change the Low Byte FIRST, triggers on high byte change.
   'Output is about 0 to 2.95 V ramp.
   For N = 1 To 5
    '  For B = 0 To 4095 Step 100
      For B = 0 To 4095
         Daca_ch0datal = Low(b)                             'Audio value
         Daca_ch0datah = High(b)
     '    Waitus 100
      Next B
   Next N
   Return

Tc0isr:
   'Timer 0 ISR
   'Flash LED 4 via Interrupts
   'With 32 MHz Clo, add software ISR divider, also.
   'This gives about 122 Intr/Second.
   'Using PortD.0 as a Scope Signal to see Intr Rate.

 '  Portd_out.0 = 1                                          'Scope Signal High
 '  Waitus 50
 '  Portd_out.0 = 0                                          'Scope Signal Low

   Ticcnt = Ticcnt + 1                                      'Incr ISR Counter

   If Ticcnt < 20 Then
      Porte_out.4 = 0                                       'ON
   Else
      Porte_out.4 = 1                                       'Off
   End If

   If Ticcnt > 122 Then                                     'Roll Over About 1 / Second
      Ticcnt = 0
   End If

   Return

Xplainbeep:                                                 'This works
   'XPlain board has a audio amp and Speaker on PortB.2.
   'Can drive it with Xmega's DAC.
   'This just plain bangs it 1/0 for now.
   'Test Program Driven , Not Intr Driven.
   'Only PortB.2 makes any noise output, Not  BD.3.
   'Need to turn ON audio Amp chip PortQ.3 Hi to to this.
   'This massively overdrives the amp input, but it makes some noise +++++++++++
   For Bd = 1 To 20                                         'Beep Duration
      For Pt = 1 To 30                                      'Piezo Toggle
         Portb_out.2 = 1                                    'Set High
      '   Portb_out.3 = 1
         Waitus 200
         Portb_out.2 = 0                                    'Set Low
      '   Portb_out.3 = 0
      Next Pt
   Next Bd
   Return


Ledflash:
   'Simultaneously Flash the eight Port F LEDs On and Off.
   'Straight code.
   'Flashes the Full LED Port, Works.

   For J = 1 To 5
      Porte_out = 0                                         'All Low
      Waitms 100
      Porte_out = 255                                       'All High, On
      Waitms 100
   Next J
   Return

Ledflash2:
   'Program Driven wig-wag two XPlain LEDs
   Msdly = 50                                               'mSec delay counter
   For J = 1 To 15
      Porte_out.0 = 0                                       'On
      Porte_out.1 = 1                                       'Off
      Waitms Msdly
      Porte_out.0 = 1                                       'Off
      Porte_out.1 = 0                                       'On
      Waitms Msdly
   Next J
   Return
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, I should have clarified that I do not wish to use the DAC to generate a signal to use for audio. I just want a range of DC voltages output through the DAC. So I guess I should be asking if this is possible. Thanks!