|
|
View previous topic :: View next topic |
Author |
Message |
joaoandrade
Joined: 27 Mar 2014 Posts: 2
|
Problems with an increase |
Posted: Thu Mar 27, 2014 11:25 am |
|
|
Hi guys.
I am doing a project using PIC16F877A reading and writing to EEPROM 24C04. The memory write is OK, but when reading the recorded data when I'm incrementing variable "Adress", strangely she jumps 3 address to the 101, I'm doing testing on Proteus Pro 8, I am using the library 240C.c CCS itself. Below is the code I implemented:
Code: |
#include <main.h>
#include <string.h>
#include <2404.C>
#include <LCD_16x2_Lib.c>
#include <stdio.h>
#include <stdlib.h>
//Strings to write
char Mard[] = "Mardonio";
char Rob[] = "Roberto";
char Lu[] = "Luciano";
//To read
char Mard2[] = "";
char Rob2[] = "";
char Lu2[] = "";
//Start position for recording
int Adress = 0x00;
void main()
{
init_ext_eeprom();
ini_lcd_16x2();
while(TRUE)
{
//Writing string on EEPROM EXT.
printf(exibe_lcd,"\f Writing...");
delay_ms(500);
for(int i = 0; i < strlen(Mard); i++)
{
write_ext_eeprom(Adress, Mard[i]);
Adress++;
printf(exibe_lcd,"\f%d",Adress);
printf(exibe_lcd,"\n%c",Mard[i]);
delay_ms(500);
}
for(int j = 0; j < strlen(Rob); j++)
{
write_ext_eeprom(Adress, Rob[j]);
Adress++;
printf(exibe_lcd,"\f%d",Adress);
printf(exibe_lcd,"\n%c",Rob[j]);
delay_ms(500);
}
for(int k = 0; k < strlen(Lu); k++)
{
write_ext_eeprom(Adress, Lu[k]);
Adress++;
printf(exibe_lcd,"\f%d",Adress);
printf(exibe_lcd,"\n%c",Lu[k]);
delay_ms(500);
}
Adress = 0x00;
printf(exibe_lcd,"\f Reading...");
delay_ms(500);
printf(exibe_lcd,"\f");
delay_ms(500);
//Lendo os dados da EEPROM EXT.
for(int p = 0; p < strlen(Mard); p++)
{
Mard2[p] = read_ext_eeprom(Adress);
Adress = Adress +1;
printf(exibe_lcd,"\f%d",Adress);
printf(exibe_lcd,"\n%c",Mard2[p]);
delay_ms(500);
}
for(int m = 0; m < strlen(Rob); m++)
{
Rob2[m] = read_ext_eeprom(Adress);
Adress++;
printf(exibe_lcd,"\f%d",Adress);
printf(exibe_lcd,"\n%c",Rob2[m]);
delay_ms(500);
}
for(int n= 0; n < strlen(Lu); n++)
{
Lu2[n] = read_ext_eeprom(Adress);
Adress++;
printf(exibe_lcd,"\f%d",Adress);
printf(exibe_lcd,"\n%c",Lu2[n]);
delay_ms(500);
}
Adress = 0x00;
char teste = read_ext_eeprom(0x00);
printf(exibe_lcd,"\f%c",teste);
delay_ms(1000);
}
}
|
This is the circuit simulated on Proteus, please ignore the buttons and leds:
|
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
|
joaoandrade
Joined: 27 Mar 2014 Posts: 2
|
|
Posted: Thu Mar 27, 2014 12:04 pm |
|
|
Hi newguy.
My question has nothing to do with Proteus, but with writing code that also sent, the figure was only an illustration, no biggie. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Thu Mar 27, 2014 12:30 pm |
|
|
Key thing is lengths.
Your source strings are longer than your target strings. Mard, is 9 characters long, but you then copy this back into a target that is only one character long. Overwrites later things in memory. Garbage results.... |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Thu Mar 27, 2014 1:03 pm |
|
|
joaoandrade wrote: |
Hi newguy.
My question has nothing to do with Proteus, but with writing code that also sent, the figure was only an illustration, no biggie. |
Quote: | I'm doing testing on Proteus Pro 8 |
Whether you realize it or not, it does have a lot to do with proteus. ...And that's the reason for our informal proteus policy. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Mar 27, 2014 3:31 pm |
|
|
You can't just declare strings as:
You need to declare how long each one will need to be:
If you are trying to stuff Mard, which is an eight character string(plus the termination character equalling nine characters), into Mard2 then you need to declare Mard2 with at least nine characters available that it can hold, ie.
Now, Mard2 could be declared to be a 40 character string and only hold nine characters. It just needs to be Declared with enough space to hold whatever you want to place into it.
Ronald |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Fri Mar 28, 2014 1:16 am |
|
|
Yes, as I said.
There is a further problem though. The null terminator.
Strlen, gives the number of characters in the string itself. Ignores the null terminator. The data copied to the EEPROM as the code is written, excludes the terminator character. When it is written back to the strings, the terminator needs to be added.
Solution one. Copy the terminator as well. One character more than strlen.
Solution two. Add a terminator after copying the data back.
The original string 'Mard', will have a strlen of 8, but use nine characters of storage.
char Mard2[] = "";
Actually reserves _one_ character of storage in memory (for the terminator alone).
As you say, the declaration of the targets needs to be as big, or larger than the incoming string.
Generally in CCS, until stuff gets a bit packed in memory, CCS puts things sequentially in the RAM as it is declared. So Mard2, Rob2, Lu2, and Adress are all one after the other in memory. So when the data is read back from the EEPROM, these all get overwritten....
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|