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.

[SOLVED] Problem in writing 10 bit adc result in successive address of external eeprom 24lc512

Status
Not open for further replies.

Logu KS

Member level 2
Member level 2
Joined
Jul 19, 2014
Messages
43
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
Chennai
Visit site
Activity points
372
I want to know how to write the adc result in successive address of external eeprom 24lc512. I am using pic16f877a controller and storing the result of adc i.e ADDRESH and ADRESL into two variables x and y. I have added my code below.


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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* TEMPERATURE MONITORING DATA LOGGER */
 
/* Header files */
 
#include<pic.h>
#include<lcd4bit.h>
#include<i2c.h>
#include<eephex.h>
 
/* ADC functions */
 
unsigned int address=0;
void adc_init(void);
void adc_channel_select(unsigned char channel);
unsigned int adc_result(void);
unsigned char x,y;
 
unsigned int Read=0,Read1=0,k=0,flag=0;
unsigned int L=0,Temp11,Temp22,Temp33;
 
/* Main function */
 
void main(void)
{   
    TRISB=0XFF;
 
    // Initialize LCD
    initlcd();
 
    // Initialize i2c module
    initi2c();
 
    // Initializ ADC
    adc_init(); 
 
    
    // While loop starts
    while(1)
    {
        // Variables for displaying and reading from eeprom
        unsigned int val=0,i=0,t=0,f=0;
        unsigned int T=0;
        unsigned int Temp1,Temp2,Temp3;
        unsigned int temp1,temp2,temp3;
        unsigned int RxByte=0,RxByte1=0,RxByte2=0;
        unsigned int far1,far2,far3;
    
 
        // ADC channel 1 selected       
        adc_channel_select(1);
        
        // Returned adc value stored in val
        val=adc_result();
    
        // Displaying temperature
        lcdcommand(0x80);
        lcddisplay("Temperature");
 
        // Combining 10 bits and storing it in int from adc
        t=(val*0.48876);
 
        temp1 = (unsigned int)((t/100)%10);     // 1st digit
        temp2 = (unsigned int)((t/10)%10);      // 2nd digit
        temp3 = (unsigned int)((t/1)%10);       // 3rd digit
    
        // Displaying temperature in lcd
        lcdcommand(0xc0);
        if(t<=99)
        {
            lcddata(' ');               // displaying the 1st digit
            lcddata(temp2+0x30);        // displaying the 2nd digit
            lcddata(temp3+0x30);        // displaying the 3rd digit
            lcddata(0xdf);              // for displaying degree symbol 
            lcddata('C');
        }
 
        lcdcommand(0xc0);
        if(t>=100)
        {
            lcddata(temp1+0x30);        // displaying the 1st digit
            lcddata(temp2+0x30);        // displaying the 2nd digit
            lcddata(temp3+0x30);        // displaying the 3rd digit
            lcddata(0xdf);              // for displaying degree symbol 
            lcddata('C');
        }   
    
        // Converting degree to farenheit
        f=((t*9)/5)+32;
 
        far1=(unsigned int) ((f/100)%10);       // 1st digit
        far2=(unsigned int) ((f/10)%10);        // 2nd digit
        far3=(unsigned int) ((f/1)%10);         // 3rd digit
    
        // Displaying farenheit in lcd
        lcdcommand(0xc6);
        if(f<=99)
        {
            lcddata(' ');               // displaying the 1st digit
            lcddata(far2+0x30);     // displaying the 2nd digit
            lcddata(far3+0x30);     // displaying the 3rd digit
            lcddata('F');
        }
        
        if(f>=99)
        {
            lcddata(far1+0x30);     // displaying the 1st digit
            lcddata(far2+0x30);     // displaying the 2nd digit
            lcddata(far3+0x30);     // displaying the 3rd digit
            lcddata('F');
        }
        
        // Writing to eeprom
            
    //  Write_Byte_To_24LC64_EEPROM(address,x);
    //  address=address+1;
    //  Write_Byte_To_24LC64_EEPROM(address,y);
    //  address=address+1;
    address=0x0000;
    for(int i=0;i<1000;i++)
    {
    Write_Byte_To_24LC64_EEPROM(address,x);
    address++;
    Write_Byte_To_24LC64_EEPROM(address,y);     
    address++;
    }       
    
    // Reading from eeprom
        address=0x00;
        RxByte = Read_Byte_From_24LC64_EEPROM(address);
        address++;  
        RxByte1 = Read_Byte_From_24LC64_EEPROM(address);
        address++;
        // Combining 10 bits and storing it in int from eeprom
        i=((RxByte<<8)|RxByte1);
 
        // Converting sample value to temperature
        T=(i*0.48876);
 
        Temp1 = (unsigned int)((T/100)%10);     // 1st digit
        Temp2 = (unsigned int)((T/10)%10);      // 2nd digit
        Temp3 = (unsigned int)((T/1)%10);       // 3rd digit
    
        // Displaying temperature in lcd
        lcdcommand(0x8b);
        if(T<=99)
        {
            lcddata(' ');               // displaying the 1st digit
            lcddata(Temp2+0x30);        // displaying the 2nd digit
            lcddata(Temp3+0x30);        // displaying the 3rd digit
            lcddata(0xdf);              // for displaying degree symbol 
            lcddata('C');
        }
    
        lcdcommand(0x8b);
        if(T>=100)
        {
            lcddata(Temp1+0x30);        // displaying the 1st digit
            lcddata(Temp2+0x30);        // displaying the 2nd digit
            lcddata(Temp3+0x30);        // displaying the 3rd digit
            lcddata(0xdf);              // for displaying degree symbol 
            lcddata('C');
        }
    __delay_ms(100);
    RB0=1;
    if(RB0==1)
        {
        Read=Read_Byte_From_24LC64_EEPROM(0x0000);
        Read1=Read_Byte_From_24LC64_EEPROM(0x0001);
        k=((Read<<8)|Read1);
        L=(k*0.48776);
        Temp11 = (unsigned int)((L/100)%10);        // 1st digit
        Temp22 = (unsigned int)((L/10)%10);     // 2nd digit
        Temp33 = (unsigned int)((L/1)%10);      // 3rd digit
    
        // Displaying temperature in lcd
        lcdcommand(0xcc);
        if(L<=99)
        {
            lcddata(' ');               // displaying the 1st digit
            lcddata(Temp22+0x30);       // displaying the 2nd digit
            lcddata(Temp33+0x30);       // displaying the 3rd digit
            lcddata(0xdf);              // for displaying degree symbol 
            lcddata('C');
        }
    
        lcdcommand(0xCC);
        if(L>=100)
        {
            lcddata(Temp11+0x30);       // displaying the 1st digit
            lcddata(Temp22+0x30);       // displaying the 2nd digit
            lcddata(Temp33+0x30);       // displaying the 3rd digit
            lcddata(0xdf);              // for displaying degree symbol 
            lcddata('C');
        }
    }
 
}
}
 
