时间参数的测量及信号完整性

217 阅读13分钟

一.时间测量单元(QTMU)

  • 时间参数是芯片测试中比较重要的参数类型,也是ATE测试中的难点。许多芯片都需要测试时间参数,如DCDC芯片的PWM频率、占空比,驱动芯片的Tr、Tf、Ton和Toff,芯片内部时钟振荡频率校准等等。那么使用ATE设备的QTMU板卡就能很好地帮助我们测试这些参数。如下链接为STS8200的QTMU板卡资源介绍,此处就不再赘述。 (AccoTEST硬件单板及编程- QTMU_PLUS.pdf)

二.信号完整性

1.什么是信号完整性

  • 信号完整性简单理解就是信号在传送路径上是否“畅通无阻”且没有任何丢失和畸变,信号完整性良好意味着信号在需要时能达到所需的电压电平数值。

2.信号完整性差表现在哪些方面?

  • 信号出现过冲、振铃和抖动

捕获.PNG

  • 时序错误和逻辑误判:由于信号失真,芯片可能会在错误的时刻开始采样,给出错误的响应。从而可能将高电平识别为低电平,将低电平识别为高电平,在ATE测试中,尤其会影响数字向量的测试。
  • 时间参数测量误差偏大:由于高低电平上存在振铃,测量时间参数时,我们设置的触发电平可能和实际的触发电平不吻合,从而导致测试的时间参数误差过大。

3.造成信号完整性差的原因有哪些

  • 阻抗不匹配:哪些地方阻抗不匹配?记住三个点,首先是信号发射端的输出阻抗,其次是信号传输路径上的特征阻抗,最后是信号接收端的输入阻抗。想象一下,信号发射端是水泵,信号传输路径是水管,信号接收端是水龙头,要想使得水能畅通无阻,就得保证三者都没有被“堵住”,这就是阻抗匹配。​​阻抗不匹配通常发生在信号接收端和传输路径之间​​,如果信号接收端阻抗过大,则会导致信号发生反射,从而造成失真。

4.阻抗匹配如何实现

  • 通常和PCB布局相关,通过仿真可以计算出传输路径的特征阻抗。作为ATE工程师,我们不需要有阻抗匹配的Layout能力,我们的工作范畴是在芯片调试过程中发现波形存在失真,从而定位硬件问题。绝对的阻抗匹配也是没有的,硬件工程师能做的只是尽量“足够好”。
  • 那么,如何在阻抗匹配不够出色的情况下,使得信号能尽可能地满足测试的需求?这就不得不提到一个关键的器件:​​Buffer​​。

5.什么是Buffer(电压跟随器),如何利用Buffer测量时间参数

  • Buffer本质是运放的一种,由于其输出端直接和反相输入端相连,使得输入阻抗无穷大,输出阻抗非常低,从而起到将信号缓冲和隔离的作用。虽然Buffer的输入阻抗也是无穷大,但因其不吸收前级电路任何电流,且像一个魔法盒一样能迅速将信号完整吸入并吐出,这和之前提到的用导线来阻抗匹配是不同的(导线很长,就像水流冲很长冲到一面墙上)。值得一提的是,Buffer的阻抗匹配在于输出端,由于输出端几乎无阻抗,所以需要串一个和传输路径相的特征阻抗匹配的电阻(一般是50欧姆左右)。
  • 在芯片时间测量中,我们通常会在QTMU和芯片之间加上Buffer,此时芯片是信号发射端,QTMU是接收端。那么电路设计顺序应该是芯片-Buffer-50欧姆电阻-QTMU;在ACCO的手册里我们也能很容易找到这个方案:

捕获3.PNG

三.时间参数测量代码

1.厂商自带QTMU的例程

