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

Expression must evaluate to a constant

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



Joined: 26 Aug 2009
Posts: 3

View user's profile Send private message

Expression must evaluate to a constant
PostPosted: Mon Jul 06, 2015 2:38 am     Reply with quote

Please help me. When i compile the below coding, the error was shown like "Expression must evaluate to a constant".
Code:

#include <18F2331.h>
#device ADC=10
#use delay(crystal=20000000)
int32 tot_val=0;
int16 avg,value=0;
CONST byte ACH = 0, BCH = 3;
float current;
average_ad(int8 chan)
{
int i,j;
while(i<31)
{
set_adc_channel(chan);
delay_us(20);
value=read_adc();
j++;
tot_val+=value;
i++;
}
if(j==31)
{
avg=tot_val>>5;
tot_val=0;
j=0;
i=0;
}
return(avg);
}

void main()
{
while(TRUE)
{
current = average_ad(ACH)/4.5;
}
}

ERROR Msg:

*** Error 27 "xxx.c" Line 21(26,30): Expression must evaluate to a constant ::
1 Errors, 0 Warnings.
Build Failed.

But,
I use 16f873A instead of 18F2331 controller. The error was not shown like "Expression must evaluate to a constant " Why this is happening? Please give me the solution. (Sorry for my English)
Code:
 
#include <16F873a.h>
#device ADC=10
#use delay(crystal=20000000)
int32 tot_val=0;
int16 avg,value=0;
CONST byte ACH = 0, BCH = 3;
float current;
average_ad(int8 chan)
{
int i,j;
while(i<31)
{
set_adc_channel(chan);
delay_us(20);
value=read_adc();
j++;
tot_val+=value;
i++;
}
if(j==31)
{
avg=tot_val>>5;
tot_val=0;
j=0;
i=0;
}
return(avg);
}

void main()
{
while(TRUE)
{
current = average_ad(ACH)/4.5;
}
}


Please help me... This is very urgent.... i cont reach my target because of this error...

alan



Joined: 12 Nov 2012
Posts: 297
Location: South Africa

View user's profile Send private message

PostPosted: Wed Jul 08, 2015 1:05 am     Reply with quote

Try defining what your function must return.

Change
Code:
 average_ad(int8 chan)

to
Code:
 int16 average_ad(int8 chan)


Regards
senthilkumar03



Joined: 26 Aug 2009
Posts: 3

View user's profile Send private message

PostPosted: Wed Jul 08, 2015 1:34 am     Reply with quote

I tried , whatever you suggest. but i got the same error. even i use " float average_ad(int8 chan) " this problem is not rectified... Please give me the solution.....................
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: Expression must evaluate to a constant
PostPosted: Wed Jul 08, 2015 2:39 am     Reply with quote

senthilkumar03 wrote:
Please help me. When i compile the below coding, the error was shown like "Expression must evaluate to a constant".
Code:

#include <18F2331.h>
#device ADC=10
#use delay(crystal=20000000)
int32 tot_val=0;
int16 avg,value=0;
CONST byte ACH = 0, BCH = 3;
float current;
average_ad(int8 chan)
{
   int i,j;
   while(i<31)
   {
      set_adc_channel(chan);
      delay_us(20);
      value=read_adc();
      j++;
      tot_val+=value;
      i++;
   }
   if(j==31)
   {
      avg=tot_val>>5;
      tot_val=0;
      j=0;
      i=0;
   }
   return(avg);
}

void main()
{
   while(TRUE)
   {
      current = average_ad(ACH)/4.5;
   }
}

ERROR Msg:

*** Error 27 "xxx.c" Line 21(26,30): Expression must evaluate to a constant ::

Please help me... This is very urgent.... i cont reach my target because of this error...


I reformatted the code and stuck it in my CCS IDE. I got the same error. It is saying that something that is variable should be constant. The message is a little cryptic about where the problem is, but the IDE takes me straight to the set_adc_channel(chan) line. Its saying it wants chan to be constant. Though you give it a constant as a parameter to the routine, in fact from the compiler's point of view, chan is a variable.