/* ADC initialization */
 
void adc_init(void)
{
    __delay_ms(20);
    ADCON1=0X80;                        // adc result right justified result
}
 
/* ADC channel selection */
 
void adc_channel_select(unsigned char channel)
{
    __delay_ms(20);
    ADCON0=0Xc1|(channel<<3);           // channel selection
}
 
/* ADC result */
 
unsigned int adc_result(void)       
{
    __delay_us(20);
    ADGO=1;                             // Start conversion
    while(ADGO)                         // wait
    continue;
    x=ADRESH;                           
    y=ADRESL;
    return ((x<<8)|y);                          // returning the 10 bit value 
}

 
Last edited:

when you call adc_result() could you do
Code:
    val=adc_result();
    Write_Byte_To_24LC64_EEPROM(address,val);
    address++;
    Write_Byte_To_24LC64_EEPROM(address,val>>8);     
    address++;
 
Last edited:
First of all i thank both of you for giving your suggestions.
My task is to write the temperature value into eeprom periodically using RTC @Brian

- - - Updated - - -

when you call adc_result() could you do
Code:
    unsigned int x=adc_result();       
    val=adc_result();
    Write_Byte_To_24LC64_EEPROM(address,val);
    address++;
    Write_Byte_To_24LC64_EEPROM(address,val>>8);     
    address++;

As per your suggestion the 10 bit adc result is stored in val. But how the 10 bit val can stored in 8 bit address of eeprom. I couldnt understand the logic and why adc_result i stored in both int x and val.
 

Hello,


Be carrefull with writing to Eeeprom , byte per Byte, because
need a delay of any mS between each writing. ( 10 to 20mS)
If you can manage "Page Mode" you can write 64 bytes without big delay between writing.


Code:
  val=adc_result();
  Write_Byte_To_24LC64_EEPROM(address,(unsiged char)(val & 0x00FF));    // LSB
  address++;
  Write_Byte_To_24LC64_EEPROM(address,(unsigned char)( val>>8));        // MSB
  address++;

