Reading a big number inside a 8 bits EEPROM

General discussion on mikroC.
Post Reply
Author
Message
Bigote
Posts: 67
Joined: 09 Aug 2009 12:51
Location: Willemstad

Reading a big number inside a 8 bits EEPROM

#1 Post by Bigote » 04 Feb 2010 00:53

Hi fellow programmers

Like i said before i am trying to read a stored big number inside an 24c02 EEPROM. The original number is 213077. I cannot save this number inside 1 byte register that's why i used 2 registers. I stored 213 inside the first one and 77 inside the other one. I did exactly the same with the number 236318. For this number i had to use 3 registers.

Below here you can see my code:


/*
* Project name:
EEPROM_Read
* Copyright:
(c) Mikroelektronika, 2006.
* Description:
This program demonstrates usage of the I2C library routines in mikroC. It
establishes I2C bus communication with 24C08A EEPROM chip, reads 10 bytes
from addresses 0 to 9 and sends them to LCD
* Test configuration:
MCU: PIC16F877A
Dev.Board: EasyPIC3
Oscillator: HS, 08.0000MHz
Ext. Modules: EEPROM (24C08A) on PORTC
SW: mikroC v6.0
* NOTES:
*/

unsigned int i;
unsigned int meli[5];
unsigned short spanning_1=213; // Positie 1
unsigned short spanning_2=77; // Positie 2
unsigned short stroom_1=236; // Positie 3
unsigned short stroom_2=31; // Positie 4
unsigned short stroom_3=8; // Positie 5


long spanning_lsb;
long stroom_lsb;


char Row1[16];
char Row2[16];


void Write_to_EEPROM()
{
Soft_I2C_Start(); // issue I2C start signal
Soft_I2C_Write(0xA2); // send byte via I2C (command to 24CO2)

Soft_I2C_Write(1); // First Adress (Adres 1)

Soft_I2C_Write(spanning_1);
Soft_I2C_Write(spanning_2);
Soft_I2C_Write(stroom_1);
Soft_I2C_Write(stroom_2);
Soft_I2C_Write(stroom_3);

Soft_I2C_Stop();
}

void Read_from_EEPROM_to_LCD()
{

Soft_I2C_Start(); // issue I2C start signal
Soft_I2C_Write(0xA2); // send byte via I2C (device address + W)
Soft_I2C_Write(1); // first word address
Soft_I2C_Start(); // issue I2C signal repeated start
Soft_I2C_Write(0xA3); // send byte (device address + R)

for (i=0;i<=4;i++)
{
meli=Soft_I2C_Read(1); // Read the data (with acknowledge)
Delay_ms(1000);
}

meli[5]=Soft_I2C_Read(0); // Dummy byte
Soft_I2C_Stop();

spanning_lsb=(meli[0]*1000) + meli[1];
stroom_lsb=(meli[2]*1000) + (meli[3]*100) + meli[4];

Row1[0]='V';
Row1[1]='=';
Row1[2]=48+(spanning_lsb/1000000); // 1 cijfer
Row1[3]=48+((spanning_lsb/100000)%10); // 2 cijfer
Row1[4]=48+((spanning_lsb/10000)%10); // 3 cijfer
Row1[5]=48+((spanning_lsb/1000)%10); // 4 cijfer
Row1[6]=48+((spanning_lsb/100)%10); // 5 cijfer
Row1[7]=48+((spanning_lsb/10)%10); // 6 cijfer
Row1[8]=48+(spanning_lsb%10); // 7 cijfer
Row1[9]=32;
Row1[10]=32;
Row1[11]=32;
Row1[12]=32;
Row1[13]=32;
Row1[14]=32;
Row1[15]=32;

Row2[0]='I';
Row2[1]='=';
Row2[2]=48+(stroom_lsb/1000000); // 1 cijfer
Row2[3]=48+((stroom_lsb/100000)%10); // 2 cijfer
Row2[4]=48+((stroom_lsb/10000)%10); // 3 cijfer
Row2[5]=48+((stroom_lsb/1000)%10); // 4 cijfer
Row2[6]=48+((stroom_lsb/100)%10); // 5 cijfer
Row2[7]=48+((stroom_lsb/10)%10); // 6 cijfer
Row2[8]=48+(stroom_lsb%10); // 7 cijfer
Row2[9]=32;
Row2[10]=32;
Row2[11]=32;
Row2[12]=32;
Row2[13]=32;
Row2[14]=32;
Row2[15]=32;
Row2[16]=32;

}

