Analog to Digital
and Digital to Analog
on an Atmel Mega644/1284
ECE 4760 Cornell University
Analog to Digital
There are several ways of converting an analog level to a number using the Mega644/1284, but this discussion will concentrate on using the built-in, 8-channel, 10-bit, successive approximation analog to digital converter (ADC). As with all the Mega644/1284 peripherials, there are a large number of ways of using the buit-in ADC. The input impedance of the ADC is around 100 MOhms, but the maximum source impedance for accurate operation of the sample-and-hold is 10 KOhm. Best accuracy requires that the ADC prescalar output be less than 200 KHz (resulting in about 15 KHz sample rate), but no lower than 50 KHz (to avoid sample-and-hold droop). The ADC will operate up to 1 MHz (about 75 KHz sample rate) with reduced accuracy. Of course, you must always low pass filter the analog input appropriately before feeding it to the ADC to avoid aliasing.
Is is a good idea to read chapter 23 of the mega1284 manual before using the ADC.
There are lots of details not covered in this page, such as autotriggering modes and power saving.
Simple polling.
The simplest way of using the ADC is to start a conversion in software, wait until it is done, read it, and repeat. This program (plus uart.c and uart.h) reads the ADC, starts a conversion, prints the value of the last conversion and repeats. The program polls the ADC completion bit (ADCSRA, ADSC bit
goes low when conversion is complete), then the actual (8-bit) A/D conversion result, then starts a new conversion and prints the value to the USART. The program sets up the ADC to read left-adjusted, 8-bits only, using an internal Vref=Vcc
. On the STK500 board, the Vref jumper
must be un-mounted.
while(1)
loop it encounters an assembler sleep
command. The MCU is disabled, the conversion is automatically started and runs, then the MCU is restarted and immedately executes the ADC ISR. Then execution resumes after the sleep
command. Of course, to actually get 10-bit accuracy, you have to minimize outside interference, such as 60 Hz noise. If you don't need more than 8-bit accuracy, then you don't need to put the MCU to sleep. You can just define an ADC ISR, turn on the ADC interrupt, and the MCU will enter the ISR when the conversion is finished.10*(channel1-channel0)
. Voltages at both inputs have to be between zero and Vref
. Clearly, if you are using gain, you must make sure that the amplified difference is also between -Vref and Vref
. The test inputs are shown below. Each potentiometer was adjusted to the middle of its range initially. Calibration of the ADC and internal differential preamp was verified with a voltmeter between the two wipers of the potentiometers. Note that differential mode is somewhat slower than single ended, has a high order 2's complement sign bit, and the differential amplifier has an analog bandwidth of 4 KHz. The data sheet says: "The differential input channels are not tested for devices in PDIP Package. This feature is only guaranteed to work for devices in TQFP and VQFN/QFN/MLF Packages.", but the differential input has worked in PDIP for me.Digital to Analog
There is no built-in D/A on the Mega644/1284, but there are easy ways of converting numbers to voltages. I will describe three here:
(8-bit timer output compare register)/256*(5 volts)
. A short example shows how you might implement a Direct Digital Synthesis (DDS) sine wave generator and output it through a PWM. Copyright Cornell University August 15, 2012