|
|
View previous topic :: View next topic |
Author |
Message |
CMatic
Joined: 11 Jan 2012 Posts: 69
|
How to do a Multi Array Selection |
Posted: Fri Oct 07, 2016 6:06 pm |
|
|
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
|
|
Posted: Fri Oct 07, 2016 8:45 pm |
|
|
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
|
|
Posted: Fri Oct 07, 2016 9:59 pm |
|
|
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: 19553
|
|
Posted: Sat Oct 08, 2016 6:44 am |
|
|
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
|
|
Posted: Sat Oct 08, 2016 10:52 am |
|
|
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
|
|
Posted: Tue Oct 11, 2016 8:08 pm |
|
|
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: 19553
|
|
Posted: Wed Oct 12, 2016 1:08 am |
|
|
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
|
|
Posted: Wed Oct 12, 2016 8:12 pm |
|
|
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: 19553
|
|
Posted: Thu Oct 13, 2016 12:48 am |
|
|
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
|
|
Posted: Sat Oct 15, 2016 2:44 pm |
|
|
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 |
|
|
|
|
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
|