PIC32-MX AD Analysis

This page is result of analysis on the PIC32/PIC32MX AD functionality per the data-sheet.   Target processor is a PIC32MX340F512H

Goal: We want continuous sampling so that all we have to do is every so often come by and process the results.. we will set all 16 Analogue inputs for potential sampling, as if they are turned off in AD1CSSLSET we shouldn’t get a sample from them anyway..

The result will be that sampling is always running, all we have to do is set an AD input as digital input and ensure it is set in AD1CSSLSET for its associated ADC1BUF0-15 to be cyclically updated

The first part of this page is a breakdown of the relevant registers, the second is an exercise working through the datasheet to meet the above goal

PIC32MX340F512H Analogue to Digital Specifications

  • Up to 16 Channels og 10bit SAR AD
  • Auto channel scan
  • External Voltage reference via 2 pins

  • Selectable trigger conversion source
  • 16 x 32bit word conversion buffer
  • Selectable buffer fill modes
  • 8 Conversion output format options
  • 2 Mux’s with inputs able to be directed to specific mux’s

Registers:

Easy parts first:

ADC1BUF0 – ADC1BUFF

  • 16 x 32bit output buffers

AD1CON1:

At POR all used bits default to 0

  • 31-16: Reserved
  • 15: ON
    • 0 = Off
    • 1 = On
  • 14: FRZ
    • 1 = Freeze in debug mode
  • 13: SIDL
    • 1 = stop operation in Idle mode
    • 0 = continue
  • 12-11: Reserved
  • 10-8: FORM
  • 7-5: SSRC: Conversion trigger source select
  • 4: CLRASAM Stop conversion sequence bit
    • 1 = Stops conversion when first ADC int is generated, hardware clears the ASAM bit when int is gernerated
    • 0 = normal operation ie buffer contents will be overwritten by next conversion sequence
  • 3: Reserved
  • 2: ASAM ADV Sample Auto Start bit
    • 1 = sampling begins immediately after last conversion completes
    • 0 = sampling begins when SAMP bit is set
  • 1: SAMP ADC Sample Enable bit
    • 1 = the ADC SHA is sampling
    • 0 = the ADC sample/hold amplifier is holding
    • When ASAM = 0, writing 1 to this bit starts samppling
    • When SSRC = 000, writing 0 to this bit will end sampling and start conversion
  • 0: DONE AD Conversion Status Bit
    • 1 = Conversion is done
    • 0 = conversion incomplete or not started
    • Not persistant in automatic modes, is cleared by hardware at the beginning of the next sample.
AD1CON1CLR = 0x00008002; //will clear bits 15 & 0 in AD1CON1

AD1CON1SET = 0x00008002; //will set bits 15 & 0 in AD1CON1

AD1CON1INV = 0x00008002; //will invert bits 15 & 0 in AD1CON1

AD1CON2:

