Measure VDD using Band-Gap voltage

This is something that would be typically used to measure Battery voltage over time.

Here’s a complete stand-alone module that can be used to investigate this feature.

// ===========================================
// o Measure VDD using BAND GAP Voltage, 1.2V
// on PIC24FJ256GB004 PIM w/ Explorer 16 Board
// o ICD3, MPLAB v8.85, C30 v3.31
// o June 2012
// o Note:  Please see Microchip Application Note AN1072
//    for an more in-depth example of this using a PIC16F690
// ===========================================

#include <p24fxxxx.h>

#ifdef __PIC24FJ64GB004__ //Defined by MPLAB when using 24FJ64GB004 device
_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & FWDTEN_OFF & ICS_PGx1)
_CONFIG2( FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_XT & FNOSC_PRI & I2C1SEL_SEC & IOL1WAY_ON)
_CONFIG3(SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS)
_CONFIG4(DSWDTEN_OFF & RTCOSC_SOSC & DSWDTPS_DSWDTPS6 & DSWDTOSC_SOSC & DSBOREN_OFF)

#else
#error ERROR: INCORRECT PIC selected for this project: Use PIC24FJ64GB004.
#endif
unsigned long VIN_Result,VDD_Result;
unsigned long Count;

int main(void)
{

AD1CON2 = 0; // AVdd, AVss, int every conversion, MUXA only
AD1CON3 = 0x1F05; // 31 Tad auto-sample, Tad = 5*Tcy
AD1CON1 = 0x80E4; // Turn on, auto sample start, auto-convert
AD1CHS = 15; // VBG 1.2V
AD1PCFGbits.PCFG15 = 0; // Disable digital input on VBG Channel
AD1CHS = 15; // CHAN for VBG 1.2V
AD1CSSL = 0; // No scanned inputs

while (1)
{
VIN_Result = VDD_Result = 0;

// ———————————————————————
// Wait for conversion to complete
// ———————————————————————
while(!AD1CON1bits.DONE)
;

// ———————————————————————
// Read A2D result
// ———————————————————————
Count = (unsigned long) ADC1BUF0;

// ———————————————————————
// FYI Only – Let’s see what VIN would be, assuming VDD is 3.3V
// ———————————————————————
VIN_Result = (Count * 3300)/1024;

// ———————————————————————
// Scale 1.2V to 1200 for calculation.
// ———————————————————————
VDD_Result = (unsigned long)((1200 * 1023.0))/(Count);

// ———————————————————————
// Set Breakpoint here…
// ———————————————————————
Nop();
Nop();
Nop();
Nop();

} // End of while(1)…

} // End of main()…

I feel the need for speed…

One of the easiest ways to config the PIC32 is to use this function call found in <plib.h>:

SYSTEMConfigPerformance(SYS_FREQ);

My setup:
Explorer 16 Demo Board
PIM PIC32MX795F512L
MLPAB v8.85
C32 v2.20
ICD3

<CODE>
#include <p32xxxx.h>
#include <plib.h>

// Configuration Bit settings
// SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)
// PBCLK = 40 MHz
// Primary Osc w/PLL (XT+,HS+,EC+PLL)
// WDT OFF
// Other options are don’t care

#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1

#define SYS_FREQ (80000000L)

int main(void)
{

SYSTEMConfigPerformance(SYS_FREQ);

mJTAGPortEnable(0); // Disable JTAG which is ON by default.

TRISAbits.TRISA0 = 0; // PORT PIN A0 = OUTPUT

while (1)
{
// ———————————————————————
// Too S…L…O…W…
// LATAbits.LATA0 ^= 1;
// ———————————————————————

// ———————————————————————
// F…A…S…T
// ———————————————————————
LATAINV = 1; // AUTOMICALLY invert/toggle A0

}
}
</CODE>

PIC32 – Watch your JTAG…

Let’s say you are debugging the PIC32 and using a port pin (RB12 for example) and all’s well.  Now, you switch from DEBUG to RELEASE and that pin “stops” working. How can THAT be???  There is a good chance that the I/O pin you are using is also a JTAG pin.
Take away:
JTAG is ON by default and needs to be turned OFF in order for you to use that I/O pin.

Hardware Breakpoints – Stopping on a Dime or two

Hardware-Breakpoints (NOT Software-Breakpoints) are the backbone of debugging.  As awesome as they are, they can be a bit confusing to an unseasoned developer.  One of the most popular debug questions I get is about “Skidding”.

Skidding happens during debugging when the program execution stops well after the desired breakpoint address is encountered.  Kind of like when you hit the brakes in your car, the tires stop rolling but your car continues a bit further than intended.  The program counter ends up one or two instructions beyond where the breakpoint was set.  This is due to the instruction pipeline which must be executed before halting.  An extreme case of this happens if you set a breakpoint on a flow control instruction (CALL or JUMP), then an actual halt may not be anywhere near where the actual breakpoint is set.

You can overcome this phenomenon in one of two ways.

  • Insert a few NOP’s before the actual breakpoint or
  • Set your breakpoint a few lines of code before the actual desired stopping point.
 

NOTE:  PIC32 devices do not exhibit skidding.

Programming – TWO power supplies required, really?

Maybe…
Depending upon the PIC you are using and the voltage level, you might need a different VDD voltage during programming.

Take the PIC16F88x part for example.
VDD ranges between 2.0V and 5.5V during operation.
Bulk erase voltages however are between 4.5V and 5.5V.
A typical error in MPLAB might look something like this:
ICD0161: Verify failed (MemType = Config, Address = 0×2007, Expected Val = 0x3FF7, Val Read = 0x3FB7)

Take away:
Make it a habit to always check the programming specification in addition to the data sheet!