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.

[51] adc0804 & 0808 readings going 0 after half the total voltage read through i/p channel

Status
Not open for further replies.

ravi_karthik

Newbie level 3
Joined
Apr 7, 2014
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
114
adc0804 & 0808 readings going 0 after half the total voltage read through i/p channel

Can someone explain why this strange behaviour is seen while interfacing adc0808 or adc0804 with at89s52 microcontroller.

Iam trying to read 5v connected to channel 0 of adc0808 , hence it should give 255 when i read 5v and 0 when i read 0v.
But strangely it gives the correct readings upto 127 that is 2.5 v but after that it goes down to 000 then 001 and then again some readings in between
are correct upto 255 that is 5v.

Same strange behaviour is seen when adc0804 is interfaced with at89s52.

In proteus simulation the the code below(adc0804) and the attached adc0808 works but in hardware the above behaviour is reflected.Reference schematics are provided .Please let me know if any one need any further details regarding the same.

Vref in adc0808 is connected to 4.95v and vcc is 4.95v ...

in adc0804 vref/2 is left unconnected.



Code:
//ADC0804 CODE

#include<at89x52.h>		//----Including the Reg file

//------------Assigning Control bits for LCD control---------/
sbit rs = P3^0;	//----Pin0 of port3 is defined as rs pin for lcd control using this command—
sbit rw = P3^1;//----Pin1 of port3 is defined as rw pin for lcd control using this command-lcd control using this command---
sbit en = P3^2;//----Pin2 of port3 is defined as en pin for 

sbit cs = P2^5;
sbit rd = P2^6; //----Read function for enabling ADC read----//
sbit wr = P2^7;//----Write Function for writing into ADC----//
sbit intr = P2^0;//----Interrupt Function which indicates the End of Conversion----//
//----------------------------------------------------------//

//------------Proto-type Decleration-----------------//
void init_lcd();		//-----Function used for Initializing LCD ------
void lcd_comm(unsigned char value1); //------Function used to send command using pass by reference type-----
void lcd_data(unsigned char value2);	//------Function used to send data using pass by reference type-----
void lcd_msg(unsigned char *ch); //----Sending a String uisng pass by pointer method------
void delay(unsigned int ms);	//------Function use to generate 1ms delay-------
					
//-----Defining the ADC Function-----//
void adc_init();									
//-----Inializing  adc -----//
void adc_read();										
//----Reading Data from ADC---//
void Converter(unsigned char v4);//----Converter data to ascii for display in LCD---//
//---------------------------------------------------//
					
unsigned char ascii_lut[] = "0123456789ABCDEF";

//-------------Main Program-------------------------//
void main()
{
/					
	init_lcd();			//-----Initializing LCD 
	adc_init();			//-----ADC initialize
	lcd_comm(0x80);	//-----1st line of LCD
	lcd_msg("VOLTAGE = ");//----Send a String 	
	while(1)
  {
	       adc_read();	//-- ADC data is send to mu and displayed in LCD
	}
}
					
					
void adc_init()
{
	cs = 0;
	wr = 1;				//------Initialize the write signal as high 
	rd = 1;				//------Initialize the read signal as high
	intr = 1;			//------Interrupt Pin to show end the Conversion
}
					
void adc_read()
{
  unsigned char v;
	cs = 0;
	wr = 0;		//----When Write Signal goes high to low to high 
	wr = 1;		//----It state End of Conversion
	while(intr == 1); //----Wait till end of conversion
	rd = 0;		//---Read is enable to read data from it
	v = P0;		//----Move data of ADC to variable v
	Converter(v);
	intr = 0; //---Clearinng for next state
}
				