At POR all used bits default to 0

  • 31-16: Reserved
  • 15-13: VCFG<2:0) Voltage ref configuration
    • 000: VR+ = AVdd, VR- = AVss
    • 001: VR+ = VRef+ pin, VR- = ADss
    • 010: VR+ = AVdd, VR_ = VRef- pin
    • 011: VR+ = VRef+ pin, VR- = VRef- pin
    • 1nn: VR+ = AVdd, VR- = AVss
  • 12: OFFCAL: Input Offset Calibration Mode Select bit
    • 1 = Enable offset mode, VINH & VINL of SHA are connected to VR-,
    • 2 = Disable, Inputs to SHA are controlled by AD1CHS or AD1CSSL
  • 11: Reserved
  • 10: CSCNA: Scan Input Selections for CH0+ SHA Input for MUX A Input Multiplexer Setting bit
    • 1 = Scan inputs
    • 0 = Do not scan inputs
  • 9-8: Reserved
  • 7: BUFS Buffer  Fill Status Bit
    • Only valid when BUFM = 1 (ADRES split into 2 x 8 word buffers)
    • 1 = ADC currently filling buffer 0×8-0xF user should read 0×0-0×7
    • 0 = ADC currently filling buffer 0×0-0×7 user should read 0×8-0xF
  • 6: Reserved
  • 5-2: SMPI<3:0>: Sample/Convert Sequence per Interrupt  Selection bits
    • 1111 = Interrupts at complete of every 16 sample/convert sequences
    • 1110 = Interrupts at complete of every 15 sample/convert sequences
    • ….
    • 0001 = Interrupts at complete of every 2 sample/convert sequences
    • 0000 = Interrupts at complete of every sample/convert sequences
  • 1: BUFM: ADC Result Buffer Mode Select bit
    • 1 = Buffer configured as 2 x 8 word buffers, ADCBUF(7…0), ADCBUF(15…8)
    • 0 = Buffer configured as1 16 word buffer, ADC1BUF(15…0)
  • 0: ALTS: Alternating Input Sample Mode Select bit
    • 1 = Use MUX A input multiplexer settings for 1st sample, then alternates between MUXA & MUXB for alternate samples
    • 0 = Always use MUXA input multiplexer settings
AD1CON2CLR = 0x00008002; //will clear bits 15 & 0 in AD1CON2

AD1CON2SET = 0x00008002; //will set bits 15 & 0 in AD1CON2

AD1CON2INV = 0x00008002; //will invert bits 15 & 0 in AD1CON2

AD1CON3:

At POR all used bits default to 0

  • 31-16: Reserved
  • 15: ADRC: ADC Conversion clock source
    • 1 = ADC internal clock
    • 0 = Derivedf rom Peripheral Bus Clock (PBCLK)
  • 14-13: Reserved
  • 12-8: SAMC<4:0> Auto Sample Time Bits
    • 11111 = 31 TAD
    • …..
    • 00001 = 1 TAD
    • 00000 = 0 Tad (Invalid)
  • 7-0: ADCS<7:0> ADC Conversion Clock Select bits
    • 11111111 = TPB * 2 * (ADCS<7:0> + 1) = 512 * TPB = TAD
    • …….
    • 00000001 = TPB * 2 * (ADCS<7:0> + 1) = 4 * TPB = TAD
    • 00000000 = TPB * 2 * (ADCS<7:0> + 1) = 2 * TPB = TAD
AD1CON3CLR = 0x00008002; //will clear bits 15 & 0 in AD1CON3

AD1CON3SET = 0x00008002; //will set bits 15 & 0 in AD1CON3

AD1CON3INV = 0x00008002; //will invert bits 15 & 0 in AD1CON3

AD1CHS:

At POR all used bits default to 0

  • 31: CH0NB: -ve Input Select for MUXB
    • 1 = Channel 0 negative input is AN1
    • 0 = Channel 0 negative input is VR-
  • 30-28: Reserved
  • 27-24: CH0SB: +ve Input Select for MUXB
    • 1111 = Channel 0 positive input is AN15
    • ….
    • 0001 = Channel 0 positive input is AN1
    • 0000 = Channel 0 positive input is AN0
  • 24: CH0NB: -ve Input Select for MUXA
    • 1 = Channel 0 negative input is AN1
    • 0 = Channel 0 negative input is VR-
  • 22-20: Reserved
  • 19-16: CH0SA: +ve Input Select for MUXA
    • 1111 = Channel 0 positive input is AN15
    • ….
    • 0001 = Channel 0 positive input is AN1
    AD1CSSLSET
    • 0000 = Channel 0 positive input is AN0
  • 15-0: Reserved
AD1CHSCLR = 0x00004001; //will clear bits 15 & 0 in AD1CHS

AD1CHSSET = 0x00004001; //will set bits 15 & 0 in AD1CHS

AD1CHSINV = 0x00004001; //will invertbits 15 & 0 in AD1CHS

