CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Split data from EEPROM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

Split data from EEPROM
PostPosted: Tue May 23, 2017 2:09 am     Reply with quote

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
                             }


                     }
               }       
         }             
}                     

Ttelmah



Joined: 11 Mar 2010
Posts: 19222

View user's profile Send private message

PostPosted: Tue May 23, 2017 3:24 am     Reply with quote

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.
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

PostPosted: Wed May 24, 2017 2:43 am     Reply with quote

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
                             }


                     }
               }       
         }             
}         
Ttelmah



Joined: 11 Mar 2010
Posts: 19222

View user's profile Send private message

PostPosted: Wed May 24, 2017 3:51 am     Reply with quote

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.
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

PostPosted: Wed May 24, 2017 7:15 pm     Reply with quote

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
                             }


                     }
               }       
         }             
}         
Ttelmah



Joined: 11 Mar 2010
Posts: 19222

View user's profile Send private message

PostPosted: Thu May 25, 2017 12:10 am     Reply with quote

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.
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

PostPosted: Thu May 25, 2017 1:48 am     Reply with quote

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
                             }

                     }
               }       
         }             
}
jeremiah



Joined: 20 Jul 2010
Posts: 1317

View user's profile Send private message

PostPosted: Thu May 25, 2017 6:31 am     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 25, 2017 10:41 am     Reply with quote

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:
Quote:

8544

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);
}
 
 
Ttelmah



Joined: 11 Mar 2010
Posts: 19222

View user's profile Send private message

PostPosted: Thu May 25, 2017 1:59 pm     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 25, 2017 3:06 pm     Reply with quote

ok, sorry.
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

PostPosted: Thu May 25, 2017 6:34 pm     Reply with quote

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?
Ttelmah



Joined: 11 Mar 2010
Posts: 19222

View user's profile Send private message

PostPosted: Fri May 26, 2017 1:02 am     Reply with quote

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...
art



Joined: 21 May 2015
Posts: 181

View user's profile Send private message

PostPosted: Fri May 26, 2017 3:04 am     Reply with quote

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?
Ttelmah



Joined: 11 Mar 2010
Posts: 19222

View user's profile Send private message

PostPosted: Fri May 26, 2017 7:00 am     Reply with quote

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....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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