|
|
View previous topic :: View next topic |
Author |
Message |
wgalaugher
Joined: 10 Jan 2011 Posts: 18
|
|
Posted: Thu Jun 16, 2011 9:50 am |
|
|
I see the logic of the new code. It compiles without error but returns a position of 0 for any value. I played with the variables to make them int16 but it seems to be stuck with the original problem.
Code: |
#include <18F2620.h>
//#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#include <flex_lcd.c>
#define NR_ELEMENTS(x) (sizeof(x)/sizeof(x[0]))
int16 table_search(int16 *pointer, int8 size, char value) // <<--- note the int16 *
{
int8 count=0;
while((value>*pointer)&&(--size)) { count++; pointer++; }
return count;
}
void main()
{
lcd_init(); // Always call this first.
int16 Array[] = {1800,2001,3500,4001,7000,7351,10100,10201,14000,14351,18068,18169,21000,21451,24890,24991,28000,29701};
int8 Position;
Position = table_search(Array,NR_ELEMENTS(Array), 7001); // changed the automatic array calculation to be more flexible for other data types
// for(;;);
lcd_putc("\fHello World\n");
printf(lcd_putc," %u "Position);
while(1);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Thu Jun 16, 2011 10:04 am |
|
|
Obvious problem.
How large is a character?.
How large is 7001?.
Best Wishes |
|
|
wgalaugher
Joined: 10 Jan 2011 Posts: 18
|
|
Posted: Thu Jun 16, 2011 2:02 pm |
|
|
I guess I'm a bit thick; hate to admit it. I think a character is a byte and 7001 is 2 bytes. It may seem obvious but I don't know how to fix it. But I want to learn. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 16, 2011 2:41 pm |
|
|
He's talking about your function declaration. You have the size of 'value'
set as a char (0 to 255), but you're giving it 7001. You need to change
the function declaration so that 'value' is specified as a data type that's
large enough to hold 7001.
Quote: |
int16 table_search(int16 *pointer, int8 size, char value) // Function Declaration
Position = table_search(Array,NR_ELEMENTS(Array), 7001);
|
Download the CCS manual.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look in this section:
Quote: | Basic and Special types |
It's on page 43 of the manual (or page 55 in the Acrobat reader).
It lists all CCS data types and the size of numbers that they can hold.
From that table, you should be able to select the next larger data type
above a char, that will hold 7001.
Note that it says: All types, except float, by default are unsigned. |
|
|
wgalaugher
Joined: 10 Jan 2011 Posts: 18
|
|
Posted: Thu Jun 16, 2011 3:08 pm |
|
|
Thanks guys. Its too bad I need a 2x4 across the forehead. I think age is creeping; no one in his right mind should be learning C at 70.
All is working and I learned alot along the way |
|
|
wgalaugher
Joined: 10 Jan 2011 Posts: 18
|
|
Posted: Thu Aug 18, 2011 5:28 pm |
|
|
I got the above code working as advertised but I need a modification to make the project work.
Below is a snippet from pbasic that does the job but I'm having a hard time to convert the code to CCS
LOOKDOWN freq,<[1800,2001,3500,4001,7000,7351,10100,10201,14000,14351,18068,18169,21000,21451,24890,24991,28000,29701],x
For example If the measured freq=14300 the x=9. If freq=13500 then x=0 which is out of amateur bands; the value of freq must fall inside the band intervals. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Fri Aug 19, 2011 9:06 am |
|
|
Heck, I'm impressed you want to learn C at 70 and a Ham at that !!
Try reading about the 'Switch' function. It might be a LOT easier to understand and code up AND get working.
ie...
Code: |
switch (cmd) {
case 0:printf("cmd 0");
break;
case 1:printf("cmd 1");
break;
default:printf("bad cmd");
break;
}
|
for you.. ??
Code: |
switch(freq ) {
case 1800:x=0;
case 2000:x=1;
more of the same...
case 14351:x=0;
more as required...
|
It's another way to get what I think you want and easier for me to understand.
BTW pressing F11 will open the CCS compiler's onscreen help file...mine's always open....
73 J |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 19, 2011 1:50 pm |
|
|
Quote: | LOOKDOWN freq,<[1800,2001,3500,4001,7000,7351,10100,10201,14000,14351,18068,18169,21000,21451,24890,24991,28000,29701],x
For example If the measured freq=14300 the x=9. If freq=13500 then x=0 which is out of amateur bands; the value of freq must fall inside the band intervals. |
I'm trying to understand what you are trying to do. In the your first
example of a number, 14300, it's clearly between two of the values in
the table, 14000 and 14351. Then you're assigning the index (9)of the
larger number in the table (14351) as the result. OK, I understand that.
But then in your 2nd example number, 13500, you don't want it to give
a result of 8, even though 13500 is between 10201 and 14000.
OK, so I'm starting to guess that maybe you view the tables as Pairs of
numbers. In other words, 1800 and 2001 are a pair. Then 3500 and 4001
are the next pair, and so on. You actually want to know if the "freq" is
within any of these pairs. If not, then return 0. If so, then return the
index (0 based) of the higher number in the pair.
See if this works:
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
int16 const freq_table[18]= { 1800,2001, 3500,4001, 7000,7351,
10100,10201, 14000,14351, 18068,18169,
21000,21451, 24890,24991, 28000,29701};
int8 lookdown(int16 freq)
{
int i;
int8 retval;
int16 lower;
int16 upper;
retval = 0;
for(i = 0; i < sizeof(freq_table)/2; i+=2) // Test each pair
{
lower = freq_table[i]; // Get lower value of current pair
upper = freq_table[i+1]; // Get upper value of current pair
if(freq >= lower && freq <= upper) // Check if freq is in range
{
retval = i+1; // If so, return index of upper pair
break;
}
}
return(retval);
}
//==========================================
void main()
{
int8 result;
result = lookdown(1800);
printf("1800 gives result of: %u \r", result);
result = lookdown(2000);
printf("2000 gives result of: %u \r", result);
result = lookdown(2001);
printf("2001 gives result of: %u \r", result);
result = lookdown(29000);
printf("29000 gives result of: %u \r", result);
result = lookdown(30000);
printf("30000 gives result of: %u \r", result);
while(1);
} |
|
|
|
wgalaugher
Joined: 10 Jan 2011 Posts: 18
|
|
Posted: Fri Aug 19, 2011 8:29 pm |
|
|
Your interpretation of the problem works perfectlly. I have wrestled with this for some time. It's nice to see the logic work. Basically, this is a universal band switch determined by frequency. |
|
|
|
|
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
|