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

How to do a Multi Array Selection

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



Joined: 11 Jan 2012
Posts: 69

View user's profile Send private message

How to do a Multi Array Selection
PostPosted: Fri Oct 07, 2016 6:06 pm     Reply with quote

I have four different arrays which have comma delimited data as follows:
Code:

unsigned char Melody1[] = {"32p,8g,8p,16a#.,8p,8g,16p,8f,8g,8p};
unsigned char Melody2[] = {"32p,8g,8p,16a#.,8p,16g,32p,8f,8g,8p};
unsigned char Melody3[] = {"32p,8g,8p,16a#.,8p,16g,8p,8f,8g,8p};
unsigned char Melody4[] = {"32p,8g,8p,16a#.,8p,16g,16p,16f,8g,8p};

How can I use switch statement or something else to select just one array each time I want to use it. So, lets say at the beginning the switch setting would be 0, and I would select Melody1[], If the switch is pressed again then I want to select the next Melody etc. Thank you for all your suggestions.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 07, 2016 8:45 pm     Reply with quote

The easiest way would be to create a 2-dimensional array.

To do the thing with the switch, just use a global variable. Initialize it to 0.
Every time the switch is pressed, increment the variable. If the value
goes beyond the limit, reset it to 0. This variable will select the Row
in the 2-dimensional array.
CMatic



Joined: 11 Jan 2012
Posts: 69

View user's profile Send private message

PostPosted: Fri Oct 07, 2016 9:59 pm     Reply with quote

I forgot to mentioned that the individual arrays are of different lengths. As such I don't understand how to make the 2 dimensional array.
Ttelmah



Joined: 11 Mar 2010
Posts: 19358

View user's profile Send private message

PostPosted: Sat Oct 08, 2016 6:44 am     Reply with quote

At the end of the day, there has to be something to say you have reached the end of an array. For a string this is the NULL ('\0') character. Now I'm not sure if your data is actually a string (you start with an opening pair of inverted commas, but don't have one at the end of the data). I suspect it is, except for the lack of the closing inverted commas, it looks like it is.
If the data is in string format, then your target function can just walk through the data till it sees the '\0' character.
You can just call this function, with a pointer to the array you want. Even better, these can be stored in another array.
As a further comment, if these melodies are not being changed in the code, they could be declared as rom/const, to save a lot of RAM.

So:
Code:

void demo_function(unsigned char * data)
{
    while (*(data++) !='\0')
    {
         //walk through the selected melody
    }
}

//Using data like:
unsigned char Melody1[] = {"32p,8g,8p,16a#.,8p,8g,16p,8f,8g,8p"};
unsigned char Melody2[] = {"32p,8g,8p,16a#.,8p,16g,32p,8f,8g,8p"};
unsigned char Melody3[] = {"32p,8g,8p,16a#.,8p,16g,8p,8f,8g,8p"};
unsigned char Melody4[] = {"32p,8g,8p,16a#.,8p,16g,16p,16f,8g,8p"};
//have added closing "

unsigned char * melodies[4]={Melody1,Melody2,Melody3,Melody4};

     //Then you can call the 'demo_function', with a selected melody, using:

     demo_function(melodies[number_you_want]);



as one added 'comment' to this. This assumes a reasonably recent compiler.
CMatic



Joined: 11 Jan 2012
Posts: 69

View user's profile Send private message

PostPosted: Sat Oct 08, 2016 10:52 am     Reply with quote

Thank you Ttelmah. Yes the data is string with inverted commas and my compiler version is CCS PCM C Compiler, Version 5.026. I assume that I will not have any compiler related issues once I compile it.
Once again thanks to Ttelmah and PCM Programmer.
CMatic



Joined: 11 Jan 2012
Posts: 69

View user's profile Send private message

PostPosted: Tue Oct 11, 2016 8:08 pm     Reply with quote

I have managed to successfully compile my program as suggested by Ttelmah in the above message. Now my question is regarding how the data array is stored in Program space.

As an example, the array:
Code:

unsigned char Melody1[] = {"32p,8g,8p,16a#.,8p,8g,16p,8f,8g,8p"};

when my rs232 stream data it shows something as follows:

3h2hph,8hgh,8hph,1h6hah#h and so on

When I look into the CCS compiler output file .LST, I see the following data:

ROM data:
001D5D: 3431 3436 3464 3435 342C 3431 3436 3464
001D65: 3423 3435 342C 3431 3436 3464 3435 342C
001D6D: 3431 3436 3464 3423 3435 342C 3431 3436
001D75: 3464 3435 342C 3431 3436 3464 3423 3435
001D7D: 342C 3431 3436 3464 3435 342C 3431 3436
001D85: 3464 3435 342C 3431 3436 and so on.

My question is why does this array look different between rs232 output and the lst file ? Thank you.
Ttelmah



Joined: 11 Mar 2010
Posts: 19358

View user's profile Send private message

PostPosted: Wed Oct 12, 2016 1:08 am     Reply with quote

You don't tell us your chip?.
Two reasons:

First, text like this is stored as ASCII. So (for instance), the byte code for the character '0', is 0x30.
Then (if your chip is a PIC16), the program memory (ROM) is only 14bits wide per instruction. As such, two 8bit characters can't be stored in a single word. Worse, on a lot of the older PIC's, the compiler cannot directly access the ROM, so has to code data stored as effectively a 'program' that returns the required bytes, using RETLW instructions (return literal in register W). It then jumps into this table of instructions, using the byte number requested.

The code you post is:
RETLW '1'
RETLW '6'
RETLW 'd'
RETLW '5'
RETLW ','
RETLW '1'
etc..

So what you post actually gives "16d5,1" etc..

So long as your data is 7bit ASCII (not 8bit), on your chip, it can be stored more efficiently using the #ROM directive. This offers the option to pack two 7bit characters into each 14bit word, but will require your code to handle unpacking this.

If you look at the data sheet, section 3.1.1, describes exactly what is being done.
CMatic



Joined: 11 Jan 2012
Posts: 69

View user's profile Send private message

PostPosted: Wed Oct 12, 2016 8:12 pm     Reply with quote

Ttelmah, thank you for a great explanation. I understand it a lot better now. My chip is PIC16F1825. I am not quite sure which datasheet were you referring to in section 3.1.1 - Please let me know so I can read it. Thanks so much, you guys are a great resource.
Ttelmah



Joined: 11 Mar 2010
Posts: 19358

View user's profile Send private message

PostPosted: Thu Oct 13, 2016 12:48 am     Reply with quote

The chip's data sheet.

When working with PIC's in CCS, you need the following in front of you:

A general C reference - possible K&R. The bible for all things C, and CCS keeps extremely close to this.
The CCS manual.
The header file for your PIC.
The CCS 'extra bits', readme.txt, fuses.txt, and the examples
The data sheet for your PIC.

These then form the 'basic reference' to work with any PIC.

3.1.1, is the same in all recent PIC16 data sheets, and describes how constant data is stored in ROM.

It's part of a fundamental understanding of the PIC16. On most processors the RAM and ROM are all part of one address space, that is the same width. This is the von Neumann architecture. The PIC instead uses the Harvard architecture. The advantage of this is that the memory paths to the RAM and ROM are separate, allowing the chip to be simultaneously accessing both at the same time, without getting involved in using cache memory. So for a small processor, quick and cheap. However downside is that the two memory spaces are completely separate, so two addresses needed (which is why pointer accesses to ROM are relatively difficult on the PIC), and given the ROM is built just to be read by the CPU to fetch instructions, and may not be the same width as the RAM, there is not necessarily an easy way to simply read a byte from the ROM. On the PIC16, the early chips did not allow any form of direct read, and the ROM is 14bits wide. Even on later chips where reading is possible, it is much slower to setup a table read, than use the RETLW instruction form, and so it is easier and quicker to still use the RETLW form to store byte data. On the PIC18, it's still a problem with two addresses, but the ROM is 16bits wide, so two bytes can be stored in each instruction word. On the PIC24, it goes slightly more complex again, with three bytes per word (24bit instruction space).
CMatic



Joined: 11 Jan 2012
Posts: 69

View user's profile Send private message

PostPosted: Sat Oct 15, 2016 2:44 pm     Reply with quote

Ttelmah thanks for such a great advice and pointing of 3.1.1 section. Once again, you guys provide such great help to all of us who are learning embedded programming. Thanks
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