|
|
View previous topic :: View next topic |
Author |
Message |
yesahycs
Joined: 31 Oct 2007 Posts: 5
|
ROM size Not Enough, a lot of NESTED IF/ELSE + SWITCH() |
Posted: Wed Nov 21, 2007 12:39 am |
|
|
Version: CCS PCM C COMPILER, version 4.033, 33187
PIC: 16F690
Background:
Wanted to build a program which can verify various instructions input through RS232. IF verification is correct, 16F690 will act as slave and send data to the master. IF input is wrong, the phrase ERR will pop up to notify user instantly. IF input is correct, an OK phrase will appear (perform sending instruction). There are about 80 sets of instructions, all with 8 characters.
For example:
"POWR0 " (3 blank space behind)
"CLCK*** " (1 blank)
"CHUP "(4 blank space)
"CHDW " (4 blankspace)..
If the user type X for the first word, the program will pop up ERR, as there is no instructions starts with the word X. Even if he type P->X, the ERR will pop up instant too.
The phrase OK will come out if and only if the user enter the codes in the correctly.
Of course,these are only 4 examples.. there are still whole load of nested if else and switch case inside..
I don't know how to separate this to two functions as i saw in other threads separating 1 big function into 2 functions may solve the problem.
So being a newbie, i did sth like below:
Code: |
#include <16F690.h>
#use delay(CLOCK=18432000) // using a 18.432Mhz clock
#use rs232(baud=9600, XMIT= PIN_B7, RCV= PIN_B5) // rs232 setting
#fuses HS,NOWDT,NOMCLR,NOPROTECT,NOBROWNOUT,NOFCMEN,NOIESO,NOCPD,NOPUT
/* Use internal clock mode, no watch dog, no code protect, no powerup timer */
char ch;
void ioput()
{
putc(ch);
ch=getchar();
}
void putsOK()
{
putc(ch);
putc('O');
putc('K');
putc('\n');
putc('\r');
}
void putsERR()
{
putc('E');
putc('R');
putc('R');
putc('\n');
putc('\r');
}
void checkinput()
{
ch=getchar();
switch(ch)
{case 'P':
ioput();
switch(ch)
{ case 'O':
ioput();
if (ch=='W')
{ ioput();
if(ch=='R')
{ioput();
if(ch=='0')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{putc(ch);
putsOK();
//perform action POWR0
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
break;
case 'C':
ioput();
switch(ch)
{case 'L':
ioput();
if(ch=='C')
{ioput();
if(ch=='K')
{ioput();
if(ch=='*')
{ioput();
if(ch=='*')
{ioput();
if(ch=='*')
{ioput();
if(ch==' ')
{
//perform CLCK***
putsOK();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
break;
case 'H':
ioput();
switch(ch)
{case 'U':
ioput();
if(ch=='P')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{
//perform CHUP
putsOK();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
break;
case 'D':
ioput();
if(ch=='W')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{ioput();
if(ch==' ')
{
//perform CHDW
putsOK();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
}
else putsERR();
break;
default: putsERR();
break;
}
break;
default: putsERR();
break;
}
break;
default:putsERR();
break;
}
}
void main()
{
while (1)
{
checkinput();
}
}
|
Sorry for the long code.
The actual 1 is 100x times longer |
|
|
yesahycs
Joined: 31 Oct 2007 Posts: 5
|
more details |
Posted: Wed Nov 21, 2007 2:05 am |
|
|
Code: |
ROM used: 1772 (43%)
1772 (43%) including unused fragments
1 Average locations per line
2 Average locations per statement
RAM used: 7 (3%) at main() level
7 (3%) worst case
Stack used: 2 worst case (out of 8 total available)
Lines Stmts % Files
----- ----- --- -----
1587 954 100 project.c
375 0 0 C:\Program Files\PICC\devices\16F690.h
----- -----
1962 954 Total
Page ROM % RAM Vol Diff Functions:
---- --- --- --- --- ---- ----------
0 9 1 0 35 1.6 ioput
0 21 1 0 86 1.3 putsOK
0 21 1 0 86 1.3 putsERR
0 1683 95 0 29854 6.0 checkinput
0 34 2 0 27 1.0 MAIN
Program metrics:
Functions 5
Statements 954
Comments 372
Volume (V) 30705
Difficilty (D) 12.9
Effort to implement (E) 395392
Time to implement (T) 6 hours, 6 minutes
Est Delivered Bugs (B) 2
Cyclomatic Complexity 338
Maintainability (MI) 61
Segment Used Free
----------- ---- ----
00000-00003 4 0
00004-007FF 1768 276
00800-00FFF 0 2048
|
|
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Wed Nov 21, 2007 4:54 am |
|
|
Your code is a classic 'code driven' approach, whereas you need to let the data drive the logic. Something like:
Code: | char ch;
#define CMD_LEN_MAX 8 // or as reqd
#define NO_OF_CMDS 80 // or as reqd
// const is a must so that compiler puts in flash, not RAM
const char commands[NO_OF_CMDS][CMD_LEN_MAX] = {
"POWR0",
"OtherCmds" }; // etc!
int not_command[NO_OF_CMDS];
void ioput()
{
putc(ch);
ch=getchar();
}
void putsOK()
{
putc(ch);
puts("OK\n\r");
}
void putsERR()
{
puts("ERR\n\r");
}
void checkinput()
{
int i,j,no_match;
for(i=0; i<NO_OF_CMDS;i++)
not_command[i] = 0;
for(j=0; j<CMD_LEN_MAX; j++) {
ch = getchar();
no_match = 1;
for(i=0; i<NO_OF_CMDS;i++) {
// this command failed to match so ignore
if(not_command[i])
continue;
if (commands[i][j] == ch)
no_match = 0;
else
not_command[i] = 1;
}
if(no_match) {
putsERR();
return;
}
}
putsOK();
} |
I've just typed this in pretty quickly so apologies for any errors, but you can see the general idea. |
|
|
Guest
|
|
Posted: Wed Nov 21, 2007 6:55 pm |
|
|
Thanks.
I'm out of town now, will try it at home.
However i wonder will the ram size fit all the commands..
Its around 100 comands, each command will hold 9 characters (include blanks). |
|
|
yesahycs
Joined: 31 Oct 2007 Posts: 5
|
|
Posted: Wed Nov 21, 2007 11:30 pm |
|
|
Hmm, i did not tried the code yet.
After browsing it through, it MAY verify the input.
However, after verifying the input, i need to send the input as SLAVE thru I2c to the master.
According to SET's code, the program only puts OK and cannot send different instructions for diff inputs.
correct me if i'm wrong.
I'm still a newbie. |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Thu Nov 22, 2007 6:15 am |
|
|
Quote: | After browsing it through, it MAY verify the input.
However, after verifying the input, i need to send the input as SLAVE thru I2c to the master.
According to SET's code, the program only puts OK and cannot send different instructions for diff inputs. |
To do this, set a variable that is set to a unique value after each command string is recognised. Then call a different function (or perform a different action) depending on this variable. |
|
|
Ttelmah Guest
|
|
Posted: Thu Nov 22, 2007 9:16 am |
|
|
To have any hope of doing this, you are going to need to:
1) Learn something about the code and chip....
2) Think _very_ carefully...
Now, '1' applies, because you mention _RAM_. SET's approach, _does not use the RAM_. The strings are declared as 'const', which means they are in _ROM_.
'2' applies, because there _will_ still be problems.
100, 9 character commands, would correspond to 900 characters. With 'null' separators (strings in 'C', have an extra 'null' character at the end of each), which would take the space _just to store the commands_, to 1000 characters. nearly 1/4 the ROM, just to hold the commands, before doing anything at all with these. However you also have the problem that the largest array supported on the 12 family chips is just 256 characters, which means you will _need_ to think things out a lot more.
Some questions apply.
Do the commands fall into 'sets' of different lengths, or types, possibly with similar starting letter combinations for the sets?. If so, then you should be able to save storage. How many different things do you need to do 'with' the commands?. Given the number of possible commands, and the storage available, it may well be impossible to actually achieve in this chip, unless the number of 'outcomes' is not as many as the number of commands.
Best Wishes |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Thu Nov 22, 2007 9:23 am |
|
|
I agree with Ttelmah - in some ways this is an ambitious project for a 'newbie'. You need to get more familiar with how the language (C) maps to the actual chip, it's memory sizes and structure. We all have to do this to some extent - right now I'm doing some DSP work on TI chips, in some ways much the same, but with differences too (code can execute out of RAM or Flash for example). |
|
|
|
|
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
|