Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] CTMU current and capacitance calibration

Status
Not open for further replies.

teddydogowners

Newbie level 4
Joined
Jul 4, 2016
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
62
Hi!

I am using the CTMU of a PIC24FJ64GA106, and I can't seem to calibrate it at all. The CTMUIsrc value always returns as 0, and the CTMUCap always returns as NaN. What could be the problem?

Thanks in advance!

Code:
#include "p24Fxxxx.h"
#include "p24FJ64GA106.h"
#include "adc.h"
#include "comparator.h"
#include "crc.h"
#include "ctmu.h"
#include "i2c.h"
#include "incap.h"
#include "outcompare.h"
#include "pmp.h"
#include "ports.h"
#include "PPS.h"
#include "PwrMgnt.h"
#include "Rtcc.h"
#include "spi.h"
#include "sram.h"
#include "timer.h"
#include "uart.h"
#include "wdt.h"
#include "stdio.h"
#include "stdlib.h"
#include "xc.h"
#include "PIC24F_periph_features.h"

// CONFIG3
#pragma config WPFP = WPFP511           // Write Protection Flash Page Segment Boundary (Highest Page (same as page 42))
#pragma config WPDIS = WPDIS            // Segment Write Protection Disable bit (Segmented code protection disabled)
#pragma config WPCFG = WPCFGDIS         // Configuration Word Code Page Protection Selectbit (Last page(at the top of program memory) and Flash configuration words are not protected)
#pragma config WPEND = WPENDMEM         // Segment Write Protection End Page Select bit (Write Protect from WPFP to the last page of memory)

// CONFIG2
#pragma config POSCMOD = EC             // Primary Oscillator Select (EC Oscillator mode Selected)
#pragma config IOL1WAY = OFF             // IOLOCK One-Way Set Enable bit (Write RP Registers Once)
#pragma config OSCIOFNC = OFF           // Primary Oscillator Output Function (OSCO functions as CLKO (FOSC/2))
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor (Both Clock Switching and Fail-safe Clock Monitor are disabled)
#pragma config FNOSC = PRI              // Oscillator Select (Primary oscillator (XT, HS, EC))
#pragma config IESO = OFF               // Internal External Switch Over Mode (IESO mode (Two-speed start-up)disabled)

// CONFIG1
#pragma config WDTPS = PS1              // Watchdog Timer Postscaler (1:1)
#pragma config FWPSA = PR32             // WDT Prescaler (1:32)
#pragma config WINDIS = OFF             // Watchdog Timer Window (Standard Watchdog timer is enabled(Windowed mode is disabled))
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (Watchdog timer is disabled)
#pragma config ICS = PGx1               // Comm Channel Select (EMUC/EMUD share PGC1/PGD1)
#pragma config GWRP = OFF               // General Code Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF                // General Code Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG port is disabled)


/**************************************************************************/
//Setup CTMU
/**************************************************************************/


double CTMUISrc=0;
double CTMUCap=0;;

int setupcur(void);
int setupcap(void);
int CurCal(void);
int CapCal(void);
int StartPulse(void);
int TimeMeasure(void);

int main(void)
{
    RCON=0x0000;
    OSCCONL=0x46;
    OSCCONH=0x78;
    //OSCCONH=0x9A;
    //OSCCONH=0x22;
    /*OSCCONbits.CLKLOCK=0;
    OSCCONbits.IOLOCK=1;
    OSCCONbits.LOCK=0;
    OSCCONbits.CF=0;
    OSCCONbits.POSCEN=1;
    OSCCONbits.SOSCEN=1;
    OSCCONbits.OSWEN=0;*/
    CLKDIV=0x0000;
    REFOCON=0x0000;
    CurCal();
    CapCal();
    /*while(1)
    {
        // Step 7: Wait for ADC interrupt
        while(IFS0bits.AD1IF == 0)
        {
            // Steps 8-11
            IFS0bits.AD1IF = 0; // clear the interrupt
            result = ADC1BUF0; // read ADC result
            CTMUCONbits.IDISSEN = 1; // begin manual discharge of cap
            asm("NOP"); // may be required for external caps
            asm("NOP");
            asm("NOP");
            asm("NOP");
            CTMUCONbits.IDISSEN = 0; // stop discharge of cap
            CTMUCON &= ~0x0300; // clear the edge status bits
        }
        
    }*/
    //TimeMeasure();
    int i=0;
    TRISFbits.TRISF0=0;
    LATFbits.LATF0=1;
    while(1)
    {
        LATFbits.LATF0=0;
        for(i=0;i<8100;i++);
        LATFbits.LATF0=1;
        for(i=0;i<8100;i++);
    }
    return(1);
}


