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

PIC24FJ128GA308 ADC Input Scan

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



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PIC24FJ128GA308 ADC Input Scan
PostPosted: Wed Mar 10, 2021 6:44 am     Reply with quote

Hello,

I need some help setting up the PIC24FJ128GA308 to scan specific ADC inputs and interrupt when all results are available.

Trigger could be Timer1 for example.

Is this supported in CCS?

Thanks.
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Mar 10, 2021 7:23 am     Reply with quote

The automated scan on that ADC, is a 'Threshold scan'. It is designed to
compare signals with levels and interrupt when thresholds are met.
I think you would be simpler and better, to just use DMA. The DMA supports
sequencing through ADC channels. You can specify this to interrupt when a
certain number of reading have been done, so you can set it up to give you
(for example) 8 sets of readings from 4 selected ADC channels, and when
you get the interrupt the buffer will have these all neatly stacked in order.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Wed Mar 10, 2021 7:33 am     Reply with quote

Ttelmah,

Thanks for the reply.
Is there any example available?

I already have it working with read_adc();
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Mar 10, 2021 8:56 am     Reply with quote

I posted a 'ongoing' code a while ago for this.
Turns out you have to tell the PIC to read from a different register to what
the data sheet actually says for the chip I was using. You can see the note at
the end for the fix for this. Your chip may be OK without this.

[url]
http://www.ccsinfo.com/forum/viewtopic.php?t=56913&highlight=adc+dma
[/url]

Another poster was doing it on a chip without this problem, his code is here:

[url]
http://www.ccsinfo.com/forum/viewtopic.php?t=47875&highlight=dma+adc
[/url]
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Mar 11, 2021 1:11 am     Reply with quote

This is a little urgent and I cannot afford trial and error.
For now I will read each channel one by one and maybe come back to DMA later in the project.

I was hoping for a more "ready" example.

Thanks for the support as always Smile
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Mar 11, 2021 1:24 am     Reply with quote

Except for the need to change the ADC channel setup to suit your project,
and possibly needing to use the different register to get the scanning to
give the right sequencing (which is probably specific to the chip I was
using), what I posted is a ready to go example.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Mar 11, 2021 1:48 am     Reply with quote

OK, this just prints once to the terminal and stops.
The value is 0 though.
I changed AD1CSS to suit my channels.

Any ideas?


Code:

int1 DMA_complete; // Flag to test if DMA interupt has been serviced.
#define BUFFER_SIZE 8  //DMA BUFFER Size

#BANK_DMA
unsigned int DMA_BUFFER[BUFFER_SIZE];

//This interrupt gets triggered after 8 DMA transfers(DMACOUNT) are complete
#INT_DMA0
void DMA0_ISR(void)
{
   DMA_complete = TRUE;
}

#BIT DMABM=getenv("BIT:DMABM")
#BIT DMAEN=getenv("BIT:DMAEN")
#BIT ASEN=getenv("BIT:ASEN")
#BIT BUFM=getenv("BIT:BUFM")
#BIT ADON=getenv("BIT:ADON")
#BIT ASAM=getenv("BIT:ASAM")
#BIT CSCNA=getenv("BIT:CSCNA")
#BIT ALTS=getenv("BIT:ALTS")
#BIT PUMPEN=getenv("BIT:PUMPEN")
#BIT BUFREGEN=getenv("BIT:BUFREGEN")
#WORD AD1CON1=getenv("SFR:AD1CON1")
#WORD AD1CON2=getenv("SFR:AD1CON2")
#WORD AD1CON3=getenv("SFR:AD1CON3")
#WORD AD1CON4=getenv("SFR:AD1CON4")
#WORD AD1CON5=getenv("SFR:AD1CON5")
#WORD AD1CSS=getenv("SFR:AD1CSSL")
#WORD AD1CSSH=getenv("SFR:AD1CSSH")
#WORD ADC1BUF0=getenv("SFR:ADC1BUF0")
#WORD ADC1BUF=getenv("SFR:ADC1BUF0")





Code:

void launch_dma(void){

   SETUP_ADC(ADC_CLOCK_INTERNAL);
   SETUP_ADC_PORTS(sAN0 | sAN1 | sAN2 | sAN3 | sAN6 | sAN7 | sAN14 | sAN15 | VSS_VDD);


   //Now need to tweak the ADC settings. Must set the individual enable
   //bits for the three channels required, and set the mode to automatically
   //scan the channels
   //Need to disable ADC before configuring
   ADON=FALSE;
   DMAEN=FALSE; //extended features off
   DMABM=FALSE; //default mode
   AD1CSS=0b1100000011001111;
   AD1CSSH=0; //No other channels used
   ASEN=FALSE; //turn off the threshold detect scan
   ALTS=FALSE; //single MUX
   CSCNA=TRUE; //continuous scan of selected channels
   BUFM=TRUE; //This should each read back to ADC1BUF0
   PUMPEN=FALSE; //disable charge pump (AVdd=3.3v)
   AD1CON2 &= 0xFF83; //SMPI=0000 forces interrupt/DMA on every sample
   //trying note from download setting 3 instead - no change
   //AD1CON2 |= 0x0080; //every third?
   BUFREGEN=FALSE; //All I/O through ADC1BUF0
   ASAM=TRUE; //automatic sample timing
   AD1CON5 &= 0xFCF3; //ensure ASINT is disabled and WM=00
   AD1CON1 = (AD1CON1 & 0xFF0F) | 0x0070; //SSRC=0111, selects Autoconvert mode

   //Now enable the ADC again
   ADON=TRUE;
   //set_adc_channel(1); //select 1 as first channel
   
   DMA_complete = FALSE;
   
   setup_dma(0, DMA_TRIGGER_ADC1, DMA_WORD);
   
   dma_start(0, DMA_CONTINUOUS | DMA_INC_DEST_ADDR | DMA_SOURCE_ADDR_UNCHANGED , DMA_BUFFER , &ADC1BUF, 8); //DMA_INC_DEST_ADDR |
   enable_interrupts(INT_DMA0);  //dma will now depend on ADC
   //Now triggering a read_adc, should force the buffer to fill with 8 samples
   read_adc(ADC_START_ONLY);

   while(1){
    if (DMA_complete){
     //here I process the results, then retrigger
     DMA_complete=FALSE;
     fprintf(USB,"\n\rADC1:%u",DMA_BUFFER[0]);
     read_adc(ADC_START_ONLY); //retrigger DMA       
    }   
   delay_ms(50);
  }
}

_________________
George.
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