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.

help needed in interfacing ADC0804 and HY62256(S-ram) to

Status
Not open for further replies.

vinash

Member level 2
Member level 2
Joined
Nov 3, 2005
Messages
45
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,999
Hi,
I have tried to interface ADC0804 and HY62256(S-ram) to AT89C52 microcontroller. The whole idea is to do an A/D conversion using ADC 0804 and than storing the data input to the SRAM. The code that i had developed is below for reference. It does not seem to work. ( Even when i do not give an input signal to the ADC, the LED keeps blinking) Could someone please tell me if there is anything wrong with my code. Thank you.

#include <reg52.h>

void delay(void);
unsigned char xdata * data addr = 0x0000; // declares a pointer staring from external memory address of 0x0000
sbit WRITE=P3^0; // defining the WR and INTR pins
sbit INTR=P3^2 ;// The INTR pin is connected to the INTO pin, so that whenever it goes low, it cause an interrupt
sbit LED=P3^1;
unsigned int advalue,value,j;


void ex0_isr (void) interrupt 0 // interrupt that is activated whenever P3^2 goes low
{ P1=0xFF; // declaring P1 as input data after A/D conversion
advalue=P1; // assigning the input bits (A/D bits) to advalue
if(addr!=0xFFFF) // keep on storing the 8 bit values obtained from the ADC in address starting from 0x0000 till
// the S-RAM gets full.
{LED=1; // to check whether there is any conversion
for(j=0;j<2000;j++);
*addr++ =value;
LED=0; //to check whether there is any conversion
delay(); // delay function
}

else
{
EX0 =0; // If the S-ram is full, disable external interrupt 0 and the Global interrupt flag
EA=0;
}
}


void main(void){
EX0 = 1; // Enable EX0 Interrupt, this function is to enable (set) or disable(clear) External intrrupt 0
EA = 1; // Enable Global Interrupt Flag
IT0=0; // Interrupt 0 type control bit.Set/cleared by software to specify falling edge/low level triggered External interrupt
P1=0xFF; // Declaring P1 as an input

while(1) {

WRITE=0; // AD conversion;
WRITE=1;
while(INTR==1);
delay();

}
}



void delay (void) // Delay function using Timer 0 for 50ms.
{
TMOD &=0xF0;
TMOD |=0x01;
ET0 =0;
TH0 =0x3C;
TL0 =0xB0;
TF0 =0;
TR0 =1;
while(TF0==0);
TR0=0;

}
 

Just at first glance:

You have a while(1) loop in the main program where you start the conversion by giving a pulse on ADC0804 /WR line via P3.0 at periodic 50 ms.
At the end of each conversion EOT, INTR goes low and a service interrupt is performed.
Though the HY62256 it's mapped only up to 7FFF, you count up to 0xFFFF. Let's say it's harmless even if the last 32768 conversion overide the first 32768 ones.
But what is more important is that 65535 x 50 ms = 3276750 ms = 3276 seconds, well almost one hour.
Hope you didn't wait to see if the LED stops blinking after one hour !
And that assuming you have an XTAL of 11.059.200 HZ and usual 12 clocks per machine cycle (the timer T0 starts at 15536 decimal and rollover 50.000 counts later - with 1 us per count)
And even regardless of additional delay inside ISR of INT0 (for(j=0;j<2000;j++);)


Don't you think that *addr++ = advalue;
Because advalue = P1; // assigning the input bits (A/D bits) to advalue
Or you performed some ADC conversion and "value' and "advalue" are somehow related ?
 

    vinash

    Points: 2
    Helpful Answer Positive Rating
HI Silvio,
Thanx for pointing out my mistake, i have rectified them and it seems to work. But now i have another problem. I am trying to store the data into the SRAM and also trying to display the value on a display. The display does not seem to work, it always display 0. And another problem i had encountered is , even when there is no input signal to the ADC, the SRAM continues storing data. My code is below for your reference. It would be very helpful, if you could advice me on it. Thank you.