{
    //{{AFX_STS_PARAM_PROTOTYPES
    CParam *Freq1 = StsGetParam(funcindex,"Freq1");
    //}}AFX_STS_PARAM_PROTOTYPES

	//for more details, please check STS8200 Programming Manual 7.16.1.1

	double val[4] = {0};
	int i=0;
	
	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_5V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStartTrigger(2, QTMU_PLUS_POS_SLOPE);//trigger=2V, Rising edge
	qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE); //SINGLE_SOURCE
	qtmu0.Connect(); 
	delay_ms(1);
	qtmu0.MeasFreq(QTMU_PLUS_COARSE,QTMU_PLUS_TRNG_US,10,10); //cycle number=10,timeout=10ms
	for(i=0; i<SITENUM; i++ )
	{
		val[i] = qtmu0.GetMeasureResult(i);
		Freq1->SetTestResult(i, 0, val[i]);
	}
	qtmu0.Disconnect(); 

    // TODO: Add your function code here
    return 0;
}

DUT_API int test_Duty(short funcindex, LPCTSTR funclabel)
{
    //{{AFX_STS_PARAM_PROTOTYPES
    CParam *Duty = StsGetParam(funcindex,"Duty");
    //}}AFX_STS_PARAM_PROTOTYPES

	//for more details, please check STS8200 Programming Manual 7.16.2
	
	double val[4] = {0};
	int i=0;
	
	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_5V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE); //SINGLE_SOURCE
	qtmu0.Connect();
	delay_ms(1);
	qtmu0.MeasDC(2, QTMU_PLUS_HIGH_DUTY,10);//trigger=2V, timeout=10ms, read Dutycycle
	for(i=0; i<SITENUM; i++ )
	{
		val[i] = qtmu0.GetMeasureResult(i);
		Duty->SetTestResult(i, 0, val[i]);
	}
	qtmu0.Disconnect(); 
	
    // TODO: Add your function code here
    return 0;
}

DUT_API int test_ChannelSetup(short funcindex, LPCTSTR funclabel)
{
    //{{AFX_STS_PARAM_PROTOTYPES
    CParam *Freq2 = StsGetParam(funcindex,"Freq2");
    //}}AFX_STS_PARAM_PROTOTYPES

	//for more details, please check STS8200 Programming Manual 7.16.1.2

	double f[4] = {0};
	int i=0;
	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_5V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_5V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStartTrigger(1.5,QTMU_PLUS_POS_SLOPE);//CHA trigger level=1.5V, Rising edge
	qtmu0.SetStopTrigger(1.5,QTMU_PLUS_POS_SLOPE);//CHB trigger level=1.5V, Rising edge
	qtmu0.SetInSource(QTMU_PLUS_DUAL_SOURCE);//DUAL_SOURCE
	qtmu0.ChannelSetup(QTMU_PLUS_CHA_STOP); //select CHB to read Freq
	qtmu0.Connect(); 
	delay_ms(1);
	qtmu0.MeasFreq(QTMU_PLUS_COARSE,QTMU_PLUS_TRNG_US,5,1);//cycle number=5,timeout=1ms
	for(i=0; i<SITENUM; i++)
	{
		f[i] = qtmu0.GetMeasureResult(i);
		Freq2->SetTestResult(i, 0, f[i]);
	}
	qtmu0.ChannelSetup(QTMU_PLUS_CHA_START);//select CHA to read Freq
	qtmu0.Disconnect(); 
	
    // TODO: Add your function code here
    return 0;
}