int setupcur(void)
{         //CTMUCON - CTMU Control register
        CTMUCON = 0x80FC; //make sure CTMU is disabled
        //CTMU continues to run when emulator is stopped,CTMU continues
        //to run in idle mode,Time Generation mode disabled, Edges are blocked
        //No edge sequence order, Analog current source not grounded, trigger
        //output disabled, Edge2 polarity = positive level, Edge2 source =
        //source 0, Edge1 polarity = positive level, Edge1 source = source 0,
        // Set Edge status bits to zero
        //CTMUICON - CTMU Current Control Register
        CTMUICON = 0x0100; //0.55uA, Nominal - No Adjustment
        //-------------------------------------------------------------------------
        //setupAD converter;
        //-------------------------------------------------------------------------
        TRISB=0x0001; //set channel 0 as an input
        AD1PCFGL=0x0000; //
        AD1PCFGH=0x0000;
        AD1CHS=0x0000; //select the analog channel(0)
        AD1CSSL=0x0001; //
        AD1CON1 = 0x8000; //Turn On A/D Converter, continue in
        // idle mode, Unsigned fractional format, Clear Samp bit to start
        //conversion, Sample when SAMP bit is set, sampling on hold
        AD1CON2 = 0x0000; //VR+ = AVDD, V- = AVSS, Don't scan,
        //always use MUX A inputs
        AD1CON3 = 0x0100; //A/D uses system clock, conversion
        //clock = 1xTcy
        return(1);
}

int setupcap(void)
{
      //CTMUCON - CTMU Control register
        CTMUCON = 0x80FC; //make sure CTMU is disabled
        //CTMU continues to run when emulator is stopped,CTMU continues
        //to run in idle mode,Time Generation mode disabled, Edges are blocked
        //No edge sequence order, Analog current source not grounded, trigger
        //output disabled, Edge2 polarity = positive level, Edge2 source =
        //source 0, Edge1 polarity = positive level, Edge1 source = source 0,
        // Set Edge status bits to zero
        //CTMUICON - CTMU Current Control Register
        CTMUICON = 0x0100; //0.55uA, Nominal - No Adjustment
        //-------------------------------------------------------------------------
        //setupAD converter;
        //-------------------------------------------------------------------------
        TRISB=0x0002; //set channel 1 as an input
        AD1PCFGL=0x0000; //
        AD1PCFGH=0x0000;
        AD1CHS=0x0101; //select the analog channel(1)
        AD1CSSL=0x0002; //
        AD1CON1 = 0x8000; //Turn On A/D Converter, continue in
        // idle mode, Unsigned fractional format, Clear Samp bit to start
        //conversion, Sample when SAMP bit is set, sampling on hold
        AD1CON2 = 0x0000; //VR+ = AVDD, V- = AVSS, Don't scan,
        //always use MUX A inputs
        AD1CON3 = 0x0100; //A/D uses system clock, conversion
        //clock = 1xTcy
        return(1);
}

#define COUNT 500 //@ 8MHz = 125uS.
#define DELAY for(i=0;i<COUNT;i++)
#define RCAL .027 //R value is 4200000 (4.2M)
//scaled so that result is in
//1/100th of uA
#define ADSCALE 1023 //for unsigned conversion 10 sig bits
#define ADREF 3.3 //Vdd connected to A/D Vr+