void Display()
{
LCD_Out(1,1,Row1);
LCD_Out(2,1,Row2);
Delay_ms(750);
}

void main()
{
ADCON1 = 0x0F; // Configure AN pins as digital
Lcd_init(&PORTD);
Soft_I2C_Config(&PORTB, 4, 3);
//Write_to_EEPROM();
Delay_ms(50);
Read_from_EEPROM_to_LCD();

while(1)
{
Display();
}

}



When i was writing this code i made sure that the writing and reading from the EEPROM was working good. I try this by sending the variable that has the numbers meli[] via USART which where received ok.

I think that the problem's lies with the lines where i am trying to put 213 and 77 together to form 213077. It's like the array doesn't allow me to manipulate the numbers. What's the problem?Should i use pointers? But i don't know how to use them.

Any help will be appreciated.

Bigote
Posts: 67
Joined: 09 Aug 2009 12:51
Location: Willemstad

#2 Post by Bigote » 04 Feb 2010 00:56

By the way i am seeing numbers on my LCD but they are not correct i get:

V=0016469
I=0042500

drdoug
Posts: 1074
Joined: 16 Aug 2007 03:49
Location: St. Louis, MO

#3 Post by drdoug » 04 Feb 2010 02:02

Using the handy dandy Quick converter, I was able to determine that 213077 and 236318 are 24 bit numbers (for storage purposes). This means you should use three 8-bit blocks to store the data in eeprom.
Untested, uncompiled.

Code: Select all

#include "built_in.h"   // This lets us use lo(), hi(), higher()

char txt[12];
unsigned short myShort;
long myVar1 = 213077;
long myVar2 = 236318;