DUT_API int test_TrTf(short funcindex, LPCTSTR funclabel)
{
    //{{AFX_STS_PARAM_PROTOTYPES
    CParam *Tr1 = StsGetParam(funcindex,"Tr1");
    CParam *Tr2 = StsGetParam(funcindex,"Tr2");
    //}}AFX_STS_PARAM_PROTOTYPES

	//for more details, please check STS8200 Programming Manual 7.16.3

	///////////////////////////////// for Tr/Tf test ////////////////////////////////////
	
	double val[4] = {0};
	int i=0;
	
	/////////////////////////periodic signal: Meas////////////////////////////////////
	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStartTrigger(2.1,QTMU_PLUS_POS_SLOPE);//trigger=2.1V, Rising edge
	qtmu0.SetStopTrigger(13.3,QTMU_PLUS_POS_SLOPE);//trigger=13.3V, Rising edge
	qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE); //SINGLE_SOURCE
	qtmu0.Connect(); 
	delay_ms(1);
	qtmu0.Meas(QTMU_PLUS_COARSE, QTMU_PLUS_TRNG_US,10);  //timeout=10ms
	for(i=0; i<SITENUM; i++ )
	{
		val[i] = qtmu0.GetMeasureResult(i);
		Tr1->SetTestResult(i, 0, val[i]);
	}
	qtmu0.Disconnect(); 
	
	
	
	
    /////////////////////aperiodic signal: SinglePlsMeas/////////////////////
	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStartTrigger(2.1,QTMU_PLUS_POS_SLOPE);//trigger=2.1V, Rising edge
	qtmu0.SetStopTrigger(13.3,QTMU_PLUS_POS_SLOPE);//trigger=13.3V, Rising edge
	qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);//SINGLE_SOURCE
	qtmu0.Connect(); 
	delay_ms(1);
	qtmu0.SetSinglePulseMeas(QTMU_PLUS_COARSE,QTMU_PLUS_TIME_US,0);
	qtmu0.SetTimeOut(10);//timeout=10ms

	//set the trigger signal here
	
	qtmu0.SinglePlsMeas(0); 
	for(i=0; i<SITENUM; i++ )
	{
		val[i] = qtmu0.GetMeasureResult(i);
		Tr2->SetTestResult(i, 0, val[i]);
	}
	qtmu0.Disconnect(); 

    // TODO: Add your function code here
    return 0;
}


DUT_API int test_TPLH(short funcindex, LPCTSTR funclabel)
{
    //{{AFX_STS_PARAM_PROTOTYPES
    CParam *TPLH1 = StsGetParam(funcindex,"TPLH1");
    CParam *TPLH2 = StsGetParam(funcindex,"TPLH2");
    //}}AFX_STS_PARAM_PROTOTYPES

	//for more details, please check STS8200 Programming Manual 7.16.4 and 7.16.5

	///////////////////////////////// for time interval test ////////////////////////////////////
	
	double val[4] = {0};
	int i=0;

	///////////////////////// periodic signal: Meas ////////////////////////////////////
	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStartTrigger(2.5,QTMU_PLUS_NEG_SLOPE);//trigger=2.5V, Falling edge
	qtmu0.SetStopTrigger(7.7,QTMU_PLUS_POS_SLOPE);//trigger=7.7V, Rising edge
	qtmu0.SetInSource(QTMU_PLUS_DUAL_SOURCE); //DUAL_SOURCE
	qtmu0.Connect(); 
	delay_ms(1);
	qtmu0.Meas(QTMU_PLUS_COARSE, QTMU_PLUS_TRNG_US,10);  //timeout=10ms
	for(i=0; i<SITENUM; i++ )
	{
		val[i] = qtmu0.GetMeasureResult(i);
		TPLH1->SetTestResult(i, 0, val[i]);
	}
	qtmu0.Disconnect(); 	


	///////////////////// aperiodic signal: SinglePlsMeas /////////////////////
	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStartTrigger(2.5,QTMU_PLUS_NEG_SLOPE);//trigger=2.5V, Falling edge
	qtmu0.SetStopTrigger(7.7,QTMU_PLUS_POS_SLOPE);//trigger=7.7V, Rising edge
	qtmu0.SetInSource(QTMU_PLUS_DUAL_SOURCE); 
	qtmu0.Connect(); 	
	delay_ms(1);
	qtmu0.SetSinglePulseMeas(QTMU_PLUS_COARSE,QTMU_PLUS_TIME_US,0);
	qtmu0.SetTimeOut(10); //timeout=10ms

	//set the trigger signal here

	qtmu0.SinglePlsMeas(0); 
	for(i=0; i<SITENUM; i++ )
	{
		val[i] = qtmu0.GetMeasureResult(i);
		TPLH2->SetTestResult(i, 0, val[i]);
	}
	qtmu0.Disconnect(); 

	// TODO: Add your function code here
	return 0;
}


