clock

Saturday, 25 May 2013

Interfacing ADC0808 to AT89C51 Microcontroller

 WARNING: Before proceeding, I'm not responsible for any damage or short circuit on your circuit. The code and circuit is tested and verified working.

 AIM: To help for understand the c language and embedded systems working in simple way.


What is ADC?
Its basically a device having internal comparators and resistors arrangement which gives you digital output value of a corresponding input voltage.
ADC stands for Analog to Digital Converter.

ADC0808 is 8bit conversion system. For more details read the datasheet.
Converts any analog input into 1byte digital output.
It has all-together 8 analog inputs (IN0 to IN7).
Each analog input has an address which is set through control signals A, B, C.
Clock has to be provided for conversion rate.
Faster clock faster conversion.
They recommend 600KHz clock.
I used 555timer at 687Hz which is good enough to convert data on one analog input.
LM324 is used so that there is no drawing current or loading effect on the input side.

First construct this schematic below on breadboard or pcb. (schematic is tested )



Based on my previous design on 16x2 LCD interface to AT89C51 I'm making advantage of it to display my adc data onto it. But this time I'm using separate header files.

After constructing the above schematic. Lets proceed with programming.
Make project in keil software selecting 89c51 microcontroller.
Now next, right click on target 1 and add a group "headers".
Now create this headers files as told below:

1. To make header files create a new file - > save the file in format "filename.h"
2. Add the files to header group in project workspace.
3. Do the above 2 steps for below codes.
This helps in debugging faster.

Check out the image below how its done. (I made group of source and header files)



Now add this files as show above. Keep them all blank and with same names.
Now open the blank 16_2lcd.h file and enter the code below and save it:

///////////////////////////////////////////INSIDE 16_2lcd.h   FILE////////////////////////////////
#include "AT89X51.H"
#include "delay.h"
#include "stdio.h"
#define RW P0_1
#define RS P0_0
#define EN P0_2
#define DATA P2

int lcd_inst(void);     //Instruction sel
int lcd_data(void);      //Data sel
int lcd_latch(void);       //Latch the bus
int lcd_write_str(char *str, int str_len, int line);       //Write string
int lcd_write_int(int num, int num_len, int line); //Write integer
int lcd_write_float(float num, int num_length, int line); //Write float
int lcd_clear(void); //clears lcd screen
int lcd_linsel(int line);    //Lcd line sel
int lcd_initialize(void);    //Initialize the LCD
///////////////////////////////////////////INSIDE 16_2lcd.h   FILE END////////////////////////////////

 Now open the blank adc0808.h file and enter the code below and save it:

///////////////////////////////////////////INSIDE adc0808.h  START////////////////////////////////

#include "AT89X51.H"
#include "delay.h"


#define OE P3_0
#define ALE P3_1
#define A P3_2
#define B P3_3
#define C P3_4

#define ADC_DATA P1


int read_ain(int ain_pin);//Reads ext. Analong in
int set_analongin(int ain_pin);// Sets in0 to in7 pin select.

///////////////////////////////////////////INSIDE adc0808.h  END////////////////////////////////

Now open the blank  delay.h file and enter the code below and save it:
///////////////////////////////////////////INSIDE delay.h  START////////////////////////////////
 void delay(int n); //Universal delay routine
///////////////////////////////////////////INSIDE delay.h  END////////////////////////////////
Now open the blank  16_2lcd.c  file and enter the code below and save it:
///////////////////////////////////////////INSIDE 16_2lcd.c START////////////////////////////////
#include "16_2lcd.h"

int lcd_inst(void)     //Instruction select
{
    RS=0;
    RW=0;
    return 0;
}

int lcd_data(void) // Data select
{
     RS=1;
     RW=0;
     return 0;
}

int lcd_latch(void) // Latch routine
{
            EN=1;
            delay(100);
            EN=0;
            delay(100);
            EN=1;
            delay(100);
            return 0;
}

int lcd_initialize(void)    //Initialize the LCD
{
             RS=0; 
             RW=0;
             EN=1;
             delay(100000);
             lcd_inst();
             DATA=0X38;     //This instruction will Enable 8-bit Databus, Set 2 lines, and Select font size 5x7
             lcd_latch();
             lcd_latch();
             lcd_latch();
             lcd_latch();
             DATA=0X0c;       //It will display the characters, will not display the cursor
             lcd_latch();
             DATA=0X80;    //Set cursor on line 1
             lcd_latch();
             DATA=0X01;       //Clear screen
             lcd_latch();
             lcd_data();
             return 0;
}

int lcd_clear(void)
{
            lcd_inst();
             DATA=0X01;       //Clear screen
             lcd_latch();
             lcd_data();
            return 0;
}
int lcd_linsel(int line)    //Lcd line sel
{
    lcd_inst();
    if(line==1)
    {
             DATA=0X80;    //Set cursor on line 1
             lcd_latch();          
    }
    if(line==2)
    {
             DATA=0XC0;    //Set cursor on line 2
             lcd_latch();          
    }
    lcd_data();
}