How to fix it? If I put a constant in place of chan in the set_adc_channel() call, then the problem goes away.

All that is understandable and pretty straightforward. The error message is telling you what's wrong, though granted, its not clear exactly where the problem is. The trouble is that normally there's no problem in having a variable in set_adc_channel(). I do it all the time, never had an issue with it. I changed the PIC type to 18F4680 and it worked fine. It makes me think that maybe there's something different about how the ADC is implemented on the 18F2331 and other simpilar PICs. Or maybe that the compiler does something different.

My conclusion is that the error itself is straightforward enough and was trivial to find and easy enough to fix, but is that it is possibly caused by a PIC-specific compiler bug. I'd submit a bug report to CCS and see what they say if I were you.

PS: Two other problems:

Code:

int32 tot_val=0;    // This is only set here, so will not be correct if average_ad is called more than once.
int16 avg,value=0; // Avoid declarations like this, it makes it look like both avg and value are being set to 0 when in fact only value is being set.


and yes, you should specify the type of the return value, in this case int16, as otherwise it will default to int.
ezflyr



Joined: 25 Oct 2010
Posts: 1012
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Thu Jul 09, 2015 8:12 am     Reply with quote

Hi All,

This thread is a classic example of why posting the compiler version number is essential. As a community, I think we should insist that *every* request for help include the version number. If the version number is not posted, then the 1st reply in the thread should always be "I'm sorry, we can't help you until you post your version number......" This has been covered so many times before, but still it's ignored......

At my company, we've invested thousands of hours, and more $$ than I want to think about, on software development. So, it makes no sense to spend a lot of additional time chasing down old issues and bugs that have been solved long ago..... Now, the 1st question we ask when we receive a software related question is "What version are you running......"

John
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Jul 09, 2015 8:40 am     Reply with quote

ezflyr wrote:

This thread is a classic example of why posting the compiler version number is essential.


Well, yes, posting compiler/IDE version is important, this doesn't appear to be a compiler version related problem, and wasn't solved "ages ago". I tested it on 5.046, and got the same results as reported by the original poster. Instead, it appears to be a PIC type related issue: happens with some PICs only, at least with recent (5.046), and presumably current, compiler issues. In this case, PIC type is the critical bit, not compiler issue.
ezflyr



Joined: 25 Oct 2010
Posts: 1012
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Thu Jul 09, 2015 10:53 am     Reply with quote

RF,

Well, it seems that you've entirely missed the salient point of my post - that posters should *always* tell us their version number when asking for help..... Parsing my reply to find the 1% instance where the version number *may* not be required does nothing but embolden those who neglect to post their version number. Posting the version number is so easy to do, and it's (probably) required information more often than not, so what's the justification to not do so? Arguing this point is just a pissing contest, pure and simple......

John
Ttelmah



Joined: 11 Mar 2010
Posts: 14997

View user's profile Send private message

PostPosted: Thu Jul 09, 2015 11:05 am     Reply with quote

Agreed 90%, but this particular problem should not apply to any compiler version, and does to the current compiler. CCS appear to have coded the set_adc_channel function differently from the manual, for some chips.
The first thing that needs to happen is to point this out to them, that for some reason, on some chips, this function is only accepting constants.

It needs to be fixed.

It is possible to code a bodge round, if I have a few minutes tomorrow, I'll try to code one.
guy



Joined: 21 Oct 2005
Posts: 280

View user's profile Send private message Visit poster's website

PostPosted: Fri Jul 10, 2015 2:20 am     Reply with quote

Quote:
the compiler version number is essential. As a community, I think we should insist that *every* request for help include the version number.

I do this with my clients and still they don't bother. So I just let go Laughing
guy



Joined: 21 Oct 2005
Posts: 280

View user's profile Send private message Visit poster's website

PostPosted: Fri Jul 10, 2015 2:22 am     Reply with quote

did anyone notice that setup_adc is missing in the code???
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Jul 10, 2015 2:54 am     Reply with quote

