How to Use ADCs in dspic30f and dspic33f

Updated on March 23, 2018
alikhan3 profile image

The author completed his final year engineering project with the dsPic micro-controllers, gaining extensive insight in these devices.

The dsPic devices offer a powerful ADC (Analogue to Digital Converter) module which can sample at speeds up to 1 Msps. It can be used in variety of different ways and modes to suite the needs of your project.

This tutorial is aimed at teaching the basics of A/D conversion modules to all those who are beginning their projects with the dsPics.

dsPic30f4011 micro-controller along-with its programmer.
dsPic30f4011 micro-controller along-with its programmer. | Source

How to Give Input to the ADC

The first step is to set up the required hardware to give input to the ADC.

Sampling a DC signal:

For initial testing you may use a potentiometer connected across a 5 V supply and give input to the ADC analogue pins directly.

Sampling an AC Signal with ADC:

To sample an AC signal (line voltages or currents), you will have to:

  1. Step down the signal to the required voltage level with the help of transformers.
  2. Level-shift the signal so that negative values below zero are shifted up. The ADCs in Pics are not able to sample negative signals.

This reference circuit design may help you with the level shifting circuits:

Sampling an AC signal with ADC. (Gain of Op-amp may be tuned through the variable resistor to achieve an output in the range of 0 - 5V, I however use a value of 2.7 kOhms in its place.)(Click to enlarge).
Sampling an AC signal with ADC. (Gain of Op-amp may be tuned through the variable resistor to achieve an output in the range of 0 - 5V, I however use a value of 2.7 kOhms in its place.)(Click to enlarge). | Source

Testing the ADC

After setting up the required code and hardware, their must be a way to test if the ADC is actually sampling correctly in the required way or not. Since you cannot peek inside the MCU to see if all things are going correctly, I suggest two ways:

  1. You can connect a debugger with the Pic like the one pictured above. In debug mode you can check the value in registers ADCBUF0 through 10 to see if they are being loaded with correctly sampled values.
  2. You can send the values of ADCBUF register thorough UART and monitor them on a PC with the help of serial monitor.

ADC Example Code for dsPic

#include "xc.h"

#define FCY 20000000
#define FPWM 3600

#include <xc.h>
#include <stdio.h>
#include <delay.h>
#include <libpic30.h>
#include <dsp.h>
#include <math.h>

_FOSC( CSW_FSCM_OFF & XT_PLL8 ); // External Oscillator, PLLx8
_FWDT( WDT_OFF );                // Watchdog timer off
_FBORPOR( MCLR_DIS );            // Disable reset

int ADCValue;

void init_ADC( void )
    TRISB = 0xFFFF;   //Set as Input Port
    ADPCFG = 0x0000;  //Selecting all analogue pins to analogue mode
    ADCHSbits.CH0SA = 1;
    ADCHSbits.CH0NA = 0;
    //ADCHSbits.CH123SA = 0;
    //ADCHSbits.CH123NA = 0;
    IEC0bits.ADIE = 1;       //Enable ADC Interrupt       
    IPC2bits.ADIP = 1;       //set interrupt priorty-6  
    ADCSSLbits.CSSL0 = 0;    //Skip input scan for analoge pin AN0,AN1,AN2
    ADCSSLbits.CSSL1 = 0;
    ADCSSLbits.CSSL2 = 0;
    ADCON3bits.SAMC = 0;     //Auto sample time 6TAD//max sample time
    ADCON3bits.ADRC = 0;     //selecting Conversion clock source derived from system clock
    ADCON3bits.ADCS = 9;     //Selecting conversion clock 6Tcy
    ADCON1bits.ADSIDL = 0;   //Selecting continue mode operation in idle mode
    ADCON1bits.FORM = 1;     //Selecting data output in signed integer format
    ADCON1bits.SSRC = 0;     //Selecting Motor Control PWM interval ends sampling and starts conversion
    ADCON1bits.SIMSAM = 0;   // Samples CH0, CH1, CH2, CH3 simultaneously 
    ADCON1bits.ASAM = 0;     //Selecting Sampling begins immediately after last conversion completes. SAMP bit is auto set
    ADCON1bits.SAMP = 0;     // At least one A/D sample/hold amplifier is sampling
    ADCON2bits.VCFG = 0;     //Voltage Reference Configuration bits
    ADCON2bits.CSCNA = 0;    //Disable input scan
    ADCON2bits.CHPS  = 0;    //Selecting conversion channel CH0
    ADCON2bits.SMPI = 0;     //Selecting 1 conversion sample per interrupt
    ADCON2bits.ALTS = 0;     //Uses MUX A input multiplexer settings
    ADCON2bits.BUFM = 0;     // Buffer configured as one 16-word buffer ADCBUF(15...0)
    ADCON1bits.ADON = 1;     //A/D converter is ON  
