![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
art
Joined: 21 May 2015 Posts: 181
|
Split data from EEPROM |
Posted: Tue May 23, 2017 2:09 am |
|
|
Hi ,
I've managed to load data from eeprom.
Output data 8544854481441122 will be display. I would like to make the output data to be split to 4 string:
8544 (address 0000 to 0003)
8544 (address 0004 to 0007)
8144 (address 0008 to 000B)
1122 (address 000C to 000F)
Is there is a code to read directly from curtain range of address?
Eg: read from address (0004 to 0007)
Could someone please help me to solve this problem. Here is my code:
Code: |
#include <18F4550.h>
#DEVICE ADC=10
#fuses HSPLL,NOWDT,PROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include <string.h>
#include <input.c>
#include <stdio.h>
#include <stdlib.h>
#include <usb_cdc.h>
#include "24256.c"
void main()
{
char c;
int8 i ;
unsigned char d;
unsigned char key;
usb_init_cs();
while (TRUE)
{
usb_task();
if (usb_cdc_kbhit())
{
c=usb_cdc_getc();
if (c=='\n') {putc('\r'); putc('\n');}
if (c=='\r') {putc('\r'); putc('\n');}
while(true)
{
ART:
d = usb_cdc_getc();
if(d=='C') // push C
{
while (key!=32) // push SPACE BAR to stop
{
if(usb_cdc_kbhit())
{key=usb_cdc_getc();}
char const line1[]= {"8544854481441122"};
{
int8 i;
int8 buffer[20];
printf(usb_cdc_putc, "\n");
for(i = 0; i < sizeof(line1); i++)
write_ext_eeprom(i, line1[i]);
for(i = 0; i < sizeof(line1); i++)
{
buffer[i] = read_ext_eeprom(i);
}
printf(usb_cdc_putc,buffer);
}
} key=0; // to initialize 'key' not as SPACE BAR
}
}
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19385
|
|
Posted: Tue May 23, 2017 3:24 am |
|
|
Think about it.
You already have everything you need....
Take your existing 'read' code, and turn it into a subroutine, and give it a 'start' and an 'end' value.
Remember that you need to null terminate a 'string'. Currently your code works, because there is actually a null being stored into the EEPROM, and since you use 'sizeof' (which includes the extra space for the null), this gets included in the transfer. You would need to add this to the shorter set of characters you extract. |
|
![](templates/subSilver/images/spacer.gif) |
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Wed May 24, 2017 2:43 am |
|
|
I have modified the code but it still cannot show the result as i want.
Kindly please show me which part is mistake.
Code: |
#include <18F4550.h>
#DEVICE ADC=10
#fuses HSPLL,NOWDT,PROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include <string.h>
#include <input.c>
#include <stdio.h>
#include <stdlib.h>
#include <usb_cdc.h>
#include "24256.c"
void main()
{
char c;
int8 i ;
unsigned char d;
unsigned char key;
usb_init_cs();
while (TRUE)
{
usb_task();
if (usb_cdc_kbhit())
{
c=usb_cdc_getc();
if (c=='\n') {putc('\r'); putc('\n');}
if (c=='\r') {putc('\r'); putc('\n');}
while(true)
{
ART:
d = usb_cdc_getc();
if(d=='C') // push C
{
while (key!=32) // push SPACE BAR to stop
{
if(usb_cdc_kbhit())
{key=usb_cdc_getc();}
char const line1[]= {"8544854481441122"};
{
int8 i,k;
int8 buffer[20];
printf(usb_cdc_putc, "\n");
for(i = 0; i < sizeof(line1); i++)
write_ext_eeprom(i, line1[i]);
for(k = 0; k < sizeof(line1);k=k+4)
{
for(i = k; i < k+4; i++)
{
buffer[i] = read_ext_eeprom(i);
}
printf(usb_cdc_putc,buffer);
printf(usb_cdc_putc,"\n");
}
}
} key=0; // to initialize 'key' not as SPACE BAR
}
}
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19385
|
|
Posted: Wed May 24, 2017 3:51 am |
|
|
Code: |
void read_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
{
int8 count;
for (count=0;count<no_chars;count++) //how many characters
{
*buffer[count]=read_ext_eeprom[start_addr++];
}
*buffer='\0';//null terminate
}
//Then call this with:
read_string_eeprom(buffer, 0, 4);
//should give buffer having "8544" (correctly terminated)
read_string_eeprom(buffer,4,8);
//should give buffer having "85448144"
//etc..
|
Remember not to call with 'no_chars' greater than the sizeof(buffer)-1.....
You were missing the point about having to null terminate the data. |
|
![](templates/subSilver/images/spacer.gif) |
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Wed May 24, 2017 7:15 pm |
|
|
Dear Ttelmah,
I've change the code
Code: |
*buffer[count]=read_ext_eeprom[start_addr++];
|
to
Code: |
*buffer[count]=read_ext_eeprom(start_addr++);
|
because it cannot compile.
After change ,it can compile but it will not return any value at all.
Code: |
#include <18F4550.h>
#DEVICE ADC=10
#fuses HSPLL,NOWDT,PROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include <string.h>
#include <input.c>
#include <stdio.h>
#include <stdlib.h>
#include <usb_cdc.h>
#include "24256.c"
void read_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
{
int8 count;
for (count=0;count<no_chars;count++)
{
*buffer[count]=read_ext_eeprom(start_addr++);
}
*buffer='\0';
void main()
{
char c;
int8 i ;
unsigned char d;
unsigned char key;
usb_init_cs();
while (TRUE)
{
usb_task();
if (usb_cdc_kbhit())
{
c=usb_cdc_getc();
if (c=='\n') {putc('\r'); putc('\n');}
if (c=='\r') {putc('\r'); putc('\n');}
while(true)
{
ART:
d = usb_cdc_getc();
if(d=='C') // push C
{
while (key!=32) // push SPACE BAR to stop
{
if(usb_cdc_kbhit())
{key=usb_cdc_getc();}
char const line1[]= {"8544854481441122"};
{
int8 i,k;
int8 buffer[20];
printf(usb_cdc_putc, "\n");
for(i = 0; i < sizeof(line1); i++)
write_ext_eeprom(i, line1[i]);
for(i = 0; i < sizeof(line1);i++)
{
buffer[i] = read_ext_eeprom(i);
}
read_string_eeprom(buffer, 0, 4);
printf(usb_cdc_putc,buffer);
printf(usb_cdc_putc,"\n");
}
}
} key=0; // to initialize 'key' not as SPACE BAR
}
}
}
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19385
|
|
Posted: Thu May 25, 2017 12:10 am |
|
|
What you have done wrong would become obvious if you used a bit of structure in your code:
1) Keep to the C standard on variable declarations. Declare them at the start of functions or at the start of code blocks. Declaring 'anywhere' makes it almost impossible to know what variables are declared where. If you want to declare in-line, then label the sections, and add really visible comments when you declare the variables.
2) Use a standard on indents. So when a code block starts have the opening bracket, and indent. When it ends close the bracket and move back. You have omitted the closing bracket from the function I posted, and then have an extra one in your main code. Because of the lack of consistency in your use of indents, it is not obvious. |
|
![](templates/subSilver/images/spacer.gif) |
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Thu May 25, 2017 1:48 am |
|
|
Hi Ttelmah,
I've rearranged the code as you advised. It still did not show the result that i need.
Code: |
#include <18F4550.h>
#DEVICE ADC=10
#fuses HSPLL,NOWDT,PROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
#include <string.h>
#include <input.c>
#include <stdio.h>
#include <stdlib.h>
#include <usb_cdc.h>
#include "24256.c"
void read_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
{
int8 count;
for (count=0;count<no_chars;count++)
{
*buffer[count]=read_ext_eeprom(start_addr++);
}
*buffer='\0';
}
void main()
{
char c;
int8 i ;
unsigned char d;
unsigned char key;
char const line1[]= {"8544854481441122"};
int8 buffer[20];
usb_init_cs();
while (TRUE)
{
usb_task();
if (usb_cdc_kbhit())
{
c=usb_cdc_getc();
if (c=='\n') {putc('\r'); putc('\n');}
if (c=='\r') {putc('\r'); putc('\n');}
while(true)
{
d = usb_cdc_getc();
if(d=='C') // push C
{
while (key!=32) // push SPACE BAR to stop
{
if(usb_cdc_kbhit())
{key=usb_cdc_getc();}
{
printf(usb_cdc_putc, "\n");
for(i = 0; i < sizeof(line1); i++)
write_ext_eeprom(i, line1[i]);
for(i = 0; i < sizeof(line1);i++)
{
buffer[i] = read_ext_eeprom(i);
}
read_string_eeprom(buffer, 0, 4);
printf(usb_cdc_putc,buffer);
printf(usb_cdc_putc,"\n");
}
} key=0; // to initialize 'key' not as SPACE BAR
}
}
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
|
Posted: Thu May 25, 2017 6:31 am |
|
|
Look at how you are using your brackets after
Code: | if(usb_cdc_kbhit()) |
You are not using standard bracket/indention after it, and as it is currently, it will not function the way you expect.
try reformatting to one of the following:
Code: |
if(usb_cdc_kbhit()){
//your code here
}
if(usb_cdc_kbhit())
{
//your code here
}
|
Your current code doesn't match either of these standard ways.
Also, some of the indention you did do is wrong. In particular look at the line with
Code: |
} key=0; // to initialize 'key' not as SPACE BAR
|
It is not indented correctly. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 25, 2017 10:41 am |
|
|
I was able to make it print the string by fixing the string routine
as shown below. Here is the working routine:
Code: |
void read_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
{
int8 count;
for(count=0; count<no_chars; count++)
{
buffer[count] = read_eeprom(start_addr++);
}
buffer[count] = '\0';
}
|
Here is the full test program. I stripped down the original program to
essentials and changed it to internal eeprom so it could run in the MPLAB
vs. 8.92 simulator. I tested this with compiler vs. 5.071.
It displays the following output:
Full test program:
Code: |
#include <18F4550.h>
#DEVICE ADC=10
#fuses HSPLL,NOWDT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
//------------------------------
void read_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
{
int8 count;
for(count=0; count<no_chars; count++)
{
buffer[count] = read_eeprom(start_addr++);
}
buffer[count] = '\0';
}
//===============================
void main()
{
int8 i;
char const line1[]= {"8544854481441122"};
int8 buffer[20];
// Fill eeprom with data from line1[] array.
for(i = 0; i < sizeof(line1); i++)
{
write_eeprom(i, line1[i]);
}
read_string_eeprom(buffer, 0, 4);
printf(buffer);
printf("\r");
while(TRUE);
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19385
|
|
Posted: Thu May 25, 2017 1:59 pm |
|
|
However that is not why it wouldn't compile....
I had spotted the errors, but wanted him to actually edit his code to lay it out sensibly, and balance the braces so it would compile, before pointing these out. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 25, 2017 3:06 pm |
|
|
ok, sorry. |
|
![](templates/subSilver/images/spacer.gif) |
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Thu May 25, 2017 6:34 pm |
|
|
Hi ttelmah and PCM,
Thank you very much. It works!
However i still have doubt about:
Code: |
void read_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
|
I've search in the external_eeprom.c and internal_eeprom.c
But cannot find this fuction. Where should i refer to? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19385
|
|
Posted: Fri May 26, 2017 1:02 am |
|
|
You need to get a C textbook.....
The function definition and declaration _are_ the code we posted.
Code: |
//------------------------------
void read_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
{
int8 count;
for(count=0; count<no_chars; count++)
{
buffer[count] = read_eeprom(start_addr++);
}
buffer[count] = '\0';
}
|
This defines and declares the function.
This reads characters from the EEPROM, starting at 'start_addr', and counting up to 'no_chars', copying each into the RAM area pointed to by 'buffer'. Then once it has copied these it adds a '\0' as the next character in the buffer.
Now you need to understand that in C, there isn't a fundamental 'string' type. A 'string' in C, is a simple array of characters, _terminated by a null_.
"8544854481441122"
Is actually 17 characters. The ones you see, and the extra terminating '\0'.
Now when you store this to the EEPROM, all 17 characters are sent (because you use 'sizeof' to give how many characters to store, rather than 'strlen, which would just give '16'). So when you read this back, you get the nice little terminator included. Problem is that if you only want to retrieve 'part' of this, you then have to add the terminator yourself.
So if you read just the first four characters into an array, and tried to print this, you would get the four character, but then the print would not see a terminator, and would carry on printing other stuff from memory, till it eventually does hit a terminator. So you would get the four characters you want and a whole load of other garbage (depending what happens to be in the RAM), after this...
Now it's also a lesson in another way. If you have a bit of code you want to repeat, then declare it as a separate function. This way the code can be re-used, without having to type it multiple times into the main. This is particularly critical on the PIC, where the memory is organised as 'pages'. Now imagine that I typed all of this (all the stuff here), and didn't break it into paragraphs. If I kept going, I'm going to overflow the page (no matter how long it is) eventually. Problem is that code is not allowed to overflow a page like this, so you then get a warning that you have run 'out of ROM', even though the code only fills perhaps 1/4 the available space on the chip.
However if the code is in 'paragraphs', then these can be placed in other pages. So you need to start 'sectionalising' your code. If you need a routine to send a particular type of message to something (or retrieve a block from the EEPROM), and it is going to be used multiple times, then write it as a separate function. Also this can then be debugged on it's own... |
|
![](templates/subSilver/images/spacer.gif) |
art
Joined: 21 May 2015 Posts: 181
|
|
Posted: Fri May 26, 2017 3:04 am |
|
|
Thanks Ttelmah.
So if i want to write to certain buffer, such as [1] to [4]
Code: |
void write_string_eeprom(char * buffer, int16 start_addr, int8 no_chars)
{
int8 count;
for(count=0; count<no_chars; count++)
{
buffer[count] = write_eeprom(start_addr++);
}
buffer[count] = '\0';
} |
Is this correct? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19385
|
|
Posted: Fri May 26, 2017 7:00 am |
|
|
Er. No....
Write_eeprom, sends data, not retrieves it. You have also switched to using 'write_eeprom' (which writes to the local chip's eeprom if it has it), rather than 'write_ext_eeprom', (which writes to an external eeprom).
Doesn't return data (so wouldn't put things into 'buffer).
You really do need to get a C textbook, and do some basic experimentation and learning,
If you were writing to either EEPROM, and included the null terminator, then this would overwrite the next character in this.... |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|