#include <reg52.h>

void delay(void);
unsigned char xdata * data addr = 0x0000; // declares a pointer staring from external memory address of 0x0000
sbit WRITE=P3^0; // defining the WR and INTR pins
sbit INTR=P3^2 ;// The INTR pin is connected to the INTO pin, so that whenever it goes low, it cause an interrupt
sbit READ=P3^3; //This is the READ pin ( for ADC)
sbit LED=P3^1;
sbit BLANK=P3^5; // I am using HP 5082-7340 (display) and the display blanks when this pin goes high
unsigned int advalue,value,j,converted,k;
scanled (); // to display the ADC value on HP 5082-7340 display



void ex0_isr (void) interrupt 0 // interrupt that is activated whenever P3^2 goes low
{ P1=0xFF; // declaring P1 as input data after A/D conversion
READ=0;
BLANK=1; /* The display is blanked so that no values would be displayed on the display
as Port 1 is used as both input from ADC and also used to connect to the display */
advalue=P1; // assigning the input bits (A/D bits) to advalue
READ=1;
if(addr<=0x0014) /* keep on storing the 8 bit values obtained from the ADC in address starting from 0x0000 till
the S-RAM stores data till the address reaches 0x0014 */
{LED=1; // to check whether there is any conversion
*addr++ =advalue; // to store the values into the address
LED=0;
//to check whether there is any conversion

}

else
{
EX0 =0; // If the S-ram stores value till desired address, disable external interrupt 0 and the Global interrupt flag
EA=0;
LED=1;


}
scanled(); // Display the input signal value on display
delay();
}


void main(void){
EX0 = 1; // Enable EX0 Interrupt, this function is to enable (set) or disable(clear) External intrrupt 0
EA = 1; // Enable Global Interrupt Flag
IT0=0; // Interrupt 0 type control bit.Set/cleared by software to specify falling edge/low level triggered External interrupt
P1=0xFF; // Declaring P1 as an input

while(1) {

WRITE=0; // AD conversion;
WRITE=1;
while(INTR==1);
BLANK=1;
delay();
LED=1;

}
}


scanled()
{
unsigned int a[10]={0xE0,0xF0,0xE1,0xF1,0xE2,0xF2,0xE3,0xF3,0xE4,0xF4}; // Configuration for display from 0-9
P1=0x00; // declare P1 as output
BLANK=0; // The Blank is made low so that the HP display shows numbers
converted=(*addr)*(5/256); // Convert the ADC value obtained so that the input signal is between 0-5V;
P1=a[converted%10]; // Display the value on Port1;

for(j=0;j<20000;j++);
}




void delay (void) // Delay function using Timer 0 for 50ms.
{
TMOD &=0xF0;
TMOD |=0x01;
ET0 =0;
TH0 =0x3C;
TL0 =0xB0;
TF0 =0;
TR0 =1;
while(TF0==0);
TR0=0;

}
 

Why do you think that SRAM continues storing data ? The P3.1 status ?

Inside INT0 ISR the scanled() function is called. But what is the value of "addr" at statement converted=(*addr)*(5/256);
Just because prior of calling scanled() function you have the statement *addr++ =advalue; // to store the values into the address
What are the precedence of unary operators in C ?
*addr++ means :
1. increment the addr and then store the value of advalue to a cell memory pointed to by addr
or
2. store the value of advalue to a cell memory pointed to by addr, then increment the addr

You performed 20 conversion at 100ms period (not counting time spent with for(j=0;j<20000;j++) inside scanled function).
Thus you have 20 calls to scanled() function during 2 seconds and end up displaying the contents of SRAM.... well guess what's the address

The INTR of ADC0804 will signal the end of conversion by a high-to-low transition and stays low until a data read occurs (/CS and /RD both held low) or a new start conversion (low-to-high transition on /WR with /CS low)
You're lucky that happens because you set the INT0 trigger on low level rather than falling edge and ADC read occurs inside ISR INT0 (that avoid continuos ISR entry)
However, even if your code is correct I would try IT0=1; Just for confidence.
 