void Write_to_EEPROM()
{
Soft_I2C_Start(); // issue I2C start signal
Soft_I2C_Write(0xA2); // send byte via I2C (command to 24CO2)

Soft_I2C_Write(1); // First Adress (Adres 1)

Soft_I2C_Write(Lo(myVar1));   // write the lowest 8 bits of myVar1
Delay_ms(20);
Soft_I2C_Write(Hi(myVar1));   // write bits 9-16 of myVar1
Delay_ms(20);
Soft_I2C_Write(Higher(myVar1));  // write bits 17-24 of myVar1
Delay_ms(20);
Soft_I2C_Write(Lo(myVar2);
Delay_ms(20);
Soft_I2C_Write(Hi(myVar2));
Delay_ms(20);
Soft_I2C_Write(Higher(myVar2));
Delay_ms(20);

Soft_I2C_Stop();
} 

void Read_from_EEPROM_to_LCD()
{

myVar1 = 0;  // Initialize the variables to keep us honest
myVar2 = 0;

Soft_I2C_Start(); // issue I2C start signal
Soft_I2C_Write(0xA2); // send byte via I2C (device address + W)
Soft_I2C_Write(1); // first word address
Soft_I2C_Start(); // issue I2C signal repeated start
Soft_I2C_Write(0xA3); // send byte (device address + R)

Lo(myVar1) = Soft_I2C_Read(1);
Delay_ms(20);
Hi(myVar1) = Soft_I2C_Read(1);
Delay_ms(20);
Higher(myVar1) = Soft_I2C_Read(1);
Delay_ms(20);
Lo(myVar2) = Soft_I2C_Read(1);
Delay_ms(20);
Hi(myVar2) = Soft_I2C_Read(1);
Delay_ms(20);
Higher(myVar2) = Soft_I2C_Read(1);
Delay_ms(20);

LongToStr(myVar1,txt);
LCD_Out(1,1,"V=");
LCD_Out_CP(txt);

LongToStr(myVar2,txt);
LCD_Out(2,1,"I=");
LCD_Out_CP(txt);

}


//The lines below are unchanged

void main()
{
ADCON1 = 0x0F; // Configure AN pins as digital
Lcd_init(&PORTD);
Soft_I2C_Config(&PORTB, 4, 3);
//Write_to_EEPROM();
Delay_ms(50);
Read_from_EEPROM_to_LCD();

while(1)
{
Display();
}

}
How cool is that? We didn't even have to do any math. I have to believe that this also saves you a lot of PIC program memory.
I think there was likely a problem with the way you were setting up the storage of the variables. Even though I used one more memory space in eeprom, it is a much more efficient way of storing the data and we don't have to worry if the your variables change (unless they become larger than 24 bits).

I also suspect you need to put a small delay between successive eeprom writes but I'll have to check the datasheet for that.

You can fine tune the LCD formatting to fit your needs. Hopefully the idea helps.

Bigote
Posts: 67
Joined: 09 Aug 2009 12:51
Location: Willemstad

#4 Post by Bigote » 04 Feb 2010 04:20

Hi drDoug

First of all thanks for the quick answer. The modifications were nearly good (i just compile it i didn't test it). You miss a ")" by the line " Soft_I2C_Write(Lo(myVar2); ". Besides this i had a method called Display which i was using to display the numbers. It was still there being called in the main but the method was deleted. I use it to display the values that where converted to string.

About the way of writing and reading of the data to the EEPROM is a very clever and usefull way of doing it. I knew about the hi and low method but i didn't know how to use it. Know i do.

One more thing. I have more data to wright. I know that the 24C02 consist of 8 bytes per page. Does this mean that i will have to start to write/read at address 8 to get to page 2?

Here is the modified code that compiles:

/*
* Project name:
EEPROM_Read
* Copyright:
(c) Mikroelektronika, 2006.
* Description:
This program demonstrates usage of the I2C library routines in mikroC. It
establishes I2C bus communication with 24C08A EEPROM chip, reads 10 bytes
from addresses 0 to 9 and sends them to LCD
* Test configuration:
MCU: PIC16F877A
Dev.Board: EasyPIC3
Oscillator: HS, 08.0000MHz
Ext. Modules: EEPROM (24C08A) on PORTC
SW: mikroC v6.0
* NOTES:
*/

#include "built_in.h" // This lets us use lo(), hi(), higher()

char txt[12];
char txt2[12];

unsigned short myShort;
long myVar1 = 213077;
long myVar2 = 236318;

void Write_to_EEPROM()
{
Soft_I2C_Start(); // issue I2C start signal
Soft_I2C_Write(0xA2); // send byte via I2C (command to 24CO2)

Soft_I2C_Write(1); // First Adress (Adres 1)

Soft_I2C_Write(Lo(myVar1)); // write the lowest 8 bits of myVar1
Delay_ms(20);
Soft_I2C_Write(Hi(myVar1)); // write bits 9-16 of myVar1
Delay_ms(20);
Soft_I2C_Write(Higher(myVar1)); // write bits 17-24 of myVar1
Delay_ms(20);
Soft_I2C_Write(Lo(myVar2));
Delay_ms(20);
Soft_I2C_Write(Hi(myVar2));
Delay_ms(20);
Soft_I2C_Write(Higher(myVar2));
Delay_ms(20);

Soft_I2C_Stop();
}

void Read_from_EEPROM()
{

myVar1 = 0; // Initialize the variables to keep us honest
myVar2 = 0;

Soft_I2C_Start(); // issue I2C start signal
Soft_I2C_Write(0xA2); // send byte via I2C (device address + W)
Soft_I2C_Write(1); // first word address
Soft_I2C_Start(); // issue I2C signal repeated start
Soft_I2C_Write(0xA3); // send byte (device address + R)

Lo(myVar1) = Soft_I2C_Read(1);
Delay_ms(20);
Hi(myVar1) = Soft_I2C_Read(1);
Delay_ms(20);
Higher(myVar1) = Soft_I2C_Read(1);
Delay_ms(20);
Lo(myVar2) = Soft_I2C_Read(1);
Delay_ms(20);
Hi(myVar2) = Soft_I2C_Read(1);
Delay_ms(20);
Higher(myVar2) = Soft_I2C_Read(1);
Delay_ms(20);

LongToStr(myVar1,txt);
LongToStr(myVar2,txt2);
}

void Display()
{
LCD_Out(1,1,"V=");
LCD_Out_CP(txt);
LCD_Out(2,1,"I=");
LCD_Out_CP(txt2);
Delay_ms(750);
}

void main()
{
ADCON1 = 0x0F; // Configure AN pins as digital
Lcd_init(&PORTD);
Soft_I2C_Config(&PORTB, 4, 3);
//Write_to_EEPROM();
Delay_ms(50);
Read_from_EEPROM();

while(1)
{
Display();
}

}


Thanks again for your help

Post Reply

Return to “mikroC General”