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

PIC24F08KA101 ADC CH SEL problem

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



Joined: 26 Jul 2011
Posts: 4

View user's profile Send private message

PIC24F08KA101 ADC CH SEL problem
PostPosted: Tue Jul 26, 2011 5:06 pm     Reply with quote

I'm trying to use AN0 and AN1. When I call "set_adc_channel(0)" nothing happens, but the AN0 input is correctly digitized with a "set_adc_channel(1)" call. I cannot access AN1 at all. From the disassembly listing, the various ADC registers appear to be correctly set---I've tried different ways to set them but the problem persists. Similar code worked fine with the PIC18F4455. The spec errata mentions "silicon" problems with these pins---is this another manifestation?
_________________
ab
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Tue Jul 26, 2011 6:37 pm     Reply with quote

Post a small compilable example with your version of PCD so we can compile it too and check the assembly.

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
ALEKANELENO



Joined: 26 Jul 2011
Posts: 4

View user's profile Send private message

PostPosted: Wed Jul 27, 2011 9:47 am     Reply with quote

Sorry for the delay...had to cut this down to bare bones and check if problem persisted.
Code:

#include <24F08KA101.h>
#DEVICE ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FRC_PLL                  //Internal osc + PLL               
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES NOPR                     //Pimary oscillator disabled
#FUSES OSCIO                    //OSC2 is general purpose output         
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES PUT                      //Power Up Timer
#FUSES BORV_MID             
#FUSES MCLR                     //Master Clear pin enabled
#FUSES ICSP3                    //ICD uses PGC3/PGD3 pins       
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD

#DEFINE sAN0 0
#DEFINE sAN0 1
//#DEFINE SPI_CLK_DIV_4 0x001E

#use delay(int=32M)
#use fast_io(A)
#use fast_io(B)

//Software SPI for DAC write  MASTER
#use spi(STREAM=DAC_WR,DO=PIN_B8,CLK=PIN_B9,ENABLE=PIN_A6,ENABLE_ACTIVE=0,SAMPLE_RISE,BITS=16)

void Lev_Disp(signed int16);
#INLINE void DAC4912_WR(int16);

int16    i,tgl,idat,odat,odtt,ocfgA,ocfgB;
int1    dacgA,dacgB;
signed int16 levA,levB;

int16   AD1CON1,AD1CON2,AD1CON3,AD1CHS,AD1PCFG,AD1CSSL;
#locate AD1CON1=0x0320
#locate AD1CON2=0x0322
#locate AD1CON3=0x0324
#locate AD1CHS=0x0328
#locate AD1PCFG=0x032C
#locate AD1CSSL=0x0330

void Lev_Disp(signed int16 amp)
{
   Output_Bit(PIN_B0,0);
   Output_Bit(PIN_B1,0);
   Output_Bit(PIN_B2,0);
   if(amp>255) Output_Bit(PIN_B0,1);
   if(amp>127) Output_Bit(PIN_B1,1);
   if(amp>63)  Output_Bit(PIN_B2,1);
return;
}

void DAC4912_WR(int16 config)
{
      int16 wrdata;
      wrdata = config | odat<<2;
      spi_xfer(DAC_WR,wrdata,16);
   Output_Bit(PIN_B7,0);         // load DAC
   Delay_Cycles(1);
   Output_Bit(PIN_B7,1);
return;
}

void main()
{
   set_tris_A(0x0000);
   set_tris_B(0x4010);
//  setup_spi(SPI_Slave|SPI_CLK_DIV_4);          // hardware SPI  (8 MHz)
//  setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_8);   // Tad = 125 ns, 750 ns acq delay
   AD1CON3 = 0x0601;                     // ADC_TAD_MUL_6
   AD1CON1 = 0x80E0;
//   setup_adc_ports(sAN0|sAN1);
   AD1PCFG = 0xFFFC;
   AD1CSSL = 0;
   AD1CON2 = 0;
    setup_wdt(WDT_OFF);
    setup_timer1(TMR_INTERNAL|TMR_DIV_BY_1);     // 62.5 ns/count
    setup_timer2(TMR_DISABLED);
    setup_timer3(TMR_DISABLED);

    set_adc_channel(0);
            
    ocfgA  =  0x3000;       // DAC A config preset (A/UNBUF/X1/ACTIVE)
    ocfgB  =  0xB000;       // DAC B config preset (B/UNBUF/X1/ACTIVE)
   Output_Bit(PIN_B7,1);         // preset DAC load
   delay_ms(1000);
   tgl = 1;
   for(i=0;i<4096;i++)         // check level display and audio output
   {
      levA = i>>3;                  // 0<j<512
      Lev_Disp(levA);
      set_timer1(0);
      if(tgl) odat = 642;             // generate output square wave
      else    odat = 382;               // +- 130
      tgl = !tgl;                     // toggle output sign
      if(i<2048)   DAC4912_WR(ocfgA);      // CHA output
      else      DAC4912_WR(ocfgB);      // CHB output
      while(get_timer1()<5120);      // wait until loop time = 320 us
   }
   Output_Bit(PIN_B0,0);            // reset LEDs
   Output_Bit(PIN_B1,0);
   Output_Bit(PIN_B2,0);
   delay_ms(1000);

    i     =  0;                    // initialize loop things
   tgl   =  1;
                 
   while(1)                       // loop indefinitely
   {
         set_timer1(0);             // start loop timer @ 62.5 ns/count
      idat = read_adc();
//      idat = odtt;

      if(i%4==0)                // every 250 us (2 kHz)
      {
         if(tgl) odtt = 640;    // generate output square wave
         else    odtt = 384;      // for testing DAC
         tgl = !tgl;            // toggle output sign
      }
      
      odat = idat;
      DAC4912_WR(0x3000);         // CHA output(A/UNBUF/X1/ACTIVE)
//      DAC4912_WR(0xB000);         // CHB output(B/UNBUF/X1/ACTIVE)
      levA = (signed)odat - 512;;
      Lev_Disp(levA);

        while(get_timer1()<1024);  // wait until accum loop time = 64 us (15625 Hz)
        i++;                       // increment delay loop counter
         if(i>63) i = 0;            // reset delay loop counter
   }                // END OF MAIN LOOP
}