HI Silvio,
Thanks for your help again, Yup with regards to storing data, i do think it is storing cos the LED switches off after some.
with regards to
What are the precedence of unary operators in C ?
*addr++ means :
1. increment the addr and then store the value of advalue to a cell memory pointed to by addr
or
2. store the value of advalue to a cell memory pointed to by addr, then increment the addr
It is the first one where *addr++ means :
increment the addr and then store the value of advalue to a cell memory pointed to by addr

As for your advice on


Inside INT0 ISR the scanled() function is called. But what is the value of "addr" at statement converted=(*addr)*(5/256);
Just because prior of calling scanled() function you have the statement *addr++ =advalue; // to store the values into the address

I have written another code which does not involve interrupts at all, The LED switches on for a short while and then it switches off, but the display still shows 0;
The code is below for your reference.
#include <reg52.h>

void delay(void);
unsigned char xdata * data addr = 0x0000; // declares a pointer staring from external memory address of 0x0000
sbit WRITE=P3^0; // defining the WR and INTR pins
sbit INTR=P3^2 ;// The INTR pin is connected to the INTO pin, so that whenever it goes low, it cause an interrupt
sbit READ=P3^3; //This is the READ pin ( for ADC)
sbit LED=P3^1;
sbit BLANK=P3^5; // I am using HP 5082-7340 (display) and the display blanks when this pin goes high
unsigned int advalue,value,j,converted,k;
scanled (); // to display the ADC value on HP 5082-7340 display






void main(void){


while(1) {

WRITE=0; // AD conversion;
WRITE=1;
while(INTR==1);
delay();
BLANK=1;
P1=0xFF; // declaring P1 as input data after A/D conversion
READ=0;

advalue=P1; // assigning the input bits (A/D bits) to advalue
READ=1;
if(addr<=0x0014) /* keep on storing the 8 bit values obtained from the ADC in address starting from 0x0000 till
the S-RAM stores data till the address reaches 0x0014 */
{LED=1; // to check whether there is any conversion (by toggling the LED)
*addr++ =advalue; // to store the values into the address
LED=0;
scanled(); // to display the input signal value on an adc
delay();
} //to check whether there is any conversion

else{
LED=1;
}

delay();


}
}


scanled()
{
unsigned int a[10]={0xE0,0xF0,0xE1,0xF1,0xE2,0xF2,0xE3,0xF3,0xE4,0xF4}; // Configuration for display from 0-9
P1=0x00; // declare P1 as output
BLANK=0; // The Blank is made low so that the HP display shows numbers
converted=(*addr)*(5/256); // Convert the ADC value obtained so that the input signal is between 0-5V;
P1=a[converted%10]; // Display the value on Port1;


for(j=0;j<20000;j++);
}




void delay (void) // Delay function using Timer 0 for 50ms.
{
TMOD &=0xF0;
TMOD |=0x01;
ET0 =0;
TH0 =0x3C;
TL0 =0xB0;
TF0 =0;
TR0 =1;
while(TF0==0);
TR0=0;

}
I really dont know where i went wrong.
 

How about if you write
converted=(*addr)*(5/256);

this way:

converted=(*addr)*5/256;
 

HI Silvio,
I have tried what you have suggested, it still does not work. I am attaching my schematic and the code...I dont know whether my hardware is wrong....

I do have another doudt, I have always tied the EA (Pin 31) to high cos i am reading my program from the internal ROM, when i try to read the data from the SRAM, do i have make EA low? cos i am reading from an external device?

I also have another question to ask also, Would it be possible for me to use P1 as both input from ADC to the microcontroller and also as to drive the HP LED (as in the Schematic). I have tried to do that in this project, (Even though i disable the ADC when i try to use P1 to drive the HP display, it does not show the value). Please do help. Thank you so much.

The code is below for your reference:

#include <reg52.h>