void readADC( )
    //ADCON1bits.SAMP = 1;  // start sampling, automatic conversion will follow
    //__delay_ms( 100 );
    ADCON1bits.SAMP = 0;        // start sampling, automatic conversion will follow
    while ( !ADCON1bits.DONE ); // wait to complete the conversion
    ADCValue = ADCBUF0;         // read the conversion result

void main( void ) 
    int data;
    while( 1 )
        data = ADCValue;      

Configuring the ADC Module

The ADC module may be initialized and configured with the help of the code given above. A step by step guide follows:

  • Steps 1 through 7 are essential. After 7 any or all of them may be skipped.

1) Set the Port as Input and in Analogue Mode

  1. Port B, on which the ADC input pins are present must be set as an input port. (line - 21).
  2. They must be set in the analogue input mode by the ADPCFG register. (line - 22).

2) Select Analogue Inputs for Sampling

Analogue inputs must be connected to an 'ADC channel' for sampling. There are usually more number of analogue inputs as compared to channels, for example: dsPic30f4011 has 09 analogue inputs but only 04 ADC channels. Therefore you must now select which analogue input pin is connected to which ADC channel. This is done with the help of ADCHS register.

  • Here AN1 is selected as the analogue pin input to channel 0. (line - 2).
  • Number of channels determine the number of simultaneous samples possible.
  • The controller can sample alternately between Mux A and Mux B.

Possible Configurations of ADCHS
Resulting Analouge Input Pin Configuaration
Code line
Channel 0 -> Mux A
Any anlouge pin from AN0 - AN8 can be selected to give input to channel 0 through Mux A.
ADCHSbits.CH0SA = 1; or any other number depending on pin
Channel 1, 2 and 3 -> Mux A
Channel 1 input is AN3, Channel 2 -> AN4, Channel 3 -> AN5
ADCHSbits.CH123SA = 1;
Channel 0 -> Mux B
Any anlouge pin from AN0 - AN8 can be selected to give input to channel 0 through Mux B
ADCHSbits.CH0SB = 1; or any other number depending on pin
Channel 1, 2 and 3 -> Mux B
Channel 1 input is AN3, Channel 2 -> AN4, Channel 3 -> AN5
ADCHSbits.CH123SB = 1;
Selecting different combinations of ADC analogue inputs and channels for dspic30f devices. (dspic33f devices may have more channels and inputs available)

3) Select the Voltage Reference

A voltage refernce must be selected to match the input range of the analogue inputs. There are two options for this.

  1. Either the Vcc and Gnd can be made upper and lower reference limits.
  2. Or an external reference voltage may be applied on the AVref pin.

This is done with the help of VCFG bit in the ADCON2 register. (line - 47)

Vref (higher)
Vref (lower)
External Vref +
External Vref -
External Vref +
External Vref -

4) Select the Output Format of Data

The output format of the data sampled through ADC can also be specified with the help of FORM bit in the ADCON1 register, according to the table below:

Data Output Format
signed integer
signed fractional

5) Select the Conversion Trigger Source

Analogue to digital conversion inside the ADC module may be initiated by a number of trigger sources, determined by the SSRC bits in the ADCON1 register according to the following table:

Conversion Trigger Source
Manually clearing the SAMP bit ends sampling and starts conversion.
Active transition on INT0 pin ends sampling and starts conversion.
Timer 3 compare match ends sampling and starts conversion.
Ending of PWM cycle ends sampling and starts conversion.
Automatic conversion triggered by internal counter.

6) Select the Mode of Sampling

Sampling on ADC channels can be initiated with either:

  1. Setting the SAMP bit manually in the code, or:
  2. Automatically after the end of last conversion.

