View previous topic :: View next topic |
Author |
Message |
feitanx
Joined: 21 Mar 2010 Posts: 37
|
A numeric expression must appear here |
Posted: Thu May 20, 2010 8:10 am |
|
|
Why keep getting "numeric expression must appear" ?
Code: |
#include <16F877A.h>
#device *=16 ADC=8
#fuses XT,NOLVP,NOWDT,NOPROTECT,NOPUT
#use delay(clock=4000000)
#use rs232(uart1,baud=9600,xmit=PIN_C6,rcv=PIN_C7,stop=1,parity=N,bits=8)
#use fast_io(D)
void main(void)
{
int16 V1;
set_tris_d(0x00); // d all output
setup_adc(ADC_CLOCK_DIV_64);
setup_adc_ports(RA0_ANALOG);
for(;;)
{
set_adc_channel(0);
read_adc(adc_start_only);
V1=read_adc(ADC_START_ONLY);
output_d(V1);
delay_ms(1000);
}
} |
|
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu May 20, 2010 8:54 am |
|
|
Where ?
Please post the full compiler error.
I also think this : V1=read_adc(ADC_START_ONLY); should be
V1=read_adc(ADC_READ_ONLY);
And you need a delay, sleep or loop to check the completion flag between the start and a read of the ADC. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu May 20, 2010 3:32 pm |
|
|
I'm not sure if this is the issue but, you have defined V1 as int16 yet you are trying to output it to an 8bit port. Not sure if the compiler is complaining about that.
Ronald |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Thu May 20, 2010 4:00 pm |
|
|
Code: | set_adc_channel(0);
read_adc(adc_start_only);
V1=read_adc(ADC_START_ONLY); |
why do you call read_adc(); twice with no delay in between and the first time you don't save the value?
.... off the top of my head... but to me that looks weird. might want to take a look at it.
g. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri May 21, 2010 6:56 am |
|
|
The error is caused by the read_adc function not returning a value when you provide it with the parameter ADC_START_ONLY.
Change to: Quote: | read_adc(adc_start_only);
V1=read_adc(ADC_READ_ONLY); |
These two lines are the same as the shorter and easier to read: |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Fri May 21, 2010 7:04 am |
|
|
Because you have a 1 second delay in your routine you could improve the performance by:-
Code: |
set_adc_channel(0);
read_adc(ADC_START_ONLY);
delay_ms(10);
for(;;)
{
V1=read_adc(ADC_READ_ONLY);
read_adc(ADC_START_ONLY);
output_d(V1);
delay_ms(1000);
}
|
There is no need to keep calling set_adc_channel(0); as you are only using 1 channel.
Using V1=read_adc(); is good but it does the start and then waits for it to finish and does a read. During this time you could have done something else. It would have been better if they made it do a READ and then a START and still leave the delay up to you! |
|
|
feitanx
Joined: 21 Mar 2010 Posts: 37
|
|
Posted: Sat May 22, 2010 4:13 am |
|
|
What if I use multiple channel? |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon May 24, 2010 2:58 am |
|
|
Then you will need to switch channels within your loop.
Now, depending on how fast your loop runs, what your sampling rate needs to be and how long it takes I would proberbly do the following:-
Code: |
int8 state = 0;
set_adc_channel(0);
delay_ms(10);
for(;;)
{
switch(chan)
case 0:
V0 = read_adc(ADC_READ_ONLY);
set_adc_channel(1);
read_adc(ADC_START_ONLY);
chan++;
break;
case 1:
V1 = read_adc(ADC_READ_ONLY);
set_adc_channel(0);
read_adc(ADC_START_ONLY);
chan = 0;
break;
}
read_adc(ADC_START_ONLY);
output_d(V1);
delay_ms(1000);
}
|
or something like that |
|
|
|