int CurCal(void)
{
        int i;
        int j = 0; //index for loop
        double Vread = 0;
        double VTot = 0;
        float Vavg=0, Vcal=0; //float values stored for calculations
        setupcur();
        CTMUCONbits.CTMUEN = 1; //Enable the CTMU
        for(j=0;j<10;j++)
        {
                AD1CON1bits.SAMP = 1; //Manual sampling start
                CTMUCONbits.IDISSEN = 1; //drain charge on the circuit
                DELAY; //wait 125us
                CTMUCONbits.IDISSEN = 0; //end drain of circuit
                CTMUCONbits.EDG1STAT = 1; //Begin charging the circuit
                //using CTMU current source
                DELAY; //wait for 125us
                CTMUCONbits.EDG1STAT = 0; //Stop charging circuit
                IFS0bits.AD1IF = 0; //make sure A/D Int not set
                AD1CON1bits.SAMP = 0; //and begin A/D conv.
                while(!IFS0bits.AD1IF); //Wait for A/D convert complete
                AD1CON1bits.DONE = 0;
                Vread = ADC1BUF0; //Get the value from the A/D
                IFS0bits.AD1IF = 0; //Clear A/D Interrupt Flag
                VTot += Vread; //Add the reading to the total
        }
        Vavg = (float)(VTot/10.000); //Average of 10 readings
        Vcal = (float)(Vavg/ADSCALE*ADREF);
        CTMUISrc = Vcal/RCAL; //CTMUISrc is in 1/100ths of uA
        return(1);
}

#define COUNT2 25 //@ 8MHz INTFRC = 62.5 us.
#define ETIME COUNT2*2.5 //time in uS
#define DELAY2 for(i=0;i<COUNT2;i++)
#define ADSCALE 1023 //for unsigned conversion 10 sig bits
#define ADREF 3.3 //Vdd connected to A/D Vr+


int CapCal(void)
{
    int i;
    int j = 0; //index for loop
    unsigned int Vread = 0;
    float Vavg;
    float VTot;
    float Vcal;
    //assume CTMU and A/D have been setup correctly
    //see Example 11-1 for CTMU & A/D setup
    setupcap();
    CTMUCONbits.CTMUEN = 1;//Enable the CTMU
    for(j=0;j<10;j++)
    {
        AD1CON1bits.SAMP = 1; //Manual sampling start
        CTMUCONbits.IDISSEN= 1; //drain any charge on the circuit
        DELAY2; //wait 62.5 us
        CTMUCONbits.IDISSEN = 0; //end drain of circuit
        CTMUCONbits.EDG1STAT = 1; //Begin charging the circuit
        //using the CTMU current source
        DELAY2; //wait for 62.5 us for circuit to charge
        CTMUCONbits.EDG1STAT = 0; //Stop charging circuit and begin A/D conv.
        AD1CON1bits.SAMP = 0;
        while(!IFS0bits.AD1IF); //Wait for A/D conversion to complete
        Vread = ADC1BUF0; //Get the value from the A/D converter
        IFS0bits.AD1IF = 0; //Clear AD1IF
        VTot += Vread; //Add the reading to the total
    }
    Vavg = (VTot/10); //Average of 10 readings
    Vcal = (Vavg/ADSCALE*ADREF);
    CTMUCap = (CTMUISrc*ETIME/Vcal)/100;
    //CTMUISrc is in 1/100ths of uA,
    //calculated in Example 1-2
    //time is in us
    //CTMUCap is in pF
    return(1);
}

int StartPulse(void)
{
    /*TRISDbits.TRISD10=0;
    RPOR1bits.RP3R=18;
    OC1CON1=0x0000;
    OC1R=0x0002;
    OC1RS=0x0008;
    PR1=0x0004;
    TMR2=0x0002;
    OC1CON1=0x1004;
    OC1CON2=0x001F;
    IEC0bits.T1IE=0;
    IEC0bits.OC1IE=0;
    T1CON=0x0000;
    PR1=0.000000125;
    T1CONbits.TON=1;
    AD1PCFGL=0x0000;
    AD1CON2=0x0000;//comment till here*/
    TRISDbits.TRISD0=0;
    RPOR5bits.RP11R=18;
    asm("NOP");
    OC1CON1 = 0x0000; // Turn off Output Compare 1 Module
    OC1CON1 = 0x0004; // Load new compare mode to OC1CON
    OC1R = 0x3000; // Initialize Compare Register1 with 0x3000
    OC1RS = 0x6000; // Initialize Secondary Compare Register1 with 0x3003
    PR3=0x6000;
    IPC0bits.OC1IP0 = 1; // Setup Output Compare 1 interrupt for
    IPC0bits.OC1IP1 = 0; // desired priority level
    IPC0bits.OC1IP2 = 0; // (this example assigns level 1 priority)
    IFS0bits.OC1IF = 0; // Clear Output Compare 1 interrupt flag
    IEC0bits.OC1IE = 0; // Enable Output Compare 1 interrupts
    T2CONbits.TSIDL=0;
    T2CONbits.TGATE=0;
    T2CONbits.TCS=0;
    T2CONbits.TCKPS=0b00;
    T2CONbits.T32=0;
    T2CONbits.TON = 1; // Start Timer2 with assumed settings
    return(1);
}