I see many times
Variable declaration inside the main code ..
but here , inside an infinite loop..
i think , we are far away from the C langage basis. ( Kernighan et Ritchie ) .
if you change of compiler, you will get problem because using a (bad) or non standard habit.

Maybe the futur is C SMS fashion ...
 
Last edited:

As per your suggestion the 10 bit adc result is stored in val. But how the 10 bit val can stored in 8 bit address of eeprom. I couldnt understand the logic and why adc_result i stored in both int x and val.
no need for x the code should have been
Code:
val=adc_result();
    Write_Byte_To_24LC64_EEPROM(address,val);
    address++;
    Write_Byte_To_24LC64_EEPROM(address,val>>8);     
    address++;
ADC bits 0 to 7 are stored in address and bit 8 and 9 in address+1 (6 bits not used)
you could always compress two 10 bit values into 3 bytes to save space

- - - Updated - - -

Variable declaration inside the main code ..
but here , inside an infinite loop..
i think , we are far away from the C langage basis. ( Kernighan et Ritchie ) .
if you change of compiler, you will get problem because using a (bad) or non standard habit.

Maybe the futur is C SMS fashion ...
in C variable declarations may be placed at the start of a compound statement
https://msdn.microsoft.com/en-us/library/ce4b8s02.aspx
C++ is more flexible alowing declarations anywhere in the program
 

i wrote into eeprom as told by you

Code:
val=adc_result();
Write_Byte_To_24LC64_EEPROM(address,val);
address++;
Write_Byte_To_24LC64_EEPROM(address,val>>8);
address++;

but while reading it is showing some junk values

Code:RxByte = Read_Byte_From_24LC64_EEPROM(address);
address++;
RxByte1 = Read_Byte_From_24LC64_EEPROM(address);
address++;
// Combining 10 bits and storing it in int from eeprom
i=((RxByte<<8)|RxByte1);

// Converting sample value to temperature
T=(i*0.48876);

Temp1 = (unsigned int)((T/100)%10); // 1st digit
Temp2 = (unsigned int)((T/10)%10); // 2nd digit
Temp3 = (unsigned int)((T/1)%10); // 3rd digit

// Displaying temperature in lcd
lcdcommand(0x8b);
if(T<=99)
{
lcddata(' '); // displaying the 1st digit
lcddata(Temp2+0x30); // displaying the 2nd digit
lcddata(Temp3+0x30); // displaying the 3rd digit
lcddata(0xdf); // for displaying degree symbol
lcddata('C');
}
 

should combining the 10 bits be
Code:
// Combining 10 bits and storing it in int from eeprom
i=((RxByte1<<8)|RxByte);
 

Before going further, check you really are storing data in the memory and you really are retrieving it again.

Try hard coding some values, for example:
Write_Byte_To_24LC64_EEPROM(0,0x55);
Write_Byte_To_24LC64_EEPROM(1,0xAA);

Then read them back to confirm the write routine works properly. If you get the same values back, try the routine to convert them to a 16-bit int and check you get a value of 0xAA55.

The methods suggested to you are the ones usually used, simply store the upper and lower 8 bit values (as they already are when you read ADRESH and ADRESL) in different addresses and combine them to recreate the 10 bit result after you have read them back from memory.

Brian.
 

I tried that also but same problem occurs
Code:
void main(void)
{	
	TRISB=0XFF;

	// Initialize LCD
	initlcd();

	// Initialize i2c module
	initi2c();

	// Initializ ADC
	adc_init();	

	
	// While loop starts
	while(1)
	{
		
		// ADC channel 1 selected		
		adc_channel_select(1);
		
		// Returned adc value stored in val
   		val=adc_result();
//		val=adc_result();
  	  	Write_Byte_To_24LC64_EEPROM(address,val);
    	address++;
    	Write_Byte_To_24LC64_EEPROM(address,val>>8);     
    	address++;

// Reading from eeprom
	//	address=0x0000;
		RxByte = Read_Byte_From_24LC64_EEPROM(address);
		address++;	
		RxByte1 = Read_Byte_From_24LC64_EEPROM(address);
		address++;
		// Combining 10 bits and storing it in int from eeprom
		i=((RxByte1<<8)|RxByte);

		// Converting sample value to temperature
		T=(i*0.48876);

		Temp1 = (unsigned int)((T/100)%10);		// 1st digit
		Temp2 = (unsigned int)((T/10)%10);		// 2nd digit
		Temp3 = (unsigned int)((T/1)%10);		// 3rd digit
	
		// Displaying temperature in lcd
		lcdcommand(0x8b);
		if(T<=99)
		{
		    lcddata(' ');				// displaying the 1st digit
			lcddata(Temp2+0x30);		// displaying the 2nd digit
			lcddata(Temp3+0x30);		// displaying the 3rd digit
			lcddata(0xdf);				// for displaying degree symbol	
			lcddata('C');
		}
	
		lcdcommand(0x8b);
		if(T>=100)
		{
			lcddata(Temp1+0x30);		// displaying the 1st digit
			lcddata(Temp2+0x30);		// displaying the 2nd digit
			lcddata(Temp3+0x30);		// displaying the 3rd digit
			lcddata(0xdf);				// for displaying degree symbol	
			lcddata('C');
		}

	__delay_ms(100);


}
}