_________________
ab
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Jul 27, 2011 10:20 am     Reply with quote

Well, that's not exactly as short as it can be, but one thing comes right off the top...

You're using RA0 and RA1...

And you're setting PORTA TRIS to 0x0000 which is all output.

Wouldn't 0x0003 be a better choice?

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
ALEKANELENO



Joined: 26 Jul 2011
Posts: 4

View user's profile Send private message

PostPosted: Wed Jul 27, 2011 11:00 am     Reply with quote

OK...just tried changing trisA to 0003...no effect...the data sheet says that AD1PCFG overrides anyway...the original code actually used the standard io (that had no effect either). Sorry about the length...this is the minimum code needed to operate the board. I forgot to mention that according to the "About" I'm running PCD v4.100...can't see any notation on the CD. Incidentally, my 24F08KA101.h is apparently missing some ADC and SPI defines. Thank you for your prompt help.
_________________
ab
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Jul 27, 2011 11:57 am     Reply with quote

Hmmm, I'm using 4.122

I also just realized, I don't see anywhere in your code a "set_adc_channel(1);"

However, keep in mind, you need a time delay after that to satisfy the ADC charge time...

AND, you need to satisfy the input impedance needs as well.

If you do not (or your soldering has an open on channel_1) then it's very possible to read the result of CH0 when reading CH1 because the S/H capacitor didn't get adjusted to the new value as you'd expect.

Check your circuit.
Check your soldering.
Get a meter/scope and verify you have something on AN1 that's different from AN0.

Maybe post your schematic so we can review that next. The LST output for set_adc_channel looks correct over here.

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
ALEKANELENO



Joined: 26 Jul 2011
Posts: 4

View user's profile Send private message

PostPosted: Wed Jul 27, 2011 3:28 pm     Reply with quote

"Hmmm, I'm using 4.122" Would that make any difference -- were the header problems fixed?

"set_adc_channel(0 OR 1);" is near the beginning, after the timer setup calls.

In this "bare-bones" code there's > 2s delay after the ADC channel is selected and the Auto-Sample delay bits are set to 6 (or 8) Tad (750-1000 ns). I cannot find a spec for setting channels wait time (so I typically put some code in). The AN0 and AN1 pins are driven directly from an op-amp (very low Zout).

Bingo! Per your suggestion I scoped the inputs and tried a couple of different boards -- and discovered CHA and CHB were reversed on the board!

After making the appropriate code changes it all works as expected. I had the sneaky feeling that the solution was staring me in the face.

Thank you very much.

Incidentally, I noticed an oddity in the disassembly listing -- "setup_adc_ports(sAN0|sAN1)" produces (among the expected stuff) a "setm.w 0x032a" instruction. But 0x032a is not a register I can find listed (in the PIC24F16KA102 Family Data Sheet). Also, the PIC24F Family Reference Manual says to set AD1CSSL (0x0330) to zero in this instance. However, none of this makes any difference.

Best regards,
_________________
ab
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Jul 27, 2011 4:24 pm     Reply with quote

ALEKANELENO wrote:

Bingo! Per your suggestion I scoped the inputs and tried a couple of different boards -- and discovered CHA and CHB were reversed on the board!


Oops! Glad you found it though.

Quote:

Incidentally, I noticed an oddity in the disassembly listing -- "setup_adc_ports(sAN0|sAN1)" produces (among the expected stuff) a "setm.w 0x032a" instruction. But 0x032a is not a register I can find listed (in the PIC24F16KA102 Family Data Sheet). Also, the PIC24F Family Reference Manual says to set AD1CSSL (0x0330) to zero in this instance. However, none of this makes any difference.


Report it if you think it's an error. (I didn't look, so I can't agree in that sense.)

Cheers,

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Jul 28, 2011 12:05 am     Reply with quote

Quote:
"setup_adc_ports(sAN0|sAN1)" produces (among the expected stuff) a "setm.w 0x032a" instruction

You are talking about a bug in an old version. It has been fixed since long.
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