Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Assembly routine for ADC0831 with AT89C51

Status
Not open for further replies.

Noman Yousaf

Full Member level 4
Joined
Nov 19, 2003
Messages
208
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,298
Location
Lahore Pakistan
Activity points
1,763
I want to use serial ADC #ADC0831.
I got it's datasheet but in that sheet, mostly written about ADC0832-8
can any body tell me the routine in assembly of AT89C51?
 

ADC0831 with AT89C51

I have the routine but for DS89C420 - 8051.
 

Re: ADC0831 with AT89C51

hi..
This posty is old, but it can be usefull for new users..

ADC0831 C code:

Code:
#define AD_CS pin_A0
#define AD_CK pin_A1
#define AD_DO pin_A2

int ADC_result;
void read_adc()
{
    int i;
    output_low(AD_CS);      //Select chip (initiate conversion.

    for (i=0; i<2; i++)
     {
        output_high(AD_CK);   //cycle clock twice (while converstion starts.
        delay_us(10);
        output_low(AD_CK);
        delay_us(10);
     }
    for (i=0;i<8;i++)
     {     //Read in value from A/D convertor
        output_high(AD_CK);
        delay_us(10);
        shift_left(&ADC_result, 1, input(AD_DO));
        output_low(AD_CK);
        delay_us(10);
    }

    output_high(AD_CK); //cycle clock once.
    delay_us(10);
    output_low(AD_CK);
    delay_us(10);

    output_high(AD_CS); //Deselect chip.
    //return ADC_result;
}

You can use:

Code:
float val=read_adc()*5/255.0

Bye
 

Re: ADC0831 with AT89C51

code will be same for all these ADCs the only difference b/w them is that they have no. of inputs. I once written code for ADC0831 but I don't know where I have kept in my PC, if I find I will post you that was for ADC0831 + 2051 temperature display.

regards
 

Re: ADC0831 with AT89C51

HI

Yes....I found in my old files this code for ADC0832...

Code:
// *******************************************
// ADC0832 v0.1
// Provides Single-Ended and Differential Mode
// *******************************************

#define AD_CK pin_A1    // Clock
#define AD_DO pin_A3    // Data Out
#define AD_DI pin_A2    // Data In (MUX Channel Selector). Use a PULL-UP resistor
#define AD_CS pin_A0    // Chip Select
 

int adc_result;
int MUX;

void  Clock() {
      output_high(AD_CK);
      output_low(AD_CK);
}

void set_adc(short ch, short mode)  {   //SGL:1/0 ==>Single-Ended/Differential Mode
      int i;
       if(mode==1 & ch==0)    {
       MUX=2;
       }
       if(mode==1 & ch==1)    {
       MUX=3;
       }
       if(mode==0 & ch==0)    {
       MUX=0;
       }
       if(mode==0 & ch==1)    {
       MUX=1;
       }
       output_high(AD_CS);          //CS=1, disable ADC0832
       output_low(AD_CS);           //CS=0, enable ADC0832
       output_high(AD_DI);          //Start BIT
       Clock();

       for (i=0;i<2;i++) {          //Send MUX word
       if((MUX & 0x2)==0)  {        //
         output_low(AD_DI);         //
         }
         else {                     //
         output_high(AD_DI);        //
         }
         MUX<<= 1;
         Clock();

         }
}


void read_adc() {
    int i;
    for (i=0;i<8;i++) {          
         Clock();                
         shift_left(&adc_result, 1, input(AD_DO));
         }
         output_high(AD_CS);
}

Code:
#include <16f628.h>
#use delay(clock=4000000)
#fuses NOWDT,INTRC_IO, PUT, NOPROTECT, BROWNOUT, MCLR, NOLVP, NOCPD
#include "ADC0832.c"
#include "flex_lcd_20x4.c"

float value;

float read_adc0832(int i, int mode){
   set_adc(i,mode);
   read_adc();
   value=(adc_result/51.0);
   return value;
}

void main() {
   int i;
   lcd_init();
   lcd_gotoxy(1,1);
   printf(lcd_putc,"**16F628A Running**");
   //delay_ms(1000);
   //lcd_gotoxy(1,2);
   //for(i=0;i<=18;i++) {
   //lcd_putc(".");
   //delay_ms(100);    }
   //delay_ms(2000);
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Channel 0=    Volts");
   lcd_gotoxy(1,3);
   printf(lcd_putc,"Channel 1=    Volts");
   //delay_ms(500);
   while(TRUE)   { 
      lcd_gotoxy(9,2);
      printf(lcd_putc,"%1.1f",read_adc0832(0,1)); //Single Ended Mode
      lcd_gotoxy(9,3);
      printf(lcd_putc,"%1.1f",read_adc0832(1,1)); //Single Ended Mode
      //lcd_gotoxy(1,4);
      //printf(lcd_putc,"read value: %Lu",v);
      delay_ms(10);                   
   }


}



/*
for(i=0;i<2;i++){
   set_adc(i,1);
   read_adc();
   
   value=(adc_result/51.0);     //escale 0-5 volt
   putc(13); //\r or carrier return
   printf("adc_result=%X\n\r",adc_result);
   printf("Channel Voltage %i = %01.4f Volts",i,value);
   printf("\n\n\n\r");
   delay_ms(1000);
}
printf("\n\n\n\r");
}
}
*/

Code:
// Flex_LCD420.c