DUT_API int test_SerialTest(short funcindex, LPCTSTR funclabel)
{
	//{{AFX_STS_PARAM_PROTOTYPES
    CParam *Tr = StsGetParam(funcindex,"Tr");
	//}}AFX_STS_PARAM_PROTOTYPES

	//for more details, please check STS8200 Programming Manual 7.16.6

	int i=0;
	double val[4]={0.0};

	qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M,QTMU_PLUS_VRNG_25V,QTMU_PLUS_FILTER_PASS);
	qtmu0.SetStartTrigger(2.1,QTMU_PLUS_POS_SLOPE);
	//trigger=2.1V, Rising edge
	qtmu0.SetStopTrigger(13.3,QTMU_PLUS_POS_SLOPE);
	//trigger=13.3V, Rising edge
	qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);//SINGLE_SOURCE
	qtmu0.Connect(); 
	delay_ms(1);
	qtmu0.SetSinglePulseMeas(QTMU_PLUS_FINE,QTMU_PLUS_TIME_NS,i);

	dvi0.Set(FV, 5, DVI400_20V,DVI400_40MA,RELAY_ON);
	delay_ms(1);
	for(i=0; i<SITENUM; i++)
	{
		BEGIN_SINGLE_SITE(i)

		qtmu0.SetTimeOut(10);//timeout=10ms

		//trigger signal A
		dvi0.Set(FV, 5, DVI400_20V,DVI400_40MA,RELAY_ON);
		delay_ms(1);
		dvi0.Set(FV, 0, DVI400_20V,DVI400_40MA,RELAY_ON);

		qtmu0.SinglePlsMeas(i); 
		val[i] = qtmu0.GetMeasureResult(i);
		Tr->SetTestResult(i, 0, val[i]);

		END_SINGLE_SITE()
	}

	qtmu0.Disconnect();


    // TODO: Add your function code here
    return 0;
}

2.带详细注释的QTMU代码

//1、逻辑通道
QTMU_PLUS qtmu(0); //单板8通道,每两个通道为一组1→A,B
StsSetModuleToSite(MD_QTMUPLUS, SITE_1, 0, -1);  //0A,0B
StsSetModuleToSite(MD_QTMUPLUS, SITE_2, 1, -1);  //1A,1B	
StsSetModuleToSite(MD_QTMUPLUS, SITE_3, 2, -1);  //2A,2B
StsSetModuleToSite(MD_QTMUPLUS, SITE_4, 3, -1);  //3A,3B


//使用QTMU最重要一点:
//COMP1和COMP2都可以用,只是单通道和双通道的区别:单通道时,COMP1和COMP2都触发时,可以测量两个点的时间(同一个波形);
//双通道时,COMP1和COMP2都触发,可以测量两个通道的时间


//2、使用:一个周期信号的频率测量(使用CHA)
//(chaA:SetStartInput、SetStartTrigger  chaB:SetStopInput、SetStopTrigger)
//从A开始,到B结束(或者反过来),当A接到B时,用于测A和B通道的传输延时,当A不接到B时,两个通道可以单独使用(频率、占空比、上升下降时间等)
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  //设置CHA信号输入模式
//阻抗 量程 滤波器频率(方波不使用滤波器:FILTER_PASS直通) 
qtmu0.SetStartTrigger(15, QTMU_PLUS_POS_SLOPE);   //内部比较器COM1的触发电平和极性(15V一定是处于沿上,上升沿、下降沿)
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE); //信号源选择,SINGLE_SOURCE:使用chA;DUAL_SOURCE:使用A和B
qtmu0.ChannelSetup(QTMU_PLUS_CHA_START); //选择A或B作为Start信号,CHA_STOP为B_Start,CHA_START为A_Start
qtmu0.Connect();
delay_ms(1);
qtmu0.MeasFreq(QTMU_PLUS_COARSE, QTMU_PLUS_TIME_US, 4, 10); //测量周期信号的频率,COARSE低分辨率,FINE高分辨率,待测周期数,测量等待时间
for(i=0;i<SITENUM;i++)
{
	freq_cha[i] = qtmu0.GetMeasureResult(i);
	Freq_A->SetTestResult(i, 0, freq_cha[i]);
}