/* ADC initialization */

void adc_init(void)
{
	__delay_ms(20);
	ADCON1=0X80;						// adc result right justified result
}

/* ADC channel selection */

void adc_channel_select(unsigned char channel)
{
	__delay_ms(20);
	ADCON0=0Xc1|(channel<<3);			// channel selection
}

/* ADC result */

unsigned int adc_result(void)		
{
	__delay_us(20);
	ADGO=1;								// Start conversion
	while(ADGO)							// wait
	continue;
	x=ADRESH;							
	y=ADRESL;
	return ((x<<8)|y);							// returning the 10 bit value 
}

- - - Updated - - -

when writing and reading like this output comes. so the read and write routines works
Code:
Write_Byte_To_24LC64_EEPROM(0X0000,x);
		Write_Byte_To_24LC64_EEPROM(0X0001,y);
		
		RxByte = Read_Byte_From_24LC64_EEPROM(0x0000);
		RxByte1 = Read_Byte_From_24LC64_EEPROM(0x0001);
 

when you read the data back what do you get? 0's, random rubbish, 0xFF ?
as betwixt says do some tests on the EEPROM code to make sure it is working
write known data to the EEPROM (e.g. 0, 0x55, 0xAA, 0xFF) and read check it
 

i checked it if i write any character in address 0 and read it back the character gets displayed in lcd
 

i checked it if i write any character in address 0 and read it back the character gets displayed in lcd
have you tried writing/reading other addresses?
this is a test I do on a MCP79410
Code:
    unsigned char  Seconds,Minutes,Hours,Date,Month,Year, test55[10],test[20]={0};
	// check SRAM
       printf("\r\nMCP79410 test: \n\r");
    	 MCP79410writeTime(23, 56, 0, 4, 3, 11);     // initialise time
    	MCP79410readTime(&Hours,&Minutes,&Seconds,&Date,&Month,&Year, 1);
       // some simple writes and reads
       unsigned char FArray[]="1234567890ABCDEF";
       MCP79410writeEEPROMbyte(0, FArray, strlen((char *)FArray)+1);
       mSecDelay(500);	
       MCP79410readEEPROMbyte(0, test, 20);
       printf("Write '%s'  Read '%s' \n", FArray, test);
		MCP79410readEEPROMbyte(10, test, 20);
		printf("Read from address 10 '%s' \n", test);
		MCP79410writeEEPROMbyte(10, "XYZ", 4);
		MCP79410readEEPROMbyte(0, test, 20);
		printf("Write to address 10 XYZ  Read from 0  '%s' \n", test);
gives
Code:
DMU dsPIC33EP256MU806 borad test Fcy 60000000
MCP79410 test:
MCP79410 write time 23:56:00 04/03/11 -  read check time 23:56:00 04/03/11
MCP79410 time 23:56:00 04/03/11
Write '1234567890ABCDEF'  Read '1234567890ABCDEF'
Read from address 10 'ABCDEF'
Write to address 10 XYZ  Read from 0  '1234567890XYZ'
 

You originally said you were using a 24LC512 but your routine names suggest you are using a 24LC64, check the read/write routines are compatible and note the addressing range allowed.

i checked it if i write any character in address 0 and read it back the character gets displayed in lcd

Do the same for address 1. Although it seems unlikely to be the problem, you might have an obscure bug that only lets it work with alternate addresses (eg. in EPROMs that are selectable 8/16 bits) and your ADC calculation relies on all addresses working. I suggest writing data to both addresses and then checking they both read back OK.

Brian.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top