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 CCS Technical Support

reading ADC
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

reading ADC
PostPosted: Wed Aug 29, 2007 11:29 am     Reply with quote

I'm using a pic18f452.
I can send it serial commands or I2C commands and everything works great until I start calling the function below.
Code:

void read_analog()
{
    int channel;
    int16 value;
    for(channel=0;channel<=5;channel++)
    {
        set_adc_channel(channel);
//        delay_us(600);
        value = Read_ADC();
        analog_array[channel] = value;
    }
}


I'm setting up the port like this
setup_adc_ports(AN0_AN1_AN2_AN3_AN4_AN5);
setup_adc( ADC_CLOCK_INTERNAL );


It works as above, but if I uncomment the line delay_us(600); then the I2C and serial comms work about 10% of the time. I've tried different delays and they all act the same. It seems from a long time ago I remember that you should have a delay from switching channels to reading the ADC (for accuracy), that is why I put in that line.

So 2 questions,
1) do I need a delay?
2) why would the delay hose my comms?

Thanks
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 11:42 am     Reply with quote

Do you have an interrupt routine that calls delay_us() ?
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 11:47 am     Reply with quote

no, I only use delay_us in 2 functions, this one and one other that runs after this one returns. I dont have delay_us or delay_ms in any ints at all.
_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 12:17 pm     Reply with quote

It looks like it is a compiler version problem. I'm using a different IDE and still had this one set to use the 4.x compiler. When I compiled with 3.249 the problem appears to have gone away.

I need to delete the 4.x crap, it has caused me pain before.
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 12:18 pm     Reply with quote

My thought was that interrupts were being disabled, due to calling the
delay routine in an isr and outside the isr. If you have Warnings enabled
the compiler will tell you if it's doing this.

According to the 18F452 data sheet the minimum required acquisition
time for the A/D is 12.86 us. So instead of 600 us, try this:
Code:
delay_us(15);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 12:19 pm     Reply with quote

I didn't see you other post about the 4.x compiler when I made the
post above. Are you still using 4.013 or something like that, as I recall ?
Definitely get rid of that early version. Just delete it.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 2:33 pm     Reply with quote

I lied about the version being the problem. It does it less often with 3.249, but still does it. Here is the entire program. As soon as I uncomment the line read_analog, it starts hanging. I'm also blinking an led in main now and that stops so the whole program is hung. I had a similar issue before and PCM programmer found a pointer I was not initializing. I'm only using 1 pointer in here and I made sure it was this time. I also have "errors" in my use232 statement. There must be something I'm missing here causing it to hang but I'm not sure how to find it.
Any ideas will be greatly appreciated.
Thanks
Ringo


Code:

...

_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 2:46 pm     Reply with quote

That code doesn't compile. It's missing some routines in utilities.c.
Also, you've still got the delay_us(600) in there, even though I said to
reduce it to delay_us(15).
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 2:50 pm     Reply with quote

oops, sory about utilities.c
I put the code in the main program. I changed the delay to 15us, but after I had posted last time.
Here is the complete code.
Code:

...

_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 2:56 pm     Reply with quote

I added this code

printf("entering read_analog\r\n");
Read_analog();
printf("out of read_analog\r\n");

and when it locks up the last thing it prints is "entering read_analog" so it must be hanging reading the adc.
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 3:07 pm     Reply with quote

1. Comment out the lines in read_analog(), one at a time, in order to
find out which line is causing the problem.

2. Post the version of the PCH compiler that you're using.

3. Get rid of the delay for 600 us and change it to 15 us, and try it,
and tell if it fixes the problem.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 3:15 pm     Reply with quote

CCS PCH C Compiler, Version 3.249, 34836

This works
Code:

void read_analog()
{
    int channel;
    int16 value;
    for(channel=0;channel<=5;channel++)
    {
        set_adc_channel(channel);
        delay_us(15);
  //      value = Read_ADC();
        analog_array[channel] = value;
    }
}

This does not
Code:

void read_analog()
{
    int channel;
    int16 value;
    for(channel=0;channel<=5;channel++)
    {
        set_adc_channel(channel);
        delay_us(15);
        value = Read_ADC();
        analog_array[channel] = value;
    }
}

_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 3:30 pm     Reply with quote

Make a small test program that only tests the ADC, and see if it works.

Code:
#include <18F452.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=20000000) 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

//=================================
void main()
{
int16 result;

setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(15);

while(1)
  { 
   result = read_adc();
   printf("%LX ", result);
   delay_ms(500);
  }

}
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 3:39 pm     Reply with quote

This runs fine

Code:

#include "18F452.h"
#fuses hs,nowdt,noprotect,put,nolvp
#device *=16
#device adc=10
#device HIGH_INTS=TRUE
#use delay(clock=20000000)
#use rs232(baud=19200,xmit=PIN_C6,rcv=PIN_c7,errors,bits=8,parity=N)

//=================================
void main()
{
int16 value;
int channel;
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(15);

    while(1)
    { 
        for(channel=0;channel<=5;channel++)
        {
            set_adc_channel(channel);
            delay_us(15);
            value = Read_ADC();
            printf("Channel %d value = %LX \r\n", channel,value);
            delay_ms(50);
        }
    }
}

_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Wed Aug 29, 2007 3:49 pm     Reply with quote

This code seems to be working
Code:

    for(channel=0;channel<=5;channel++)
    {
        printf("setting--");
        set_adc_channel(channel);
        delay_us(15);
        value = 42*channel;
        printf("reading--");
        value = Read_ADC();
        printf("storing--");
        analog_array[channel] = value;
    }


which makes me wonder if I need a delay after reading before going to another channel. I'm going to try that next.
_________________
Ringo Davis
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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