qtmu0.Disconnect();

//3、使用:一个周期信号的频率测量(使用CHB)
qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS); //区别1:SetStopInput
qtmu0.SetStopTrigger(15, QTMU_PLUS_POS_SLOPE);   //区别2:SetStopTrigger
qtmu0.SetInSource(QTMU_PLUS_DUAL_SOURCE);   //区别3:DUAL_SOURCE:使用A和B
qtmu0.ChannelSetup(QTMU_PLUS_CHA_STOP);     //区别4:CHA_STOP使用CHB作为START信号	
qtmu0.Connect();
delay_ms(1);
qtmu0.MeasFreq(QTMU_PLUS_COARSE, QTMU_PLUS_TIME_US, 4, 10);
for(i=0;i<SITENUM;i++)
{
	freq_chb[i] = qtmu0.GetMeasureResult(i);
	Freq_B->SetTestResult(i, 0, freq_chb[i]);
}

qtmu0.Disconnect();

//4、使用:测试周期信号的占空比
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);
qtmu0.Connect();
delay_ms(1);
qtmu0.MeasDutyCycle(2, QTMU_PLUS_HIGH_DUTY,10);  //触发电平(相当于节约Trigger语句),高于50%使用HIGH,低于使用LOW
for(i=0; i<SITENUM; i++ )
{
	val[i] = qtmu0.GetMeasureResult(i);
	Duty->SetTestResult(i, 0, val[i]);
}
qtmu0.Disconnect();

//5、使用:测试OUT端周期信号的上升沿时间(设低电平为1V,高电平为5V)
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);
qtmu0.SetStartTrigger(0.4, QTMU_PLUS_POS_SLOPE);  //触发电平0.4(start_point)>=(5-4)*10%
qtmu0.SetStopTrigger(3.6, QTMU_PLUS_POS_SLOPE);   //触发电平3.6(stop_point)<=(5-4)*90%
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);   
qtmu0.Connect();
delay_ms(1);
qtmu0.Meas((QTMU_PLUS_COARSE, QTMU_PLUS_TIME_US, 10); //测量等待时间10mS//周期信号测时间只有Meas函数
for(i=0; i<SITENUM; i++ )
{
	val[i] = qtmu0.GetMeasureResult(i);
	Tr->SetTestResult(i, 0, val[i]);
}
qtmu0.Disconnect();


//*6、使用:非周期信号的上升沿时间(设待测信号CH2低电平为1V,高电平为5V,CH1从0V上到5V时,测量CH2的上升沿时间)
CH1.Set(FV, 0 ,FOVI_10V, FOVI_100MA, RELAY_ON); 
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);
qtmu0.SetStartTrigger(0.4, QTMU_PLUS_POS_SLOPE);  //触发电平0.7(start_point)>(5-4)*10%
qtmu0.SetStopTrigger(3.6, QTMU_PLUS_POS_SLOPE);   //触发电平3.4(stop_point)<(5-4)*90%
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);   
qtmu0.Connect();
delay_ms(1);
qtmu0.SetSinglePulseMeas(QTMU_PLUS_COARSE, TIME_US, 0);//非周期测量语句组1/3//非周期启动函数:分辨率 档位NS和US 工位(COAR
qtmu0.SetTimeOut(10);//非周期测量语句组2/3//测量等待时间设置
CH1.Set(FV, 5 ,FOVI_10V, FOVI_100MA, RELAY_ON); 

qtmu0.SinglePlsMeas(0); //非周期测量语句组3/3 //非周期时间测量启动//分辨率//档位
for(i=0; i<SITENUM; i++ )
{
	val[i] = qtmu0.GetMeasureResult(i);
	Tr->SetTestResult(i, 0, val[i]);
}
qtmu0.Disconnect();