void Converter(unsigned char v4)
{
 //---Converter to analog input voltage
	float g,h;
	unsigned int d,t;
	g = ((v4 * 5)/255);	//--Analog input voltage is float type---/				
	d = g;			//--Move float into interger will eliminate the decimal point---// 
	h = g - d;		//--Now calculate the difference between float and interger
	t = h * 100;		//--Now Removing the decimal point//
	lcd_comm(0x89);	//---Forcing to the Centre
	lcd_data(d|(0x30));
	lcd_data('.');
	lcd_data(((t/10)%10)|(0x30));
	lcd_data(((t)%10)|(0x30));
	lcd_data('V');
						
//---Converting ADC data to Decimal
					
	lcd_comm(0xC0);
	lcd_msg("D=");
	lcd_data(((v4/100)%10)|(0x30));
	lcd_data(((v4/10)%10)|(0x30));
	lcd_data(((v4)%10)|(0x30));

//----Converting the data to hexa

	lcd_comm(0xC7);
	lcd_msg("H=");
	lcd_data(ascii_lut[((v4 & 0xF0)>>4)]);
	lcd_data(ascii_lut[((v4 & 0x0F))]);
}
					
void init_lcd()
{
	lcd_comm(0x38);		//----Initializing 16x2 line LCD dispaly 
	delay(10) ;				//-----10ms delay
	lcd_comm(0x0E);		//----Setting Display ON and Cursor as Blinking		
	delay(10);				//-----10ms delay
	lcd_comm(0x01);		//-----Clearing the LCD display
	delay(10);				//-----10ms delay
	lcd_comm(0x06);		//-----Auto incrementing Cursor
	delay(10);				//-----10ms delay
	lcd_comm(0x80);		//-----Setting first location on first line of LCD 
	delay(10);				//-----10ms delay
}

					
void lcd_comm(unsigned char value1)
{
	P1 = value1;	//----Sending the command to lcd from Port0 
	rs = 0;	//----RS = Register Select pin, when [rs = 0] means its Command register
	rw = 0;	//----RW = Read / Write pin, when [rw = 0] means write function
//----EN = Enable pin, it is use to latch data to lcd when it has high to low pulse at en pin		
	en = 1;					
	delay(1);	//----1ms delay
	en = 0;
}
					
void lcd_data(unsigned char value2)
{
	P1 = value2;//----Sending the command to lcd from Port0 
	rs = 1;	//----RS = Register Select pin, when [rs = 1] means its Data register
	rw = 0;	//----RW = Read / Write pin, when [rw = 0] means write function
//----EN = Enable pin, it is use to latch data to lcd when it has high to low pulse at en pin
	en = 1;						
	delay(1);	//----1ms delay
	en = 0;
}
					
void lcd_msg(unsigned char *ch)
{
while(*ch != 0)//----Creating super loop with condition that pointer ch pointing data using address is not equal to zero
{
	lcd_data(*ch);	//-----Sending String by pointing addresss of data
	ch++;		//-----Incrementing the ch pointer variable
	}
}
					
void delay(unsigned int ms)
{
	unsigned int i,j;
	for(i=0;i<=ms;i++)	//-----Nop operation till the loop execution complete 
	for(j=0;j<=120;j++);	//-----Nop operation till the loop execution complete
}
 

Attachments

  • adc0804_schematic.png
    adc0804_schematic.png
    201.6 KB · Views: 113
  • adc0808_schematic.png
    adc0808_schematic.png
    225.8 KB · Views: 116
  • adc_0808_code.rar
    44 KB · Views: 97

Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

didn't you forget to make P0 as input?

your code

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//ADC0804 CODE
 
#include<at89x52.h>     //----Including the Reg file
 
//------------Assigning Control bits for LCD control---------/
sbit rs = P3^0; //----Pin0 of port3 is defined as rs pin for lcd control using this command—
sbit rw = P3^1;//----Pin1 of port3 is defined as rw pin for lcd control using this command-lcd control using this command---
sbit en = P3^2;//----Pin2 of port3 is defined as en pin for 
 
sbit cs = P2^5;
sbit rd = P2^6; //----Read function for enabling ADC read----//
sbit wr = P2^7;//----Write Function for writing into ADC----//
sbit intr = P2^0;//----Interrupt Function which indicates the End of Conversion----//
//----------------------------------------------------------//
 
//------------Proto-type Decleration-----------------//
void init_lcd();        //-----Function used for Initializing LCD ------
void lcd_comm(unsigned char value1); //------Function used to send command using pass by reference type-----
void lcd_data(unsigned char value2);    //------Function used to send data using pass by reference type-----
void lcd_msg(unsigned char *ch); //----Sending a String uisng pass by pointer method------
void delay(unsigned int ms);    //------Function use to generate 1ms delay-------
                    