void delay(void);
unsigned char xdata * data addr = 0x0000; // declares a pointer staring from external memory address of 0x0000
sbit WRITE=P3^0; // defining the WR and INTR pins
sbit INTR=P3^2 ;// The INTR pin is connected to the INTO pin, so that whenever it goes low, it cause an interrupt
sbit READ=P3^3; //This is the READ pin ( for ADC)
sbit LED=P3^1;
sbit CS=P3^4; // Used as Chip select for ADC0804
sbit BLANK=P3^5; // I am using HP 5082-7340 (display) and the display blanks when this pin goes high
unsigned int advalue,value,j,converted,k;
scanled (); // to display the ADC value on HP 5082-7340 display






void main(void){


while(1) {
P1=0xFF; // declaring P1 as input data after A/D conversion
BLANK=1; // Blank the Display
CS=0; // To enable the ADC chip

WRITE=0; // AD conversion;
WRITE=1;
while(INTR==1);
delay();

READ=0;

advalue=P1; // assigning the input bits (A/D bits) to advalue
delay();
READ=1;
CS=1; //To disable the ADC,so that no conversion occurs
for (j=0;j<20;j++){delay();} // delay for about 1 second

if(addr<=0x0014) /* keep on storing the 8 bit values obtained from the ADC in address starting from 0x0000 till
the S-RAM stores data till the address reaches 0x0014 */
{LED=1; // to check whether there is any conversion (by toggling the LED)
*addr++ =advalue; // to store the values into the address
LED=0;
scanled(); // to display the input signal value on an adc
delay();
} //to check whether there is any conversion

else{
LED=1;
}

delay();


}
}


scanled()
{
unsigned int a[10]={0xE0,0xF0,0xE1,0xF1,0xE2,0xF2,0xE3,0xF3,0xE4,0xF4}; // Configuration for display from 0-9
P1=0x00; // declare P1 as output
BLANK=0; // The Blank is made low so that the HP display shows numbers
converted=(advalue)*5/256; // Convert the ADC value obtained so that the input signal is between 0-5V;
P1=a[converted%10]; // Display the value on Port1;



}




void delay (void) // Delay function using Timer 0 for 50ms.
{
TMOD &=0xF0;
TMOD |=0x01;
ET0 =0;
TH0 =0x3C;
TL0 =0xB0;
TF0 =0;
TR0 =1;
while(TF0==0);
TR0=0;

}
 

Hi Vinash

I do have another doudt, I have always tied the EA (Pin 31) to high cos i am reading my program from the internal ROM, when i try to read the data from the SRAM, do i have make EA low? cos i am reading from an external device?

EA means External code memory Access and is tied to ground when you want the microcontroller to perform fetched from external memory.
Access to external data memory is done regardless of EA logic level.

Even though i disable the ADC when i try to use P1 to drive the HP display
No you didn't. It's true that you set /CS of ADC to High level, but you succeed to bring the inputs A of 74LS245 to indeterminate level.
The B outputs are still valid until you set pin 19 ( /G ) to high level.

A more proper wiring is:
pin 1 (DIR) 74LS245 - pin 3 (/WR) ADC0804 (though you'll never write data to ADC, using the /WR pin only to start the conversion)
pin 19(/G) 74LS245 - pin 2 (/RD) ADC0804

74LS245 it's useless if you use the BLANK feature of display (when the pin is High you won't see the data trafic on P1)
But you can get the same result is you use the LE pin (when the pin is High the display preserve the last entry regardless the new input status - read data trafic on P1).
Because you don't use the pin is better tied direct to ground rather than P1.3

I'll check tonight in keil simulator these two statements:

converted=(advalue)*5/256;
P1=a[converted%10];

and I'll let you know the results.
 

    vinash

    Points: 2
    Helpful Answer Positive Rating
HI Silvio,
I have solved the Problem. Thank you so so much, It has to do with my 74LS245. As you had mentioned earlier,I have to disable OE before i use the HP Display.Thank you again....I shall continue with my project......
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top