AD1PCFG:

At POR all used bits default to 0

  • 31-16: Reserved
  • 15-0: PCFG<15:0> Analogue Input Pin Configuration bits
    • 1 = Analogue input pin in digital mode, port read enabled, ADC input multiplexer input for this analogue pin connected to AVss
    • 0 = Analogue input pin in analogue mode, digital port read will return a 1 always, ADC samples pin voltage
AD1PCFGCLR = 0x00008002; //will clear bits 15 & 0 in AD1PCFG

AD1PCFGSET = 0x00008002; //will set bits 15 & 0 in AD1PCFG

AD1PCFGINV = 0x00008002; //will invert bits 15 & 0 in AD1PCFG

Note: To use an analogue pin ANx, the PCFG bit must be 0, and the PIN TRIS bit must be 1 ie configured as input, if the TRIS bit is 0 ie configured as output, the Pins LATx level will be sampled..

AD1CSSL:

At POR all used bits default to 0

  • 31-16: Reserved
  • 15-0: CSSL<15:0>: ADC Input Pin Scan Selection Bits
    • 1 = Select ANx for input scan
    • 0 = Skip ANx for input scan
AD1CSSLCLR = 0x00008002; //will clear bits 15 & 0 in AD1CSSL

AD1CSSLSET = 0x00008002; //will set bits 15 & 0 in AD1CSSL

AD1CSSLINV = 0x00008002; //will invertbits 15 & 0 in AD1CSSL

Various interrupt flags..

Configuration

Setup required parameters

Note the configuration steps here (ie A-1) relate directly to the:

  • Microchip PIC32MX FRM (Family Reference Manual) Section 17:  10bit A/D convertor:
    • Chapter 17.4, ADC Module configuration

A-0 We will set all registers back to POR status as we dont know what the TCPIP stack has done already or what it will do in future releases.

		// Configure AD module
	// First set all registers except AD1PCFGCLR back to POR State ie all cleared as we dont know what the
	// TCPIP Initalisation routines have done or will do in future revisions
	AD1CON1CLR = 0xFFFFFFFF; // This will also turn off the AD module if it was already on (bit 15)
	AD1CON2CLR = 0xFFFFFFFF;
	AD1CON3CLR = 0xFFFFFFFF;
	AD1CSSLCLR = 0xFFFFFFFF;

	AD1PCFGSET = 0xFFFFFFFF; // Turn off all Analogue

A-1. Select Analogue inputs by clearing applicable pin bits in AD1PCFG<15:0> and also by setting applicable TRIS bits (Configure as input)

We want to sample AN0-AN3:

	// The following sequence and identifiers (A-1) etc are per the PIC32MX ADC reference manual steps
	// for chapter 17.4 ADC Module configuration (Microchip doc ref DS61104D)

	// A-1: Select Analogue inputs by clearing applicable pin bits in AD1PCFG<15:0> and also by setting applicable TRIS bits (Configure as input)
	//AD1PCFGCLR = 0x0000000F; // Turn on AN0-3  // Because we are using scan mode it is AD1CSSLSET that defines the input channels..

	//Set Digital IO for AN0-AN3 to Inputs
	TRISBbits.TRISB0 = 1;
	TRISBbits.TRISB1 = 1;
	TRISBbits.TRISB2 = 1;
	TRISBbits.TRISB3 = 1;

B-1. Select ADC MUX per analogue input in ADCHS<32:0>

	// B-1: Select ADC MUX per analogue input in ADCHS<32:0>
	// By default MUX input channel selects are cleared means MUX A & B -ve input is VR-
	// Connect AN0 as +ve input to CH0SA (MUX A)
	// For CH0SA is AD1CHSSET bits 19-16, ie 0 = AN0, 1 = AN1... 15 = AN16
	// Note that in SCAN mode CH0SA is ignored
	// AD1CHSSET = 0x00000000;  // No change but we will leave this as an example/template