//-----Defining the ADC Function-----//
void adc_init();                                    
//-----Inializing  adc -----//
void adc_read();                                        
//----Reading Data from ADC---//
void Converter(unsigned char v4);//----Converter data to ascii for display in LCD---//
//---------------------------------------------------//
                    
unsigned char ascii_lut[] = "0123456789ABCDEF";
 
//-------------Main Program-------------------------//
void main()
{
/                   
    init_lcd();         //-----Initializing LCD 
    adc_init();         //-----ADC initialize
    lcd_comm(0x80); //-----1st line of LCD
    lcd_msg("VOLTAGE = ");//----Send a String   
    while(1)
  {
           adc_read();  //-- ADC data is send to mu and displayed in LCD
    }
}
                    
                    
void adc_init()
{
    cs = 0;
    wr = 1;             //------Initialize the write signal as high 
    rd = 1;             //------Initialize the read signal as high
    intr = 1;           //------Interrupt Pin to show end the Conversion
}
                    
void adc_read()
{
  unsigned char v;
    cs = 0;
    wr = 0;     //----When Write Signal goes high to low to high 
    wr = 1;     //----It state End of Conversion
    while(intr == 1); //----Wait till end of conversion
    rd = 0;     //---Read is enable to read data from it
    v = P0;     //----Move data of ADC to variable v
    Converter(v);
    intr = 0; //---Clearinng for next state
}
                
void Converter(unsigned char v4)
{
 //---Converter to analog input voltage
    float g,h;
    unsigned int d,t;
    g = ((v4 * 5)/255); //--Analog input voltage is float type---/              
    d = g;          //--Move float into interger will eliminate the decimal point---// 
    h = g - d;      //--Now calculate the difference between float and interger
    t = h * 100;        //--Now Removing the decimal point//
    lcd_comm(0x89); //---Forcing to the Centre
    lcd_data(d|(0x30));
    lcd_data('.');
    lcd_data(((t/10)%10)|(0x30));
    lcd_data(((t)%10)|(0x30));
    lcd_data('V');
                        
//---Converting ADC data to Decimal
                    
    lcd_comm(0xC0);
    lcd_msg("D=");
    lcd_data(((v4/100)%10)|(0x30));
    lcd_data(((v4/10)%10)|(0x30));
    lcd_data(((v4)%10)|(0x30));
 
//----Converting the data to hexa
 
    lcd_comm(0xC7);
    lcd_msg("H=");
    lcd_data(ascii_lut[((v4 & 0xF0)>>4)]);
    lcd_data(ascii_lut[((v4 & 0x0F))]);
}
                    
void init_lcd()
{
    lcd_comm(0x38);     //----Initializing 16x2 line LCD dispaly 
    delay(10) ;             //-----10ms delay
    lcd_comm(0x0E);     //----Setting Display ON and Cursor as Blinking     
    delay(10);              //-----10ms delay
    lcd_comm(0x01);     //-----Clearing the LCD display
    delay(10);              //-----10ms delay
    lcd_comm(0x06);     //-----Auto incrementing Cursor
    delay(10);              //-----10ms delay
    lcd_comm(0x80);     //-----Setting first location on first line of LCD 
    delay(10);              //-----10ms delay
}
 
                    
void lcd_comm(unsigned char value1)
{
    P1 = value1;    //----Sending the command to lcd from Port0 
    rs = 0; //----RS = Register Select pin, when [rs = 0] means its Command register
    rw = 0; //----RW = Read / Write pin, when [rw = 0] means write function
//----EN = Enable pin, it is use to latch data to lcd when it has high to low pulse at en pin       
    en = 1;                 
    delay(1);   //----1ms delay
    en = 0;
}
                    
void lcd_data(unsigned char value2)
{
    P1 = value2;//----Sending the command to lcd from Port0 
    rs = 1; //----RS = Register Select pin, when [rs = 1] means its Data register
    rw = 0; //----RW = Read / Write pin, when [rw = 0] means write function
//----EN = Enable pin, it is use to latch data to lcd when it has high to low pulse at en pin
    en = 1;                     
    delay(1);   //----1ms delay
    en = 0;
}
                    
