Connecting ADC to Microcontrollers Tutorial

Microcontroller Topics
Post Reply
User avatar
Reginald
Sergeant Major
Sergeant Major
Posts: 29
Joined: Mon Aug 03, 2009 9:54 pm
Location: Mount Lavinia

Connecting ADC to Microcontrollers Tutorial

Post by Reginald » Sun Sep 20, 2009 5:52 am

Introduction
In our daily life, anything we deal like sound, pressure, voltage or any measurable quantity, are usually in analog form So what if we want to interface any analog sensor with our digital controllers? There must be something that translate the analog inputs to digital output, and so Analog to digital converters come to play. Usually we call them ADC (Analog to digital converter). Before going to learn how to interface an ADC with a controller we first take a look at basic methods of analog to digital conversion.

This is a sample of the large number of analog-to-digital conversion methods. The basic principle of operation is to use the comparator principle to determine whether or not to turn on a particular bit of the binary number output. It is typical for an ADC to use a digital-to-analog converter (DAC) to determine one of the inputs to the comparator.

Following are the most used conversion methods:
  • Digital-Ramp ADC
  • Successive Approximation ADC
  • Flash ADC
Digital-Ramp ADC
adc.gif
adc.gif (7.1 KiB) Viewed 4819 times
Conversion from analog to digital form inherently involves comparator action where the value of the analog voltage at some point in time is compared with some standard. A common way to do that is to apply the analog voltage to one terminal of a comparator and trigger a binary counter which drives a DAC. The output of the DAC is applied to the other terminal of the comparator. Since the output of the DAC is increasing with the counter, it will trigger the comparator at some point when its voltage exceeds the analog input. The transition of the comparator stops the binary counter, which at that point holds the digital value corresponding to the analog voltage.

Successive Approximation ADC
Illustration of 4-bit SAC with 1 volt step size
adc3.gif
adc3.gif (4.6 KiB) Viewed 4819 times
The successive approximation ADC is much faster than the digital ramp ADC because it uses digital logic to converge on the value closest to the input voltage. A comparator and a DAC are used in the process. A flowchart explaining the working is shown in the figure below.
adc4.gif
adc4.gif (3.01 KiB) Viewed 4819 times
Flash ADC
adc5.gif
adc5.gif (3.03 KiB) Viewed 4819 times
Illustrated is a 3-bit flash ADC with resolution 1 volt (after Tocci). The resistor net and comparators provide an input to the combinational logic circuit, so the conversion time is just the propagation delay through the network - it is not limited by the clock rate or some convergence sequence. It is the fastest type of ADC available, but requires a comparator for each value of output (63 for 6-bit, 255 for 8-bit, etc.) Such ADCs are available in IC form up to 8-bit and 10-bit flash ADCs (1023 comparators) are planned. The encoder logic executes a truth table to convert the ladder of inputs to the binary number output.

Now we lets take a look at the various Analog to Digital converters that are most commonly used with our controllers
NameDescription
ADC08008-bit ADC
ADC08018-bit ADC 100us 0.25 LSB
ADC08028-bit ADC 100us 0.5 LSB
ADC08048-bit ADC 100us 1.0 LSB
ADC08088-bit 8 channel 100us ADC
ADC08098-Bit 8 channel ADC (=~ADC0808)
AD57110-Bit, A/D Converter, Complete with Reference and Clock
MAX12045V, 8-Channel, Serial, 10-Bit ADC with 3V Digital Interface
MAX12025V, 8-Channel, Serial, 12-Bit ADCs with 3V Digital Interface
MAX19516-Bit, Self-Calibrating, 10us Sampling ADC
More information on how to interface the above listed ADC can be obtained from the datasheets of respective ICs. In the next part of tutorial we will look into the interfacing and programming of a simple 8-bit ADC (ADC0804).