int TimeMeasure(void)
{
    float vread=0;
    float time=0;
    int i;
    //setup CTMU
    //CTMUCON
    CTMUCONbits.CTMUEN = 0; //make sure CTMU is disabled
    CTMUCONbits.CTMUSIDL = 0; //CTMU continues to run in idle mode
    CTMUCONbits.TGEN = 0; //disable edge delay generation mode of the CTMU
    CTMUCONbits.EDGEN = 1; 
    CTMUCONbits.EDGSEQEN = 1; 
    CTMUCONbits.IDISSEN = 0; //Do not ground the current source
    CTMUCONbits.CTTRIG = 0; //Trigger Output is disabled
    CTMUCONbits.EDG2POL = 0;
    CTMUCONbits.EDG2SEL = 0b10; //Edge2 Source = CTED2
    CTMUCONbits.EDG1POL = 1;
    CTMUCONbits.EDG1SEL = 0b11; //Edge1 Source = CTED1
    CTMUCONbits.EDG1STAT=0;
    CTMUCONbits.EDG2STAT=0;
    //CTMUICON
    CTMUICON=0x0000;
    CTMUICONbits.IRNG=0b01; //55uA
    CTMUICONbits.ITRIM = 0b000000; //Nominal - No Adjustment
    //setup A/D converter
    TRISBbits.TRISB12 = 1; // Configure RB12 as a input CTED2
    TRISBbits.TRISB13 = 1; // Configure RB13 as a input CTED1
    TRISBbits.TRISB2 = 1; // Configure RB2 as a input
    AD1PCFGL=0x0000; //-----------------IT SAID 0x0004, find out why
    AD1PCFGH=0x0000;
    AD1CHS=0x0004; //select the analog channel(2)
    AD1CSSL=0x0004; //
    AD1CON1 = 0x0000; //Turn Off A/D Converter, continue in idle mode, Unsigned fractional format, Sample when SAMP bit is set, sampling on hold
    AD1CON1bits.SSRC = 4; // CTMU is the conversion trigger source
    AD1CON2 = 0x0000; //VR+ = AVDD, V- = AVSS, Don't scan, always use MUX A inputs
    AD1CON3 = 0x0000; //A/D uses system clock, conversion clock = 1xTcy
    AD1CON3bits.ADCS = 8; // conversion clock = 1xTcy
    AD1CON1bits.ADON = 1;
    AD1CON1bits.ASAM = 1; // Auto-sample
    AD1CHSbits.CH0SA = 2; // Select AN2
    CTMUCONbits.CTMUEN=1;
    CTMUCONbits.IDISSEN = 1; //drain charge on the circuit
    DELAY; //wait 125us
    CTMUCONbits.IDISSEN = 0; //end drain of circuit
    AD1CON1bits.SAMP=1;
    StartPulse();
    DELAY; //wait for 125us
    DELAY;
    IFS0bits.AD1IF = 0; //make sure A/D Int not set
    AD1CON1bits.SAMP = 0; //and begin A/D conv.
    while(!IFS0bits.AD1IF); //Wait for A/D convert complete
    AD1CON1bits.DONE = 0;
    vread = ADC1BUF0;
    time=vread*(CTMUCap/CTMUISrc)*(ADREF/ADSCALE); //Get time difference
    return(1);
}

tdr.jpg
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top