void lcd_msg(unsigned char *ch)
{
while(*ch != 0)//----Creating super loop with condition that pointer ch pointing data using address is not equal to zero
{
    lcd_data(*ch);  //-----Sending String by pointing addresss of data
    ch++;       //-----Incrementing the ch pointer variable
    }
}
                    
void delay(unsigned int ms)
{
    unsigned int i,j;
    for(i=0;i<=ms;i++)  //-----Nop operation till the loop execution complete 
    for(j=0;j<=120;j++);    //-----Nop operation till the loop execution complete
}

 
Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

VREF/2 have to be provided 2.5V for ADC0804. Also there is a bug in ADC0804 part (in Proteus 7.10, don't know about Proteus 8). The ADC0804 outputs are inverted that is. D0-D7 is like D7-D0. So, D7 is LSB and D0 is MSB. Sometime back romel_emperado had the same problem. Search for ADC0804 8051 in romels's posts.
 

Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

In proteus simulation the the code below(adc0804) and the attached adc0808 works but in hardware the above behaviour is reflected.

He is not experiencing the problem with Proteus.
 

Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

@papunblg

Ok.

@ravi_karthik


You should not make intr high in adc_init(); If intr = 1 in adc_init() is to make intr pin as input then it is correct. As mentioned by papunblg P0 has to be made input port and it as to be pulled-up.

You should not clear intr pin (P2.0) and it is not valid because intr pin is input type. It goes high during adc conversion as INTR pin of ADC0804 goes high. You have to read data only after P2.0 goes low.
 
Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

@milan.rajak

Yes , in adc_init() the intr pin has been made input(intr = 1).
I agree that the data has to be read once the INTR pin goes low hence i have removed the INTR pin forceful pull-down(INTR = 0) in the code.

@papunblg
As indicated by papunblg i have pulled-up port0 .

Modified the code as per changes advised but still the same problem persists i.e after half the voltage at input channel voltage goes down to zero and again it starts counting upto 255 i.e 5v.


Code:
#include<at89x52.h>		//----Including the Reg file

//------------Assigning Control bits for LCD control---------/
sbit rs = P3^3;	//----Pin3 of port3 is defined as rs pin for lcd control using this command—
sbit rw = P3^0;//----Pin0 of port3 is defined as rw pin for lcd control using this command-
sbit en = P3^1;//----Pin1 of port3 is defined as en pin for lcd control using this command---

sbit cs = P2^5; //----Chip select function for ADC----//
sbit rd = P2^6; //----Read function for enabling ADC read----//
sbit wr = P2^7;//----Write Function for writing into ADC----//
sbit intr = P2^0;//----Interrupt Function which indicates the End of Conversion----//
//----------------------------------------------------------//

//------------Proto-type Decleration-----------------//
void init_lcd();		//-----Function used for Initializing LCD ------
void lcd_comm(unsigned char value1); //------Function used to send command using pass by reference type-----
void lcd_data(unsigned char value2);	//------Function used to send data using pass by reference type-----
void lcd_msg(unsigned char *ch); //----Sending a String uisng pass by pointer method------
void delay(unsigned int ms);	//------Function use to generate 1ms delay-------
					
//-----Defining the ADC Function-----//
void adc_init();									
//-----Inializing  adc -----//
void adc_read();										
//----Reading Data from ADC---//
void Converter(unsigned char v4);//----Converter data to ascii for display in LCD---//
//---------------------------------------------------//
					
unsigned char ascii_lut[] = "0123456789ABCDEF";

//-------------Main Program-------------------------//
void main()
{
 	  P0 = 0xFF;			//-----Input port used to read data from ADC---//
 	  P1 = 0x00;			//-----Defining the Port 1 as output----//	
	init_lcd();			//-----Initializing LCD 
	adc_init();			//-----ADC initialize
	lcd_comm(0x80);	//-----1st line of LCD
	lcd_msg("VOLTAGE = ");//----Send a String 	
	while(1)
  {
	       adc_read();	//-- ADC data is send to mu and displayed in LCD
	}
}
					
					
void adc_init()
{
	cs = 0;
	wr = 1;				//------Initialize the write signal as high 
	rd = 1;				//------Initialize the read signal as high
	intr = 1;			//------Interrupt Pin to show end the Conversion
}
					
void adc_read()
{
  unsigned char v;
	cs = 0;
	wr = 0;		//----When Write Signal goes high to low to high 
	wr = 1;		//----It starts End of Conversion
	while(intr == 1); //----Wait till end of conversion
	v = P0;		//----Move data of ADC to variable v
	Converter(v);
	rd = 0;		//---Read is enable to read data from it

}
				
void Converter(unsigned char v4)
{
 //---Converter to analog input voltage
	float g,h;
	unsigned int d,t;
	g = ((v4 * 5)/255);	//--Analog input voltage is float type---/				
	d = g;			//--Move float into interger will eliminate the decimal point---// 
	h = g - d;		//--Now calculate the difference between float and interger
	t = h * 100;		//--Now Removing the decimal point//
	lcd_comm(0x89);	//---Forcing to the Centre
	lcd_data(d|(0x30));
	lcd_data('.');
	lcd_data(((t/10)%10)|(0x30));
	lcd_data(((t)%10)|(0x30));
	lcd_data('V');
						
//---Converting ADC data to Decimal
					
	lcd_comm(0xC0);
	lcd_msg("D=");
	lcd_data(((v4/100)%10)|(0x30));
	lcd_data(((v4/10)%10)|(0x30));
	lcd_data(((v4)%10)|(0x30));

//----Converting the data to hexa

	lcd_comm(0xC7);
	lcd_msg("H=");
	lcd_data(ascii_lut[((v4 & 0xF0)>>4)]);
	lcd_data(ascii_lut[((v4 & 0x0F))]);
}
					
void init_lcd()
{
	lcd_comm(0x38);		//----Initializing 16x2 line LCD dispaly 
	delay(10) ;				//-----10ms delay
	lcd_comm(0x0E);		//----Setting Display ON and Cursor as Blinking		
	delay(10);				//-----10ms delay
	lcd_comm(0x01);		//-----Clearing the LCD display
	delay(10);				//-----10ms delay
	lcd_comm(0x06);		//-----Auto incrementing Cursor
	delay(10);				//-----10ms delay
	lcd_comm(0x80);		//-----Setting first location on first line of LCD 
	delay(10);				//-----10ms delay
}

					
void lcd_comm(unsigned char value1)
{
	P1 = value1;	//----Sending the command to lcd from Port0 
	rs = 0;	//----RS = Register Select pin, when [rs = 0] means its Command register
	rw = 0;	//----RW = Read / Write pin, when [rw = 0] means write function		
	en = 1; //----EN = Enable pin, it is use to latch data to lcd when it has high to low pulse at en pin					
	delay(1);	//----1ms delay
	en = 0;
}
					
void lcd_data(unsigned char value2)
{
	P1 = value2;//----Sending the command to lcd from Port0 
	rs = 1;	//----RS = Register Select pin, when [rs = 1] means its Data register
	rw = 0;	//----RW = Read / Write pin, when [rw = 0] means write function
	en = 1;	//----EN = Enable pin, it is use to latch data to lcd when it has high to low pulse at en pin					
	delay(1);	//----1ms delay
	en = 0;
}
					
void lcd_msg(unsigned char *ch)
{
while(*ch != 0)//----Creating super loop with condition that pointer ch pointing data using address is not equal to zero
{
	lcd_data(*ch);	//-----Sending String by pointing addresss of data
	ch++;		//-----Incrementing the ch pointer variable
	}
}
					
void delay(unsigned int ms)
{
	unsigned int i,j;
	for(i=0;i<=ms;i++)	//-----Nop operation till the loop execution complete 
	for(j=0;j<=120;j++);	//-----Nop operation till the loop execution complete
}
 

Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

Is your question for 0804 or 0808 or both?


Code C - [expand]
1
2
P2 = 0x01;
P3 = 0x00;



remove intr = 1; from adc_init().
 
Last edited:
Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

The question is targetted more towards 0804 but the behaviour is same for both (ADC0804 and 0808).
 

Re: adc0804 & 0808 readings going 0 after half the total voltage read through i/p cha

Try this code. If it works in hardware then try changing the ADC port to P0 and see if it works as expected.
 

Attachments

  • Keil uVision 4.rar
    71.2 KB · Views: 104
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top