Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

CTMU for time measurement calibration

Status
Not open for further replies.

trojsi

New Member
Hi,
I have been experimenting a lot with the PIC24F16KA102 for measuring accurately a period at nanosecond resolution.

I managed to get current calibration up an d running with very good values. I used the 55µA mode with 30K 0.1% resistance to produce 70% of full scale 2.5V as suggested in the application note.

Now I am trying to do capacitance calibration. I am starting from the smallest value of time to give to the A/D internal cap to charge and gradually increase the time and plot a graph. At first there seems to be a cap charging graph but at times, the value is totally distorted and totally goes out of the way. When I simulate it with proteus I get good values all the way. With MPLAB SIM the 5 transients for the A/D cap to charge up to approx. 1.65V, the stop watch showed 184µs. The code is below and the schematic is attached. The CTMUI is infact the voltage across the resistance not the current.
LCD 4-bit PIC24.png

Did anyone try something like and can give me some tips? Or even maybe there is a particular pic that is preferred when it comes to time measurement with the ctmu. (if it is possible to eliminate these factors)

Code:
#include <p24F16KA102.h>
#include "stdio.h"
#include "lcd.h"
#include "main.h"
#include "string.h"


_FPOR ( MCLRE_ON );
_FOSCSEL(FNOSC_PRI & IESO_OFF);
_FOSC	(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_HS & POSCFREQ_HS & SOSCSEL_SOSCLP);
_FICD( ICS_PGx2 );


#define COUNTC 45 //12 //90 //@ 4MHz 
#define ETIME COUNTC //time in uS
#define COUNT 370 	//@ 4MHz 
#define DELAY for(i=0;i<COUNT;i++)
#define DELAYC for(i=0;i<COUNTC;i++)
#define RCAL 0.03006 //2.983 // 	//R value is 3MΩ approx
					//scaled so that result is in 
					//1/100th of uA
#define ADSCALE 1023 //for unsigned conversion 10 sig bits
#define ADREF  2.4941 //Vdd connected to A/D Vr+
#define home 0x80 //Cursor home
#define line2 0xC0 //Cursor line2


void Print(char* data0);
void PrintF(float num);
void nib_cmd(unsigned char);
void Delay_ms(unsigned int);

void lcd_init();

void initADC(int amask);
int readADC(int ch);

void setup(void);

void convert(int v);

char* CTMUI(float microamps,char *strprt);
char* CTMUCAP(float picof,char *strprt);



int main()

{


int i = 0;
int j = 0; 							//index for loop

DELAYC;


unsigned int Vread = 0;
double VTot = 0;
float Vavg=0, Vcal=0, CTMUISrc = 0; //float values stored for calcs 

TRISB=0;
AD1PCFG=0;

lcd_init();			// LCD initialization
nib_cmd(0x01);		//assume CTMU and A/D have been setup correctly

setup();

while(1)
{

Vread=0;
VTot=0;
									//see Example 11-1 for CTMU & A/D setup
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;
	 						
	IFS0bits.AD1IF = 0; 		//make sure A/D Int not set
	AD1CON1bits.SAMP = 0; 		//and begin A/D conv.
	//DELAY;

while(!IFS0bits.AD1IF); 	//Wait for A/D convert complete
AD1CON1bits.DONE = 0;
	
	CTMUCONbits.EDG1STAT = 0; 	//Stop charging circuit
	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.0000); //Average of 10 readings
Vcal = (float)((Vavg/ADSCALE)*ADREF);
CTMUISrc = Vcal/RCAL; 		//CTMUISrc is in 1/100ths of uA

char s[20];

nib_cmd(home);
Print("CTMUI: "); 
Print(CTMUI(Vcal, s));

i=0;
j=0; //index for loop
Vread = 0;

double CTMUCap=0,time=0,VcTot=0;


setup();
CTMUCONbits.CTMUEN = 1;//Enable the CTMU

for(j=0;j<10;j++)
	{
	Vavg =0; 
	Vcal =0;
	Vread=0;
	CTMUCap=0;
	
	AD1CON1bits.SAMP = 1; //Manual sampling start
	CTMUCONbits.IDISSEN= 1; //drain any charge on the circuit
	
	Delay_ms(50); //wait 62.5 us
	
	
	CTMUCONbits.IDISSEN = 0; 	//end drain of circuit
	CTMUCONbits.EDG1STAT = 1;	//Begin charging the circuit
								//using the CTMU current source
	DELAYC; 						//wait for 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
	VcTot += Vread; 			//Add the reading to the total
}

Vavg = (float)(VcTot/10.000); 				//Average of 10 readings
Vcal = (float)(Vavg/ADSCALE*ADREF);
CTMUCap = (float)((CTMUISrc*ETIME)/Vcal)/100;
												//CTMUISrc is in 1/100ths of uA,
												//calculated in Example 1-2
												//time is in us
												//CTMUCap is in pF

char c[10];
nib_cmd(line2);
Print("Cap: "); 
Print(CTMUCAP(Vcal, c));

}

return(0);
}


char* CTMUI(float microamps,char *strprt)              // convert long to voltage string
{
        int      iw=0,ip=0;
		iw=(long)((float)microamps);
        ip=(long)((float)microamps*1000)-(iw*1000);
        sprintf(strprt,"%d.%d",(int)iw,(int)ip);
        return strprt;
}

char* CTMUCAP(float picof,char *strprt)              // convert long  to voltage string
{
        int      iw=0,ip=0;
		iw=(long)((float)picof);
        ip=(long)((float)picof*1000)-iw*1000;
        sprintf(strprt,"%d.%d",(int)iw,(int)ip);
        return strprt;
}

void setup(void)

{ 

	//CTMUCON - CTMU Control register
   
	//	CTMUCON = 0x89DC; //make sure CTMU is disabled
// CTMU continues to run when emulator is stopped,CTMU continues 
// to run in Idle mode, Time Generation mode enabled, 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 = 0x0300; //55uA, Nominal - No Adjustment


//adc

TRISB=0x0001; // Set channel 2 as an input// Channel 10 here 0x0001
AD1PCFG=0x0002; 
AD1CHS=0X0002; // Select the analog channel(2)
AD1CSSL=0;

AD1CON1 = 0x8000; 	// Turn On A/D Converter, continue in Idle mode,
				//AD1CON1 = 0x00E0;
 			        // Unsigned fractional format, Clear SAMP bit to
				// start conversion, Sample when SAMP bit is set,
				// sampling on hold 
AD1CON2 = 0x2000; 	// VR+ = AVDD, V- = AVSS, Don't scan,0x2000
AD1CON3 = 0x0000;

}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top