//7、使用:周期信号的高电平时间(低电平0V,高电平5V)
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);
qtmu0.SetStartTrigger(2.6, QTMU_PLUS_POS_SLOPE);  //触发电平2.6(start_point)>(5-0)*50%
qtmu0.SetStopTrigger(2.6, QTMU_PLUS_POS_SLOPE);   //触发电平2.6(stop_point)>(5-0)*50%	
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);
qtmu0.Connect();
delay_ms(1);
qtmu0.Meas((QTMU_PLUS_COARSE, QTMU_PLUS_TIME_US,0); //测量等待时间0mS//周期信号测时间只有Meas函数
for(i=0; i<SITENUM; i++ )
{
	val[i] = qtmu0.GetMeasureResult(i);
	TH->SetTestResult(i, 0, val[i]);
}
qtmu0.Disconnect();

//8、使用:非周期信号的高电平时间(低电平0V,高电平5V)
CH1.Set(FV, 0 ,FOVI_10V, FOVI_100MA, RELAY_ON); 
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);
qtmu0.SetStartTrigger(2.6, QTMU_PLUS_POS_SLOPE);  //触发电平2.6(start_point)>(5-0)*50%
qtmu0.SetStopTrigger(2.6, QTMU_PLUS_POS_SLOPE);   //触发电平2.6(start_point)>(5-0)*50%	
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);
qtmu0.Connect();
delay_ms(1);
qtmu0.SetSinglePulseMeas(QTMU_PLUS_COARSE, TIME_US, 0);//非周期测量语句组1/3//非周期启动函数:分辨率 档位NS和US 工位
qtmu0.SetTimeOut(10);//非周期测量语句组2/3//测量等待时间设置
CH1.Set(FV, 5 ,FOVI_10V, FOVI_100MA, RELAY_ON);  
delay_ms(3);

qtmu0.SinglePlsMeas(0); //非周期测量语句组3/3 //非周期时间测量启动//分辨率//档位

for(i=0; i<SITENUM; i++ )
{
	val[i] = qtmu0.GetMeasureResult(i);
	TH->SetTestResult(i, 0, val[i]);
}
qtmu0.Disconnect();