This is decided by the ASAM bit in ADCON1 register.

Sampling begins when SAMP bit set
Sampling begins immediately after the end of last conversion.

7) Select the Conversion Clock

Any Analouge to Digital conversion with the A/D module requires 12 clock periods. The period of a single clock cycle can be configured with the help of ADCS bits in the ADCON3 register. The value placed in ADCS is a six bit value. This can be calculated from the following formulas:

Minimum value of Tad that can be used is 154 nanoseconds.

8) Decide if Simultaneous Sampling is Required or Not

(Optional step)

Simultaneous sampling can be enabled by the SIMSAM bit in the ADCON1 register. Simultaneous sampling captures the samples of all input channels at precisely the same instant. If Simultaneous sampling is disabled, the channels will be sampled one after the other.

9) Select the Conversion Clock Source

(Optional step)

In most cases the conversion clock source is selected to be the system clock by setting the ADRC bit in the ADCON3 register to 0.

10) Determine if Input Scanning is Required

(Optional step)

  • This step can be skipped in most applications.
  • Input scanning can be enabled by the CSNA bit in the ADCON2 register.

Channel 0 of the ADC module can be configured to scan multiple analogue inputs. This can be used if their are multiple input sources and not all of them are active at the same time.

The ADC Interrupt in dspic30f and dspic33f

Instead of using the readADC() function in main body to read the values from the ADC module, an interrupt is used to perform the same function in most advanced applications.

For more information on interrupts refer to this detailed tutorial – How to use Interrupts in Pic MicroControllers

Interrupt based code for ADCs in dspic30f and dspic33f

#define FCY 30000000

#include <xc.h>
#include <stdio.h>
#include <delay.h>
#include <libpic30.h>
#include <math.h>
#include <p30F4011.h>

_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, i.e. 30 MIPS
_FWDT(WDT_OFF);                  // Watchdog timer off

void Interrupt_Init( void )
    IEC0bits.ADIE = 1;       //Enable ADC Interrupt       
    IPC2bits.ADIP = 6;       //set interrupt priority = 6

void __attribute__((interrupt, auto_psv))_ADCInterrupt (void) 
    while ( !ADCON1bits.DONE );   // wait to complete the conversion
    sample.Va = ADCBUF0;
    sample.Vb = ADCBUF1;
    IFS0bits.ADIF = 0;

int main( void )
    // Make RD0 a digital output
    _TRISD0 = 0;

    while( 1 )
        _LATD0 = 1;
        _LATD0 = 0;
  • A conversion trigger source should be selected for the ADC interrupt to function properly as directed in step 5.
  • Sampling should be done in automatic mode. (ASAM bit)
  • Frequency of the triggering of ADC interrupt may be controlled with the help of SMPI bits in the ADCON2 register. (line 50).

This article is accurate and true to the best of the author’s knowledge. Content is for informational or entertainment purposes only and does not substitute for personal counsel or professional advice in business, financial, legal, or technical matters.