ADC0804 Pinout and Typical Connections
adc0804.gif
adc0804.gif (11.1 KiB) Viewed 4818 times
As shown in the typical circuit, ADC0804 can be interfaced with any microcontroller. You need a minimum of 11 pins to interface ADC0804, eight for data pins and 3 for control pins. As shown in the typical circuit the chip select pin can be made low if you are not using the microcontroller port for any other peripheral (multiplexing).

There is a universal rule to find out how to use an IC. All you need is the datasheet of the IC you are working with and take a look at the timing diagram of the IC which shows how to send the data, which signal to assert and at what time the signal should be made high or low etc.

Note: Keep this in mind that whenever you are working with an IC and you want to know how to communicate with that IC, then simply look into the timing diagram of that IC from its datasheet. It gives you complete information that you need regarding the communication of IC.
adc0804-timing.gif
adc0804-timing.gif (6.58 KiB) Viewed 4818 times
adc0804-timing1.gif
adc0804-timing1.gif (5.02 KiB) Viewed 4818 times
The above timing diagrams are from ADC0804 datasheet. The first diagram (FIGURE 10A) shows how to start a conversion. Also you can see which signals are to be asserted and at what time to start a conversion. So looking into the timing diagram FIGURE 10A. We note down the steps or say the order in which signals are to be asserted to start a conversion of ADC. As we have decided to make Chip select pin as low so we need not to bother about the CS signal in the timing diagram. Below steps are for starting an ADC conversion. I am also including CS signal to give you a clear picture. While programming we will not use this signal.
  1. Make chip select (CS) signal low.
  2. Make write (WR) signal low.
  3. Make chip select (CS) high.
  4. Wait for INTR pin to go low (means conversion ends).

Once the conversion in ADC is done, the data is available in the output latch of the ADC. Looking at the FIGURE 10B which shows the timing diagram of how to read the converted value from the output latch of the ADC. Data of the new conversion is only available for reading after ADC0804 made INTR pin low or say when the conversion is over. Below are the steps to read output from the ADC0804.
  1. Make chip select (CS) pin low.
  2. Make read (RD) signal low.
  3. Read the data from port where ADC is connected.
  4. Make read (RD) signal high.
  5. Make chip select (CS) high.
In the next section of this tutorial we will follow the above mentioned steps to program the ADC.

Programming AVR Microcontroller

ASM Code

Code: Select all

.include "8515def.inc"

.equ rd = PORTB0           ;Read signal PortB.0
.equ wr = PORTB1           ;Write Signal PortB.1
.equ cs = PORTB2           ;Chip Select PortB.2
.equ intr = PORTB3         ;INTR signal PortB.3
.equ adc_port = PINA       ;ADC data pins PortA
.def adc_val = r16         ;To store ADC value
.def temp = r17            ;Temporary register

.org 0x00
start:
        ldi temp,low(RAMEND)   ;Load stack with
        out SPL,temp           ;RAMEND - highest value
        ldi temp,high(RAMEND)  ;of internal SRAM
        out SPH,temp

        sbi DDRB,rd            ;Make RD as o/p
        sbi DDRB,wr            ;Make WR as o/p
        sbi DDRB,cs            ;Make CS as o/p
again:
        rcall conv             ;Start ADC Conversion
        rcall read             ;Read ADC conversion
        ldi temp,0xFF
        out DDRC,temp          ;Make PORTC as o/p Port
        out PORTC,adc_val      ;Move the read value to PORT C
        rjmp again             ;Do it again

conv:                      ;Start conversion
        cbi PORTB,cs           ;Make CS low
        cbi PORTB,wr           ;Make WR low
        nop
        sbi PORTB,wr           ;Make WR high
        sbi PORTB,cs           ;Make CS high
wait:
        sbic PINB,intr         ;Wait for INTR signal
        rjmp wait

        ret                    ;Conversion done
       