C-1. Select output format of result in FORM<2:0> (AD1CON1<10:8>)

	// C-1: Select output format of result in FORM<2:0> (AD1CON1<10:8>)
	// We simply want our 10 bit integers.. so will select a 16bit integer which is the default..
	// ADCON1SET = 0x00000000 // No change but we will leave this as an example/template

C-2 Select sample clock source using SSRC<2:0> (AD1CON1<7:5>)

We want auto convert on the selected channels, requires SSRC = 111, will sample continously at the rate specified by SAMC.

	// C-2: Select sample clock source using SSRC<2:0> (AD1CON1<7:5>)
	// *** With scan we shouldn't need to set these? But we will just in case.. ***
	//AD1CON1SET = 0x00000070; // We want to autoconvert across our selected channels so SSRC = 111
	AD1CON1bits.SSRC = 0b111;
	//AD1CON1SET = 0x00000002; // We want autosampling so need ASAM (AD1CON1<2> set)
	AD1CON1bits.ASAM = 0b1;

D-1: Select voltage reference source for VR+ & VR- using VCFG<2:0> (AD1CON2<15:13>)

	// D-1: Select voltage reference source for VR+ & VR- using VCFG<2:0>  (AD1CON2<15:13>)
	//AD1CON2SET 0x00000000; // Default = 000 = VR+ = AVdd, VR- = AVss so no change but we will leave this as an example/template
	AD1CON2bits.VCFG = 0b000;

D-2: Select scan mode using CSCNA (AD1CON2<10>)

	// D-2: Select scan mode using CSCNA (AD1CON2<10>)
	//AD1CON2SET = 0x00000400;
	AD1CON2bits.CSCNA = 0b1;
	AD1CSSLSET = 0x0000000F; // Scan AN0-3

D-3: Set the number of conversions per interrupt (if interrupts are to be used) using SMPI<3:0> (AD1CON2<5:2>)

	// D-3 Set the number of conversions per interrupt (if interrupts are to be used) using SMPI<3:0> (AD1CON2<5:2>)
	//AD1CON2SET = 0x0000000C; // We will setup to use all 16 buffers regardless of the no of inpuits we are scanning
	AD1CON2bits.SMPI = 0b1111;

D-4: Set buffer fill mode using BUFM (AD1CON2<1>)

	// D-4: Set buffer fill mode using BUFM (AD1CON2<1>)
	//AD1CON2SET = 0x00000002;	// we will leave as 0 ie 16 sequential buffers
	//AD1CON2bits.BUFM = 0b0;

D-5: Select the MUX to be connected to the ADC in ALTS (AD1CON2<0>)

	// D-5: Select the MUX to be connected to the ADC in ALTS (AD1CON2<0>)
	// We have no need to use ALTS at this time so will accept the default (ALTS = 0) for Single input selection
	// AD1CON2SET = 0x00000000; no change but we will leave this as an example/template
	//AD1CON2bits.ALTS = 0b0;

E-1: Select ADC Clock source using ADRC (AD1Con3<15>)

	//E-1: Select ADC Clock source using ADRC (AD1Con3<15>)
	AD1CON3bits.ADRC = 0b1;

E-2: Select the sample time using SAMC<4:0> (AD1CON3<12:8>) if autoconvert is to be used

// E-2: Select the sample time using SAMC<4:0> (AD1CON3<12:8>) if autoconvert is to be used
AD1CON3bits.SAMC = 0b11111; // We will wait for the longest time..

E-3: Select the ADC clock prescaler using ADCS<7:0> (AD1CON3<7:0>

	// E-3: Select the ADC clock prescaler using ADCS<7:0> (AD1CON3<7:0>
	// As we are using the Internal RC this is ignored
	//AD1CON3bits.ADRC = 0b0;

F: Turn on the ADC module using AD1CON1<15>

	// Now Turn on ADC:
	AD1CON1bits.ON = 1;