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

dsPIC33 ADCON1 FORM 00

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



Joined: 06 May 2013
Posts: 33
Location: Toronto

View user's profile Send private message

dsPIC33 ADCON1 FORM 00
PostPosted: Fri Sep 01, 2017 8:25 am     Reply with quote

Hi All,

I am using dsPIC33FJ256GP710A with CCS v5.074. I am trying to setup ADC FORM as integer. I looked into the manual and in header file to set FORM as integer but couldn't find it. If anybody knows please let me know.

Code:
void main()
{
    unsigned int16 x = 0;
    pwm_set_duty_percent(250);
    setup_adc_ports(sAN5, VSS_VDD);
    setup_adc(ADC_CLOCK_INTERNAL);
    set_adc_channel (5);
   

    while(1)
    {
        x= read_adc();
        if(x > 500)
            output_high(GREEN_LED);
        else
            output_low(GREEN_LED);
     
    }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Sep 01, 2017 8:45 am     Reply with quote

I'm sorry, but you are very unclear about what you mean....

The value from the ADC is always an integer.

How big, is controlled by the device statement (#device ADC=12).

There is nothing in the chip called 'ADC FORM', nor in CCS.

Look at the examples using the ADC.

You mean the data format I suspect....

It always defaults to unsigned, _unless you select a second -ve channel_.
tripper269



Joined: 06 May 2013
Posts: 33
Location: Toronto

View user's profile Send private message

ADC FORM
PostPosted: Fri Sep 01, 2017 8:51 am     Reply with quote

ADxCON1 bits 9:8 called FORM, which sets the data format into 16 bits signed fractional, fractional, signed integer and integer. Its on dsPIC33FJxxxGPx06A/08A/10A manual page 241. In CCS debug mode, you can see FORM as well.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Sep 01, 2017 9:18 am     Reply with quote

The description of them though is the format bits.
You can only have a signed output, when you are running the chip with differential inputs:
Code:

#include "33FJ256GP710a.h"
#device ADC=12
//Then suitable clocks etc.

void main()
{
   unsigned int16 x = 0;
   setup_adc_ports(sAN5, VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_4);
   set_adc_channel (5);

   while(TRUE)
   { 
   
   x= read_adc();
   if(x > 500)
      output_high(PIN_G0);
   else
      output_low(PIN_G0);

   }
}

Since you are acquiring 'without pause', you need some acquisition time programmed. If you then look at the listing:

Code:

0022A:  MOV     #84E0,W4
0022C:  MOV     W4,320


Which is selecting 12bit, unsigned 1000 0100 in byte 321.

#device ADC=signed

With a second channel selected, sets the chip up to deliver a signed result
tripper269



Joined: 06 May 2013
Posts: 33
Location: Toronto

View user's profile Send private message

PostPosted: Tue Sep 05, 2017 7:46 am     Reply with quote

Thanks Ttelmah,

You are right, i need a fixed sampling rate. I am trying to use timer with ADC to get fixed sampling rate. I know how to configure timer interrupt, for example to blink a LED. But how to configure it with ADC, i am still confused. Should I turn on the ADC in timer interrupt or once its configured, it will automatically start sampling at fixed intervals ??
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Sep 05, 2017 8:03 am     Reply with quote

You are using the wrong timer.... Smile

The ADC on your chip can be programmed to start automatically triggered by a timer. Timer5 or Timer3 for ADC1.
What you do is program the timer, setup the ADC to automatically start when the timer tells it to, and then enable INT_ADC1. When you receive this interrupt, you use read_adc(ADC_READ_ONLY), which just reads the result from the conversion that has already been done (so is very quick), and exit the interrupt. When the timer next triggers the same happens again.
Code:

#byte ADCON1L=getenv("SFR:ADCON1")
#define TRIGGER_FROM_TIMER5 0x80
#define TRIGGER_FROM_TIMER3 0x40

     //setup the ADC for the conversion etc. as required.
     //Then TIMER5 for the interval required
     //Then:
     ADCON1L = (ADCON1L & 0x1F) | TRIGGER_FROM_TIMER5;

     //Will set the ADC up to automatically start when Timer5 resets

Alternatively setup timer3, and select this as the trigger source.
tripper269



Joined: 06 May 2013
Posts: 33
Location: Toronto

View user's profile Send private message

PostPosted: Tue Sep 05, 2017 3:06 pm     Reply with quote

I think its #word ADCON1L=getenv("SFR:ADCON1"), not #byte. Also it changes the ADCON1 to 10000010000000. We can do the work around, but what is the use of CCS then. In header file, there are only limited options. Is there any way to configure ADC with timer using CCS inbuilt functions?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed Sep 06, 2017 12:45 am     Reply with quote

No. You can use #byte.

I only want to update the low byte of the word. Using #byte forces this to happen. If you use #word, you have to expand the mask to cover the high 8bits or it changes things you don't want...

Synchronous sampling, is more commonly done using DMA. CCS have options to set this up, but it is a more complex way to do the simple operation you describe.
They will add the define for you, if you ask CCS, but since it only involves a couple of lines as I show, it is as easy to do it yourself.

It has to be AD1CON1, but works with this change as posted. I was copying from a chip that only has a single ADC.
tripper269



Joined: 06 May 2013
Posts: 33
Location: Toronto

View user's profile Send private message

PostPosted: Wed Sep 06, 2017 9:33 am     Reply with quote

Thanks Ttelmah,

You are right. It's setting up all the registers correctly. Below is my code, and there is still something i am doing wrong. Your comments will be much appreciated.
Code:

#include <33FJ256GP710A.h>
#device ADC=12
#fuses HS,WDT
#use delay(clock = 8000000)

#byte ADCON1L=getenv("SFR:AD1CON1")
#define TRIGGER_FROM_TIMER5 0x80
#define TRIGGER_FROM_TIMER3 0x40
#define GREEN_LED PIN_A0

unsigned int16 x = 0;

#int_adc1

void adc1_isr()
{
    x = read_adc(ADC_READ_ONLY);
}


void main()
{
   setup_timer2(TMR_INTERNAL | TMR_DIV_BY_256, 1562);
   setup_compare(1, COMPARE_PWM | COMPARE_TIMER2);
   
   setup_adc_ports(sAN5, VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_8);
   ADCON1L = (ADCON1L & 0x1F) | TRIGGER_FROM_TIMER5;
   set_adc_channel (5);
   
   setup_timer5(TMR_INTERNAL | TMR_DIV_BY_1,15625);
   
   enable_interrupts(INT_ADC1);
   enable_interrupts(INTR_GLOBAL);
   set_timer5(0);

    while(1)
    {
        //x= read_adc();
        set_pwm_duty(1,x );
        if(x > 500)
            output_high(GREEN_LED);
        else
            output_low(GREEN_LED);
     
    }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Sep 07, 2017 1:18 am     Reply with quote

Try either adding a delay to the loop, or setting a flag in the interrupt routine, and only changing things when this is set. So:
Code:

unsigned int16 x = 0;
int1 have_reading=FALSE;

#int_adc1
void adc1_isr()
{
    x = read_adc(ADC_READ_ONLY);
    have_reading=TRUE;
}

//then in the main

    while(1)
    {
        if (have_reading)
        {
            have_reading=FALSE;
            set_pwm_duty(1,x );
            if(x > 500)
               output_high(GREEN_LED);
            else
               output_low(GREEN_LED);
        }
    }


Otherwise you are continuously updating the PWM duty with the same value.
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