int lcd_write_str(char *str,int str_len, int line)
{
    int i;
    lcd_linsel(line);    //Lcd line sel
    lcd_data();
    for(i=0;i<=str_len-1;i++)
    {
            DATA=str[i];
            lcd_latch();
    }
    return 0;
}

int lcd_write_int(int num,int num_len,int line) //Write integer
{

    int i;
    char str[16];
    str[0]=0;
    str[1]=0;
    str[2]=0;
    lcd_linsel(line);    //Lcd line sel
    lcd_data();
    sprintf(str,"%3.0d",num);
    for(i=0;i<=num_len-1;i++)
    {
            DATA=str[i];
            lcd_latch();
    }
    return 0;
}

int lcd_write_float(float num,int num_len,int line) //Write integer
{

    int i;
    char str[16];
    str[0]=0;
    str[1]=0;
    str[2]=0;
    lcd_linsel(line);    //Lcd line sel
    lcd_data();
    sprintf(str,"%3.3f ",num);
    for(i=0;i<=num_len-1;i++)
    {
            DATA=str[i];
            lcd_latch();
    }
    return 0;
}
///////////////////////////////////////////INSIDE 16_2lcd.c END////////////////////////////////


 Now open the blank  adc0808.c  file and enter the code below and save it:
///////////////////////////////////////////INSIDE adc0808.c START////////////////////////////////
#include "adc0808.h"


int read_ain(int ain_pin)// Reads adc value at given pin
{
  int num;
  ADC_DATA=0xFF;
  OE=0;
  set_analongin(ain_pin);
  OE=1;
  num=ADC_DATA;
  OE=0;
  return num;
}

int set_analongin(int ain_pin)// Sets in0 to in7 pin select.
{
      ALE=0;
    switch(ain_pin)
    {
        case 0: A=0;B=0;C=0;break;
        case 1: A=1;B=0;C=0;break;
        case 2: A=0;B=1;C=0;break;
        case 3: A=1;B=1;C=0;break;
        case 4: A=0;B=0;C=1;break;
        case 5: A=1;B=0;C=1;break;
        case 6: A=0;B=1;C=1;break;
        case 7: A=1;B=1;C=1;break;
        default:break;
    }
    ALE=1;
      delay(100);
      ALE=0;
    return 0;
}
///////////////////////////////////////////INSIDE adc0808.c END////////////////////////////////
 Now open the blank  delay.c  file and enter the code below and save it:

///////////////////////////////////////////INSIDE delay.c START////////////////////////////////
 #include "delay.h"


 void delay(int n) //Universal delay routine
{
 int i=0,j=0;
 for(i=0;i<=n;i++)
 for(j=0;j<=10;j++);
}
 ///////////////////////////////////////////INSIDE delay.c END////////////////////////////////
Now open the blank  main.c  file and enter the code below and save it:
  ///////////////////////////////////////////INSIDE main.c START////////////////////////////////
//Programmed by Macjan Camilo Fernandes
//Test Version 1.0.0

#include "16_2lcd.h"
#include "adc0808.h"
#include "delay.h"
#include "REGX51.H"
#include "stdio.h"

int main(void)
{
    float calc;
    int test,i;
    char mac[16];
P3=0;
 //Initialize LCD
 lcd_initialize();
 lcd_clear();
 //write title
//i can be from 0 to 7 since only 8 channel select
  i=3; // to read analog input at pin in3 of ADC0808
  sprintf(mac,"ADC Data %d in V",i+1);
  lcd_write_str(mac,15,1);       //Write string
 while(1)
 {
   test=read_ain(i); //reads analog input of channel i
   calc= test*0.0195; //calculates voltage for vref=5v vref-=0v
   delay(100);
  //Write_adc data on LCD
  lcd_write_float(calc,5,2);         //Write adc data
 }


return 0;
}
  ///////////////////////////////////////////INSIDE main.c END////////////////////////////////
After doing this above process. Compile and program the microcontroller.
Check the ADC value. 
The adc0808.h and adc0808.c was done by me so that you can make use of adc easily if you include this header files in main code as shown above.
Use this function   
int read_ain(int ain_pin);// Reads adc value at given pin
eg: x=read_ain(3); 
This instruction above will store value of adc input IN3 value into x variable which you can then process into your desired calculations.
You can go though the header files and source files for deeper details.

Some snapshots of my demo for one ADC input at ADC0808 in3



All the best to you,
Will be updating my blog with lots of interfaces. Be in touch.
Thank you for reading,

2 comments :

  1. help me :
    2 channel pressure ( 2 pressure 100bar)
    if : pressure A > pressure B
    => A-B = LCD 16x2 and programer computer ( RS 232)

    else pressure B> pressure A
    => B-A = LCD 16x2 and programer computer ( RS 232)

    ReplyDelete
  2. help me :
    2 channel pressure ( 2 pressure 100bar)
    if : pressure A > pressure B
    => A-B = LCD 16x2 and programer computer ( RS 232)

    else pressure B> pressure A
    => B-A = LCD 16x2 and programer computer ( RS 232)

    ReplyDelete