© 2017 StormsHalted


    0 of 8192 characters used
    Post Comment
    • alikhan3 profile imageAUTHOR


      3 months ago from Karachi, Pakistan

      The code lines displayed in this article are tested to work, if you copy and paste it, it will be the same as if I send you the code.

      You might want to recheck the MCU model and its configuration bits. This one is for dsPic30f4011.

    • profile image

      Lucas Felfoldi 

      14 months ago


      First, thank you for sharing your knowledge!

      Could you explain a little bit about the code [ADCS = 9] (on "ADC Example Code for dsPic") ?

      In the comments, you said that the clock conversion is 6Tcy, but according to the datasheet, Conversion time = (Tcy/2) * (ADCS + 1)..



      Conversion time = (Tcy/2) * (9 + 1) = 5Tcy...

      Am I wrong?

      Thank you

    • profile image


      15 months ago

      Thank you so much. You really saved my day!!

    • alikhan3 profile imageAUTHOR


      2 years ago from Karachi, Pakistan

      Try debugging with MplabX. It will give a much better interface.

      You will have to disconnect and plugin pickit back. This type of issue is not uncommon with pickit.

    • profile image

      Pramod singh 

      2 years ago


      I am facing an issue with pickit3 where I'm trying to debug a dspic30f4011 on which I could debug it only once. If I try it once again The ID says no device ID found.


    This website uses cookies

    As a user in the EEA, your approval is needed on a few things. To provide a better website experience, uses cookies (and other similar technologies) and may collect, process, and share personal data. Please choose which areas of our service you consent to our doing so.

    For more information on managing or withdrawing consents and how we handle data, visit our Privacy Policy at:

    Show Details
    HubPages Device IDThis is used to identify particular browsers or devices when the access the service, and is used for security reasons.
    LoginThis is necessary to sign in to the HubPages Service.
    Google RecaptchaThis is used to prevent bots and spam. (Privacy Policy)
    AkismetThis is used to detect comment spam. (Privacy Policy)
    HubPages Google AnalyticsThis is used to provide data on traffic to our website, all personally identifyable data is anonymized. (Privacy Policy)
    HubPages Traffic PixelThis is used to collect data on traffic to articles and other pages on our site. Unless you are signed in to a HubPages account, all personally identifiable information is anonymized.
    Amazon Web ServicesThis is a cloud services platform that we used to host our service. (Privacy Policy)
    CloudflareThis is a cloud CDN service that we use to efficiently deliver files required for our service to operate such as javascript, cascading style sheets, images, and videos. (Privacy Policy)
    Google Hosted LibrariesJavascript software libraries such as jQuery are loaded at endpoints on the or domains, for performance and efficiency reasons. (Privacy Policy)
    Google Custom SearchThis is feature allows you to search the site. (Privacy Policy)
    Google MapsSome articles have Google Maps embedded in them. (Privacy Policy)
    Google ChartsThis is used to display charts and graphs on articles and the author center. (Privacy Policy)
    Google AdSense Host APIThis service allows you to sign up for or associate a Google AdSense account with HubPages, so that you can earn money from ads on your articles. No data is shared unless you engage with this feature. (Privacy Policy)
    Google YouTubeSome articles have YouTube videos embedded in them. (Privacy Policy)
    VimeoSome articles have Vimeo videos embedded in them. (Privacy Policy)
    PaypalThis is used for a registered author who enrolls in the HubPages Earnings program and requests to be paid via PayPal. No data is shared with Paypal unless you engage with this feature. (Privacy Policy)
    Facebook LoginYou can use this to streamline signing up for, or signing in to your Hubpages account. No data is shared with Facebook unless you engage with this feature. (Privacy Policy)
    MavenThis supports the Maven widget and search functionality. (Privacy Policy)
    Google AdSenseThis is an ad network. (Privacy Policy)
    Google DoubleClickGoogle provides ad serving technology and runs an ad network. (Privacy Policy)
    Index ExchangeThis is an ad network. (Privacy Policy)
    SovrnThis is an ad network. (Privacy Policy)
    Facebook AdsThis is an ad network. (Privacy Policy)
    Amazon Unified Ad MarketplaceThis is an ad network. (Privacy Policy)
    AppNexusThis is an ad network. (Privacy Policy)
    OpenxThis is an ad network. (Privacy Policy)
    Rubicon ProjectThis is an ad network. (Privacy Policy)
    TripleLiftThis is an ad network. (Privacy Policy)
    Say MediaWe partner with Say Media to deliver ad campaigns on our sites. (Privacy Policy)
    Remarketing PixelsWe may use remarketing pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to advertise the HubPages Service to people that have visited our sites.
    Conversion Tracking PixelsWe may use conversion tracking pixels from advertising networks such as Google AdWords, Bing Ads, and Facebook in order to identify when an advertisement has successfully resulted in the desired action, such as signing up for the HubPages Service or publishing an article on the HubPages Service.
    Author Google AnalyticsThis is used to provide traffic data and reports to the authors of articles on the HubPages Service. (Privacy Policy)
    ComscoreComScore is a media measurement and analytics company providing marketing data and analytics to enterprises, media and advertising agencies, and publishers. Non-consent will result in ComScore only processing obfuscated personal data. (Privacy Policy)
    Amazon Tracking PixelSome articles display amazon products as part of the Amazon Affiliate program, this pixel provides traffic statistics for those products (Privacy Policy)
    ClickscoThis is a data management platform studying reader behavior (Privacy Policy)