guy wrote:
did anyone notice that setup_adc is missing in the code???


I didn't... and setup_adc_ports(). Maybe it acts as a hint to the compiler as to what values are acceptable to select_adc_channel() on some PICs. So, I put:
Code:

   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_DIV_32);

into main(). It made no difference.

And I looked at the top ten threads, not one has a compiler version, yet we help them. So why make a stand here on this thread, and not elsewhere? Why jump down my throat for offering help when the issue is surely with the original poster? In a year or so time this issue will have become compiler issue related, but as is stands it isn't, or doesn't appear to be.

We have the same problem where I work. We have a returns form that has to be filled in by customers and service agents before we're meant to issue an RMA number. How many have been filled out? Three. I have to confess that we do an order of magnitude more repairs than than. I'd love to enforce a "no form, no repair" policy, and I have said so, but it simply isn't going to happen in the real world.

I find it somewhat perverse to suggest in a self-help forum that we should adopt what I see as a jobs-worth attitude: not helping on priniciple because they didn't give the compiler version. I also find it odd that this issue, rather than any, or in effect all others, should be the one to suffer for it.
Ttelmah



Joined: 11 Mar 2010
Posts: 14997

View user's profile Send private message

PostPosted: Fri Jul 10, 2015 3:26 am     Reply with quote

Yes, and the multiplexer is also not setup.
The code won't actually 'work'.....

On the original 'constant' problem, this is because the chip has the ability to work with single or multiple 'groups' of channels, and sample multiple channels automatically from the separate groups. So unlike most chips where you just write the channel number to the 'select' register, here you have to change which group the converter is using. according to what channel is selected. So actually re-configure the ADC itself....

Now, obviously the simplest way if only two channels are to be used, is to simply have a flag, and do a test in the reading code:
Code:

#include <18F2331.h>
#device ADC=10
#use delay(crystal=20000000)

#define ACH 0
#define BCH 3

int16 average_ad(int8 chan)
{
   int i;
   int32 tot_val=0; //this needs to be zeroed....
   if (chan==ACH)
       set_adc_channel(ACH); //set this once
   else
       set_adc_channel(BCH);
   for (i=0;i<31;i++)
   {
      delay_us(20);
      tot_val += read_adc();
   }
   return(tot_val/32);
}

void main()
{
   float current;
   setup_adc(ADC_CLOCK_DIV_16);
   setup_adc_ports(ALL_ANALOG); //or whichever channels needed

   while(TRUE)
   {
      current = average_ad(ACH)/4.5;
   }
}


However a 'set_adc_chan' (to replace set_adc_channel), for this chip is going to be something like:
Code:

#byte ADCHS=getenv("SFR:ADCHS")
struct {
   int8 adon:1;
   int8 go:1;
   int8 acm:2;
   int8 acsch:1;
   int8 aconv:1;
} ADCON0;
#byte ADCON0=getenv("SFR:ADCON0")

void set_adc_chan(int8 chan)
{
   int8 mask1, mask2;
   int8 ctr=0;
   mask1=chan%4;
   mask2=(chan/4)&3;
   while (ctr++<=mask1)
   {
      shift_left(&mask2,1,0);
      shift_left(&mask2,1,0); //Shift twice for each count
   }   
   //stop the adc
   ADCON0.adon=FALSE;
   ADCHS=mask2; //put the channel selection into ADCHS
   ADCON0.acm=mask1; //select the required group
   ADCON0.adon=TRUE; //and re-enable the ADC
}


I haven't even compiled it, but the point is that you have to take the bits 2, & 3 of the channel number, and put these into bits 0:1, 2:3, 4:5, or 6:7, according to the value of the bottom two bits of the channel number. These locations correspond to groups A to D. Then select which of these groups to use in the ADCON register. Ouch. No wonder CCS elected to go 'constant'. What they should have done, was warned that this was the case.
senthilkumar03



Joined: 26 Aug 2009
Posts: 3

View user's profile Send private message

PostPosted: Fri Jul 10, 2015 11:02 pm     Reply with quote

Compiler version is 5.036
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