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.

dsPIC CTMU does not give sensible readings

Status
Not open for further replies.

FoxyRick

Advanced Member level 4
Joined
Jan 8, 2004
Messages
1,249
Helped
321
Reputation
640
Reaction score
277
Trophy points
1,373
Location
England, UK
Activity points
12,979
Can someone help me solve the following please:

I'm trying to measure the time between the rising edges on two equal frequency, slow (~2Hz), almost in phase square waves. They are within about 500nS but can go down to almost 0ns. One has a random jitter of +/-25ns, the other <<1ns and signal 1 normally leads signal 2 (I can adjust the phase difference for testing). A dsPIC with CTMU seems ideal and I'm using one in the circuit anyway: dsPIC33EP128MC202

I've been at it for two days, going around in circles, re-reading all the datasheets, trying all sorts of variations and repeating the tests. No matter what I try I can't seem to get a sensible response from the CTMU/ADC. It always does the same thing:

It seems to be basically working, but the readings just don't make sense. In particular, when I lower the pulse separation from 400ns to zero, the ADC readings don't really change accordingly although they do get lower.

With a 5.5uA current, and with the ADC (+stray) capacitance of ~5pf, I should get an ADC reading of ~0.44V = 136 counts (3.3V supply, 10 bits, V=T.I/C). I get around 350 counts.

With the current set at 0.55uA, which should give a tenth of that, I get readings around 270 for 400nS. Setting 55uA makes the ADC go full scale instantly. As I bring the pulse difference down to zero, the ADC reading gets to around 180 counts (regardless of the current) before the pulses reverse and the ADC goes full scale as expected. :???:

Discharge time for the sampling capacitor makes no difference; I've tried adjusting that too.

Below is the reduced (and now somewhat messy looking) code I've done for testing, along with an output log from a constant ~400ns (with jitter) pulse separation, and a log where I slowly ramp Pulse_2 closer to Pulse_1, eventually swapping order. Note that I've written the code in CCS C, but I also rewrote it with xc16 last night and got the same results (although for some reason (bug?) in xc16 the CTMU will not trigger the ADC to read, despite setting the registers correctly and the CTMU functioning as expected otherwise. I had to read the ADC manually).

The pulses were observed on a 200MHz oscilloscope throughout. The waves are nice and clean and I can't see anything in the signals to explain the above.

Code:
// Include file not shown but has nothing of relevance to the issue 
// CTMUICON bits
#word CTMUICON = getenv("SFR:CTMUICON")

// CTMUCON1 bits
#word CTMUCON1 = getenv("SFR:CTMUCON1")
#bit CTMUEN = getenv("BIT:CTMUEN")		// Enable CTMU
#bit CTMUSIDL = getenv("BIT:CTMUSIDL")
#bit TGEN = getenv("BIT:TGEN")
#bit EDGEN = getenv("BIT:EDGEN")		// 0 = Software, 1 = Hardware edges
#bit EDGSEQEN = getenv("BIT:EDGSEQEN")		// 1 = Edge 1 must occur before Edge 2
#bit IDISSEN = getenv("BIT:IDISSEN")		// Enable current discharge
#bit CTTRIG = getenv("BIT:CTTRIG")		// CTMU triggers ADC

// CTMUCON2 bits
#word CTMUCON2 = getenv("SFR:CTMUCON2")
#bit EDG1STAT = getenv("BIT:EDG1STAT")
#bit EDG2STAT = getenv("BIT:EDG2STAT")

// ADC Registers
#word AD1CON1 = getenv("SFR:AD1CON1")
#bit ADON = AD1CON1.15				// Enable ADC
#bit SAMP = AD1CON1.1				// 1=Sampling, 0=Holding
#bit DONE = AD1CON1.0				// 1=Conversion finished
#word AD1CON2 = getenv("SFR:AD1CON2")
#word AD1CON3 = getenv("SFR:AD1CON3")
#word AD1CHS0 = getenv("SFR:AD1CHS0")
#word ADCBUF  = getenv("SFR:ADC1BUF0")

long int CTMUvalue;

// Initialise the CTMU
void initCTMU() {
	CTMUICON  = 0b0000000100000000;	// 0.55uA, no trim
	CTMUCON2  = 0b1100110011001100;	// Rising Edges, CTED1=Pulse_1, CTED2=Pulse_2
	CTMUCON1  = 0b0000010100000000;	// CTMU Off, EDGSEQEN, CTTRIG
  	
	AD1CON1   = 0b0000000011000000;	// 10-bit, CTMU triggers conversion
	AD1CON2   = 0;					// Supplyr rail Vrefs, CH0
	AD1CON3   = 0b0000000000000101;	// ADC uses system clock, (5+1)*Tcy=120ns
	AD1CHS0   = 0b0001111100011111;	// ADC MUX to Open for CTMU
  	
	ADON=1;		// Enable ADC
	SAMP=1;		// Set ADC to Sampling
	IDISSEN=1;	// Ground the current source
	delay_us(100);	// Time to discharge the sample capacitor
	IDISSEN=0;	// Disable discharge
	CTMUEN=0;	// Disable CMTU
	CTMUCON2=0b1100110011001100;	// Reset EDGxSTAT
	EDGEN=1;	// Enable hardware edges
	CTMUEN=1;	// Enable CTMU
}



#int_CTMU
void CTMU_Interrupt(void) {
	if (EDG1STAT && EDG2STAT) {
		while (!DONE) {}
		DONE=0;	// Clear ADC done flag
		CTMUvalue = ADCBUF;
		printf("%lu\r\n",CTMUvalue);
		
		// Reset for next trigger
		CTMUEN=0;	// Disable CTMU
		SAMP=1;		// Set ADC to Sampling
		IDISSEN=1;	// Ground the current source
		delay_us(100);	// Time to discharge the sample capacitor
		IDISSEN=0;	// Disable discharge
		CTMUCON2  = 0b1100110011001100;	// Reset EDGxSTAT
		CTMUEN=1;	// Enable CTMU
	}
}



void main() {
	setup_oscillator(OSC_CLOCK,100000000,10000000);
	#use delay(clock=100000000)

	set_uart_speed(57600,UART_PORT1,100000000);
	printf("\r\nI'm Alive\r\n");

	enable_interrupts(INT_CTMU);
	enable_interrupts(GLOBAL);
  		
	initCTMU();
  	
	while (1) {	}
}


Code:
0.55uA current. Pulse_2 lags Pulse_1 by about 400nS with 20nS jitter.

ADC Counts
----------
270
270
268
269
267
271
... continues similar to above



0.55uA Current, bringing Pulse 2 gradually closer to Pulse 1 until they are in phase and then swap order.

ADC		Lag, ns
counts		(approx)
------		-----
242		400
268
276
228
253	
251
256		300
221
245
250
208
233
201		200
228
222
237
192
215
214		100
184
212
217
174
195
165		0 
...		reverses order
1022
...
1023
...
the pulses reverse order and the readings go full scale every other pair
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top