read:                      ;Read ADC
        cbi PORTB,cs           ;Make CS low
        cbi PORTB,rd           ;Make RD low

        in adc_val,adc_port    ;Read ADC data

        sbi PORTB,rd           ;Make RD high
        sbi PORTB,cs           ;Make CS high
        ret                    ;Reading done
C Code

Code: Select all

#include <avr/io.h>#define adc_port PINA                    //ADC data pins PORTA
#define rd PB0                           //Read signal PORTB0
#define wr PB1                           //Write signal PORTB1
#define cs PB2                           //Chip Select PORTB2
#define intr PB3                         //INTR signal PORTB3

void conv();                             //Start Conversion
void read();                             //Read ADC value

unsigned char adc_val;

int main(){
        DDRB = (1<<rd)|(1<<wr)|(1<<cs);      //RD, WR, CS as output
        DDRC = 0xFF;                         //PORTC as output
        PORTC = 0xFF;
        while(1){                            //Forever loop
                conv();                          //Start of conversion
                read();                          //Read converted ADC
                PORTC = adc_val;                 //Move it to PORTC
        }
        return 0;
}


void conv(){
        PORTB = PORTB & (~((1<<cs)|(1<<wr))); //Make CS and WR low
        PORTB = PORTB | ((1<<cs)|(1<<wr));    //Make CS and WR high
        while(PINB&(1<<intr));                //Wait for INTR signal
}

void read(){
        PORTB = PORTB & ( ~((1<<cs)|(1<<rd))); //Make RD and CS low
        adc_val = adc_port;                    //Read ADC port
        PORTB = PORTB | ((1<<cs)|(1<<rd));     //Make RD and CS high
}
The next section of the tutorial will cover the programming of 8051 for ADC0804.

Programming 8051 Microcontroller

ASM Code

Code: Select all

        rd equ P1.0           ;Read signal P1.0
        wr equ P1.1           ;Write signal P1.1
        cs equ P1.2           ;Chip Select P1.2
        intr equ P1.3         ;INTR signal P1.3

        adc_port equ P2       ;ADC data pins P2
        adc_val equ 30H       ;ADC read value stored here

        org 0H
start:                    ;Start of Program
        acall conv            ;Start ADC conversion
        acall read            ;Read converted value
        mov P3,adc_val        ;Move the value to Port 3
        sjmp start            ;Do it again

conv:                     ;Start of Conversion
        clr cs                ;Make CS low
        clr wr                ;Make WR Low
        nop
        setb wr               ;Make WR High
        setb cs               ;Make CS high
wait:
        jb intr,wait          ;Wait for INTR signal
        ret                   ;Conversion done

read:                     ;Read ADC value
        clr cs                ;Make CS Low
        clr rd                ;Make RD Low
        mov a,adc_port        ;Read the converted value
        mov adc_val,a         ;Store it in local variable
        setb rd               ;Make RD High
        setb cs               ;Make CS High
        ret                   ;Reading done
C Code

Code: Select all

#include <REGX51.H>#define adc_port P2              //ADC Port
#define rd P1_0                  //Read signal P1.0
#define wr P1_1                  //Write signal P1.1
#define cs P1_2                  //Chip Select P1.2
#define intr P1_3                //INTR signal P1.3

void conv();                     //Start of conversion function
void read();                     //Read ADC function

unsigned char adc_val;

void main(){
        while(1){                    //Forever loop
                conv();                  //Start conversion
                read();                  //Read ADC
                P3 = adc_val;            //Send the read value to P3
        }
}

void conv(){
        cs = 0;                      //Make CS low
        wr = 0;                      //Make WR low
        wr = 1;                      //Make WR high
        cs = 1;                      //Make CS high
        while(intr);                 //Wait for INTR to go low
}

void read(){
        cs = 0;                      //Make CS low
        rd = 0;                      //Make RD low
        adc_val = adc_port;          //Read ADC port
        rd = 1;                      //Make RD high
        cs = 1;                      //Make CS high
}
Post Reply

Return to “Microcontrollers”