//9、使用:两个周期信号OUT1和OUT2的传输延时(CHA(0,5),CHB(0,7))
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  //设置CHA信号输入模式
qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  //设置CHB信号输入模式
qtmu0.SetStartTrigger(2.5, QTMU_PLUS_POS_SLOPE);  //触发电平2.5(start_point)>(5-0)*50%
qtmu0.SetStopTrigger(3.5, QTMU_PLUS_POS_SLOPE);   //触发电平3.5(stop_point)>(7-0)*50%
qtmu0.SetInSource(QTMU_PLUS_DUAL_SOURCE);   //双通道
qtmu0.ChannelSetup(QTMU_PLUS_CHA_STOP);  //选择B为开始,A为停止,不加该句为默认A开始,B结束(*判断两个波形需要比较的两个点前后顺序)
qtmu0.Connect();
delay_ms(1);
qtmu0.Meas((QTMU_PLUS_COARSE, QTMU_PLUS_TIME_US,0);

for(i=0; i<SITENUM; i++ )
{
	val[i] = qtmu0.GetMeasureResult(i);
	TPLH->SetTestResult(i, 0, val[i]);
}

qtmu0.ChannelSetup(QTMU_PLUS_CHA_START);   //恢复A为开始
qtmu0.Disconnect();

//10、使用:非周期信号之间的传输延时
CH1.Set(FV, 0 ,FOVI_10V, FOVI_100MA, RELAY_ON); 
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  //设置CHA信号输入模式
qtmu0.SetStopInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  //设置CHB信号输入模式
qtmu0.SetStartTrigger(2.5, QTMU_PLUS_POS_SLOPE);  //触发电平2.5(start_point)>(5-0)*50%
qtmu0.SetStopTrigger(3.5, QTMU_PLUS_POS_SLOPE);   //触发电平3.5(stop_point)>(7-0)*50%
qtmu0.SetInSource(QTMU_PLUS_DUAL_SOURCE);   //双通道
qtmu0.ChannelSetup(QTMU_PLUS_CHA_STOP);  //选择B为开始,A为停止,不加该句为默认A开始,B结束(*判断两个波形需要比较的两个点前后顺序)
qtmu0.Connect();
delay_ms(1);

qtmu0.SetSinglePulseMeas(QTMU_PLUS_COARSE, TIME_US, 0);//非周期测量语句组1/3//非周期启动函数:分辨率 档位NS和US 工位
qtmu0.SetTimeOut(10);//非周期测量语句组2/3//测量等待时间设置
CH1.Set(FV, 5 ,FOVI_10V, FOVI_100MA, RELAY_ON);  

qtmu0.SinglePlsMeas(0); //非周期测量语句组3/3 //非周期时间测量启动//分辨率//档位

for(i=0; i<SITENUM; i++ )
{
	val[i] = qtmu0.GetMeasureResult(i);
	TPLH->SetTestResult(i, 0, val[i]);
}

qtmu0.ChannelSetup(QTMU_PLUS_CHA_START);   //恢复A为开始
qtmu0.Disconnect();

//11、使用:捕获一个周期信号的跳变时刻(第一个下降沿跳变记录为时刻T0=0,第二个上升沿跳变记录为T1=TL(低电平时间)...以此类推)
double Tevent[3][site_num]={ 0 };  //二维数组第一个参数为第几个跳变时刻,第二个参数为site
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  //设置CHA信号输入模式
qtmu0.SetStartTrigger(2, QTMU_PLUS_POS_SLOPE);  //trigger_point=2
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);   //单通道
qtmu0.Connect();
delay_ms(1);

qtmu.EventCounter(3,10);  //捕获3个点,测量等待延时10ms

for(int SITEID=0; SITEID<site_num; SITEID++)
{
	for(int i=0; i<3; i++)
	{
		Tevent[i][SITEID]=qtmu0.GetEventMeasureResult(SITEID, i);
	}
	T1->SetTestResult(i, 0, Tevent[0][SITEID]);
	T2->SetTestResult(i, 0, Tevent[1][SITEID]);	
}

	

//12、使用:捕获一个非周期信号的5个跳变时刻
double Tevent[5][site_num]={ 0 }; 
EN.Set(FV, 0 ,FOVI_10V, FOVI_100MA, RELAY_ON); 
qtmu0.SetStartInput(QTMU_PLUS_IMPEDANCE_1M, QTMU_PLUS_VRNG_25V, QTMU_PLUS_FILTER_PASS);  //设置CHA信号输入模式
qtmu0.SetStartTrigger(2, QTMU_PLUS_POS_SLOPE);  //trigger_point=2
qtmu0.SetInSource(QTMU_PLUS_SINGLE_SOURCE);   //单通道
qtmu0.Connect();
delay_ms(1);
qtmu0.SetSinglePulseEventCounter(5);//非周期测量语句组1/3//非周期启动函数:分辨率 档位NS和US 工位
qtmu0.SetTimeOut(100);//非周期测量语句组2/3//测量等待时间设置
EN.Set(FV, 5 ,FOVI_10V, FOVI_100MA, RELAY_ON);  

qtmu0.SinglePlsEventCounter(); //非周期测量语句组3/3 //非周期时间测量启动//分辨率//档位

for(int SITEID=0; SITEID<site_num; SITEID++)
{
	for(int i=0; i<5; i++)
	{
		Tevent[i][SITEID]=qtmu0.GetEventMeasureResult(SITEID, i);
	}
	T1->SetTestResult(i, 0, Tevent[0][SITEID]);
	T2->SetTestResult(i, 0, Tevent[1][SITEID]);	
}

***注*:以上代码如需搬运,需经过本人同意。*