// These pins are for my Microchip PicDem2-Plus board,
// which I used to test this driver.
// An external 20x4 LCD is connected to these pins.
// Change these pins to match your own board's connections.

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_RS    PIN_B3
#define LCD_RW    PIN_B2
#define LCD_E     PIN_B1

/*
// To prove that the driver can be used with random
// pins, I also tested it with these pins:
#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_B1
#define LCD_DB6   PIN_C5
#define LCD_DB7   PIN_B5

#define LCD_RS    PIN_E2
#define LCD_RW    PIN_B2
#define LCD_E     PIN_D6
*/

// If you want only a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.  Doing so will save one PIC
// pin, but at the cost of losing the ability to read from
// the LCD.  It also makes the write time a little longer
// because a static delay must be used, instead of polling
// the LCD's busy bit.  Normally a 6-pin interface is only
// used if you are running out of PIC pins, and you need
// to use as few as possible for the LCD.
#define USE_RW_PIN   1     


// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54

// These are the line addresses for LCD's which use
// the Hitachi HD66712U controller chip.
/*
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x20
#define LCD_LINE_3_ADDRESS 0x40
#define LCD_LINE_4_ADDRESS 0x60
*/


//========================================

#define lcd_type 2   // 0=5x7, 1=5x10, 2=2 lines(or more)

int8 lcd_line;

int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2),  // Set mode: 4-bit, 2+ lines, 5x8 dots
 0xc,                     // Display on
 1,                       // Clear display
 6                        // Increment cursor
 };
                             

//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2)); 
 output_bit(LCD_DB6, !!(nibble & 4));   
 output_bit(LCD_DB7, !!(nibble & 8));   

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.     

#ifdef USE_RW_PIN
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;
   
output_high(LCD_E);
delay_us(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
 
output_low(LCD_E);
delay_us(1);
   
return(retval);   
}   
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_RW_PIN
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_RW_PIN
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60); 
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);
     
 delay_cycles(1);

#ifdef USE_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------

void lcd_init(void)
{
int8 i;

lcd_line = 1;

output_low(LCD_RS);

#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif

output_low(LCD_E);

// Some LCDs require 15 ms minimum delay after
// power-up.  Others require 30 ms.  I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);         

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);
   
    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 50 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_RW_PIN
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;


switch(y)
  {
   case 1:
     address = LCD_LINE_1_ADDRESS;
     break;

   case 2:
     address = LCD_LINE_2_ADDRESS;
     break;

   case 3:
     address = LCD_LINE_3_ADDRESS;
     break;

   case 4:
     address = LCD_LINE_4_ADDRESS;
     break;

   default:
     address = LCD_LINE_1_ADDRESS;
     break;
     
  }

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      lcd_line = 1;
      delay_ms(2);
      break;
   
    case '\n':
       lcd_gotoxy(1, ++lcd_line);
       break;
   
    case '\b':
       lcd_send_byte(0,0x10);
       break;
   
    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_RW_PIN
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7)); 

output_high(LCD_RS);
value = lcd_read_byte();
output_low(LCD_RS);

return(value);
}
#endif

Added after 19 minutes:

And for ADC0834....

Code:
#include <16f628.h>
#use delay(clock=4000000)
#fuses NOWDT,INTRC_IO, PUT, NOPROTECT, BROWNOUT, MCLR, NOLVP, NOCPD
#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_B2, RCV=PIN_B1)
#include "adc0834.c"

float value;
void main() {

 while(1) {
   int a;
   for(a=0;a<4;a++) {
   value=0;
   set_adc(a,SGL);
   read_adc();
   value=(adc_result/51.0);     //0-5 volt scale
   putc(13);
   printf("adc_result=%X\n\r",adc_result);
   printf("Voltage Channel %d = %3.2f Volts",a,value);
   printf("\n\n\n\r");
   delay_ms(1000);
}
}
}

Code:
// ***************************************

// (Single-Ended)
// Diferential (Dif)

#define AD_CK pin_A1    // Clock
#define AD_DO pin_A3    // Data Out
#define AD_DI pin_A2    // Data In (MUX Channel Selector)
#define AD_CS pin_A0    // Chip Select
#define SGL 1           // Single-Ended Mode
#define DIF 0           // Diferential Mode

int adc_result;
int MUX;

void  Clock() {
      output_high(AD_CK);
      output_low(AD_CK);
}

void set_adc(int ch, short mode)  {
       int i;
       if(mode==SGL)
       switch(ch)    {
         case 0: MUX=4; break;
         case 1: MUX=6; break;
         case 2: MUX=5; break;
         case 3: MUX=7; break;
         }
         else
         switch(ch)  {
         case 0: MUX=0; break;
         case 1: MUX=2; break;
         case 2: MUX=2; break;
         case 3: MUX=3; break;

         }

       output_high(AD_CS);             //CS=1, disable ADC0834
       output_low(AD_CS);              //CS=0, enable  ADC0834
       output_high(AD_DI);             //Start BIT
       Clock();

       for (i=0;i<3;i++) {             //Send MUX word into ADC0834
       if((MUX & 0x4)==0)  {           
         output_low(AD_DI);           
         }
         else {                        
         output_high(AD_DI);           
         }
         MUX<<= 1;
         Clock();
         }
}

void read_adc() {
    int i;
    for (i=0;i<8;i++) {
         Clock();
         shift_left(&adc_result, 1, input(AD_DO));
         }
         output_high(AD_CS);
}

bye
 

ADC0831 with AT89C51

**broken link removed**
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top