Hi guys,
I am currently trying to build a time measurement unit using the CTMU module of a PIC. I noticed that there seems to be some leakage current from the CTMU module whilst enabled but while the EDGE1STAT and EDGE2STAT are not active. Is this correct or am i doing something wrong? below is the code i am using.
I am activating the CTMU module and then setting a pin ( called LED) high which is connected via coax cable to the start and stop pins of the CTMU. This processes works and i get working results, but if i increase the delay time before activating the led pin connected to the coax cable then my results change. Also simply leaving the module active for a while without enabling the LED pin results in a measurable difference and indication of current leakage (which is kinda small but still a problem for me).
I am currently trying to build a time measurement unit using the CTMU module of a PIC. I noticed that there seems to be some leakage current from the CTMU module whilst enabled but while the EDGE1STAT and EDGE2STAT are not active. Is this correct or am i doing something wrong? below is the code i am using.
I am activating the CTMU module and then setting a pin ( called LED) high which is connected via coax cable to the start and stop pins of the CTMU. This processes works and i get working results, but if i increase the delay time before activating the led pin connected to the coax cable then my results change. Also simply leaving the module active for a while without enabling the LED pin results in a measurable difference and indication of current leakage (which is kinda small but still a problem for me).
Code:
#include <xc.h>
#define _XTAL_FREQ 16000000
#define TRUE 1
#define FALSE 0
#define LEDs PORTA
#define LED1 PORTAbits.RA2
#define COUNT 2 //500 //@ 8MHz = 125uS.
#define DELAY for(i=0;i<COUNT;i++)
//#define RCAL 19950 //R value is 19.95Kohm 19950
#define RCAL 1496000 //R value is 19.95Kohm 19950
//scaled so that result is in
//1/100th of uA
#define ADSCALE 4096 //for unsigned conversion 10 sig bits
#define ADREF 2
#define Current3 80 // current was calibrated to 80uA
#define Current1 0.28 // current was calibrated to 0.28uA
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <usart.h>
#include <plib.h>
#include <delays.h>
#include <sw_uart.h>
void IO_ports_init(void)
{
TRISA = 0x00; //set as output
PORTA = 0x00;
TRISB = 0;
//PORTB = 0;
TRISBbits.TRISB2 =1; // input for CTMU 1 edge
TRISBbits.TRISB3=1; // input for CTMU 2 edge
//LATB = 0;
//--ADC
TRISBbits.TRISB0 = 1; //set channel 10 as an input
PORTAbits.RA0 = 0;
LATAbits.LATA0 = 0;
//--UART
TRISCbits.TRISC6 = 0; // RC6 (TX1)
TRISCbits.TRISC7 = 1; //RC7 (RX1)
PORTC=0x00;
PORTD=0x00;
SLRCON = 0x00;
CTMUCONH = 0x00;
RCONbits.IPEN = 1;
INTCONbits.GIEH = 1;
}
void USART_init(void){
TXSTA1 = 0b10100100;
SPBRG1 = 103;
}
void OscillatorConfig(void){
OSCCON = 0b01111100;
OSCCON2 = 0b00010010;
}
void delayMsx(int time){
for(int x = 0; x < time; x++){
__delay_ms(1);
}
}
void delayUsx(int time){
for(int x = 0; x < time; x++){
__delay_us(1);
}
}
void ADCConfig(void){
ANCON1 = 3;
ADCON2bits.ADFM=1; // Result format 1= Right justified
ADCON2bits.ACQT=1; // Acquisition time 7 = 20TAD 2 = 4TAD 1=2TAD
ADCON2bits.ADCS=2; // Clock conversion bits 6= FOSC/64 2=FOSC/32
ADCON1bits.TRIGSEL=1;
ADCON1bits.VCFG0 =0; // Vref+ = AVdd
ADCON1bits.VCFG =2; // Vref+ = AVdd
ADCON1bits.VNCFG = 0; // Vref- = AVss
ADCON0bits.CHS=10; // Select ADC channel
ADCON0bits.ADON=1; // Turn on ADC
}
void CTMUInit (void){
CTMUCONH = 0; //make sure CTMU is disabled
CTMUCONHbits.EDGEN=1; // edge are not blocked
CTMUCONHbits.EDGSEQEN=1; // edge 1 then 2 for interrupt
CTMUCONHbits.CTTRIG=1;
CTMUCONL = 0b11011100; // CTMU trigger setup : net edge 1, neg edge 2, edge 1&2 source select CTED 1&2, clear event bits
CTMUICON = 0b01111111; // 1= base current 0.55uA 2= 5.5uA 3=55uA // max positive trim
}
void CTMU (void){
int Vread;
CTMUCONHbits.CTMUEN = 0;
CTMUCONL = 0b11011100;
LEDs = 0;
CTMUCONHbits.IDISSEN = 1; //drain charge on the circuit
__delay_us(30);
CTMUCONHbits.IDISSEN = 0; //end drain of circuit
CTMUCONHbits.CTMUEN = 1;
__delay_us(500);
LEDs = 255;
PIR1bits.ADIF = 0; //make sure A/D Interupt not set
ADCON0bits.GO=1; //and begin A/D conv.
while(!PIR1bits.ADIF); //Wait for A/D convert complete
Vread = ADRES; //Get the value from the A/D
PIR1bits.ADIF = 0; //Clear A/D Interrupt Flag
char ac_sample_char[12];
char spacer[5];
if(Vread > 10){
sprintf(spacer, " ");
if(Vread > 100){
sprintf(spacer, " ");
if(Vread > 1000){
sprintf(spacer, "");
}
}
}
sprintf(ac_sample_char, "%02d %s - CT1:%01d CT2:%01d E1:%01d E2:%01d", Vread, spacer , PORTBbits.RB2, PORTBbits.RB3 ,CTMUCONLbits.EDG1STAT, CTMUCONLbits.EDG2STAT);
puts1USART(ac_sample_char);
putrs1USART(" \n\r");
}
void CurrentCalibration (void){
int i;
int j = 0; //index for loop
int Vread = 0;
double VTot = 0;
double Vavg=0, Vcal=0, CTMUISrc = 0;
CTMUCONHbits.CTMUEN = 1; //Enable the CTMU
CTMUCONHbits.IDISSEN = 1; //drain charge on the circuit
__delay_ms(1); //wait 125us
CTMUCONHbits.IDISSEN = 0; //end drain of circuit
CTMUCONLbits.EDG1STAT = 1; //Begin charging the circuit
for(j=0;j<10;j++)
{
delayMsx(100); //wait for 125us
PIR1bits.ADIF = 0; //make sure A/D Interupt not set
ADCON0bits.GO=1; //and begin A/D conv.
while(!PIR1bits.ADIF); //Wait for A/D convert complete
Vread = ADRES; //Get the value from the A/D
PIR1bits.ADIF = 0; //Clear A/D Interrupt Flag
VTot = VTot + Vread; //Add the reading to the total
}
CTMUCONLbits.EDG1STAT = 0; //Stop charging circuit
CTMUCONHbits.CTMUEN = 0; //Enable the CTMU
Vavg = (double)(VTot/10); //Average of 10 readings
Vcal = 0.0004882812;
Vcal = (double)Vcal*Vavg;
CTMUISrc = (double)Vcal/RCAL; //CTMUISrc is in 1/100ths of uA
CTMUISrc = CTMUISrc*1000000; // current in uA
char ac_sample_char[12];
sprintf(ac_sample_char, "%0.1f Vavg : %0.3f Voltage : %0.2f CTMUISrc ", Vavg,Vcal,CTMUISrc );
puts1USART(ac_sample_char);
putrs1USART(" \n\r");
}
void CapacitanceCalibration (void){
int i;
int j = 0; //index for loop
int Vread = 0;
float CTMUISrc, CTMUCap, Vavg, VTot, Vcal;
//assume CTMU and A/D have been setup correctly
//see Example 25-1 for CTMU & A/D setup
CTMUCONHbits.CTMUEN = 1; //Enable the CTMU
for(j=0;j<10;j++)
{
CTMUCONHbits.IDISSEN = 1; //drain charge on the circuit
delayUsx(125); //wait 125us
CTMUCONHbits.IDISSEN = 0; //end drain of circuit
CTMUCONLbits.EDG1STAT = 1; //Begin charging the circuit
//using CTMU current source
delayUsx(12); //wait 125us
CTMUCONLbits.EDG1STAT = 0; //Stop charging circuit
PIR1bits.ADIF = 0; //make sure A/D Int not set
ADCON0bits.GO=1; //and begin A/D conv.
while(!PIR1bits.ADIF); //Wait for A/D convert complete
Vread = ADRES; //Get the value from the A/D
PIR1bits.ADIF = 0; //Clear A/D Interrupt Flag
VTot += Vread; //Add the reading to the total
}
Vavg = (double)(VTot/10.000); //Average of 10 readings
Vcal = 0.0004882812;
Vcal = (double)Vcal*Vavg;
CTMUISrc = 0.28; //CTMUISrc is in 1/100ths of uA
CTMUCap = (double)(CTMUISrc*12/Vcal);
char ac_sample_char[12];
sprintf(ac_sample_char, "%0.1f Vavg : %0.3f Voltage : %0.2f CTMUCap ", Vavg,Vcal,CTMUCap );
puts1USART(ac_sample_char);
putrs1USART(" \n\r");
}
/*******************************************/
void main(void) {
OscillatorConfig();
IO_ports_init();
USART_init();
ADCConfig();
CTMUInit();
BAUDCON1bits.BRG16 = 1;
Open1USART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_CONT_RX & USART_BRGH_HIGH, 68); //103 for 16 mhz 51 for 8mhz
RCONbits.IPEN = 1;
INTCONbits.GIEL = 0;
INTCONbits.GIEH = 1;
CTMUCONHbits.CTMUEN = 1;
putrs1USART("Starting \n\r");
while(1)
{
CTMU();
delayMsx(1000);
}
}