写程序来控制函数发生器来输出任意波形


前言

提示: 之前查找很多资料,都是国外的,怎么用c语言和c++来控制函数发生器输出任意波,搞了很久才弄明白怎么一回事。具体可以看我之前写的文章,里面有详细的安装方式,软件和函数发生器的使用。这是只是告诉大家怎么用c语言实现任意波。

一、函数发生器是什么?

它可以生成任意波形,是一个功能十分强大的仪器,我这里使用的是,德州的335xx系列的产品,输出的任意波的格式为arb格式,之前老版本的仪器用的格式为prn格式,大同小异。问题不大。

二、使用步骤

1.直接上程序,加载任意波的文件用的

代码如下(示例):

 #include <iostream.h>
#include <stdio.h>
#include "visa.h"
#include <afx.h>
ViStatus errStatus=0;
char cycle=1;
BOOL Output(ViSession vi,CString channel,CString filename)			//指定通道输出目标arb文件波形
{
    CString str;														//创建字符串str存放仪器指令
	if(vi)															//判断仪器连接状态
	{
		str="MMEM:LOAD:DATA"+channel+" \"INT:\\"+filename+"\"\n";	//合成指令存放在str中,指令功能为将发生器中要输出的arb文件加载到指定通道的易失存储器中,其中channel存放的通道号,filename存放的arb文件名。
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
		if(VI_SUCCESS!=errStatus)
		return FALSE;

		Sleep(1000);		
		str="SOUR"+channel+":FUNC ARB\n";							//合成指令存放在str中,指令功能为设置指定通道的输出波形类型为任意波
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
		if(VI_SUCCESS!=errStatus)  
		return FALSE;
		
		Sleep(1000);
        str="SOUR"+channel+":FUNC:ARB \"INT:\\"+filename+"\"\n";	//合成指令存放在str中,指令功能为选中要输出的波形,channel存放的通道号,filename存放的arb文件名。
	    errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
	    if(VI_SUCCESS!=errStatus)  
		return FALSE;

		str="OUTP"+channel+" 1\n";									//合成指令存放在str中,指令功能为指定通道输出
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
		Sleep(1000);
		if(VI_SUCCESS!=errStatus)  
		return FALSE;

		return TRUE;
	}
	return FALSE;
}
CString LoadData(CString path)							//加载path文件,将文件中所有内容形成字符串并返回
{
	CString str;										//创建字符串str,用来存放文件的一行内容
	CString strcommand;									//创建字符串str,用来存放文件的所有内容
	CStdioFile myfile;
	cout<<"数据加载中..."<<endl;
	if(myfile.Open(path,CFile::typeText|CFile::modeNoTruncate|CFile::modeRead|CFile::modeCreate))//打开文件
	{	
		myfile.ReadString(str);							//读取文件一行内容放在str中
        while(str!="")									//读到文件末尾停
		{
			str+="\n";									//每行字符串末尾加上换行
			strcommand+=str;							//将新读的一行加到字符串strcommand末尾
		    myfile.ReadString(str);	
		}
		strcommand+="\n";								//strcommand末尾加上回车
		myfile.Close();									//关闭文件
	}
	return strcommand;
}
BOOL SendArbWaveform(ViSession vi,CString strCommand,CString path)	//给仪器发送数据
{
   CString str,Count,Length;										//由于仪器指令需要,创建字符串str存放仪器指令,Length存放字符串的字符个数,Count存放Length的位数
   int count=1;														//位数默认值为1
   int length=strCommand.GetLength();								//获取字符串字符数
   while(length/10>=1)												//计算位数
   {
	length=length/10;
	count++;
   }
	cout<<"数据发送中..."<<endl;
	str="MMEM:DOWN:FNAM \"INT:\\"+path+"\"\n";						//将指令合成存放在str中,这条指令的功能是在信号发生器中INT路径下创建同名arb文件。其中path存放的是计算机中arb文件的名字(包括后缀)					
	if(vi)															//仪器连接中
	{	
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength())); 		//发送指令给仪器
		if(VI_SUCCESS!=errStatus)  
			return FALSE;
		Count.Format("%d",count);									//将位数的类型转化为字符串用于指令合成
		Length.Format("%d",strCommand.GetLength());					//将字符数的类型转化为字符串用于指令合成
	
		str="MMEM:DOWN:DATA #"+Count+Length+strCommand+"\n";		//指令合成存放在str中,将字符串strCommand内容存放在上一步指定的文件中。

		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//发送指令给仪器
		if(VI_SUCCESS!=errStatus)
			return FALSE;
		return TRUE;
	}
	return FALSE;
}

void main()
{
	char Uamx_Uo;
	ViSession viDefaultRM=NULL;
	ViSession vi;
	char channel;
	unsigned long iret=0;
	unsigned char buf[100];
	//CString strData,filename,str,filepath,strAddress="TCPIP::169.254.5.21::5025::SOCKET";
	CString strData,filename,str,filepath,strAddress="TCPIP::192.168.0.88::5025::SOCKET";//仪器地址
	cout<<strAddress<<endl;
	errStatus=viOpenDefaultRM(&viDefaultRM);
	if(VI_SUCCESS!=errStatus)
		return;
	errStatus=viOpen(viDefaultRM,strAddress.GetBuffer(strAddress.GetLength()+1),VI_NULL,VI_NULL,&vi);//打开会话
	if(VI_SUCCESS!=errStatus)
	{
		viClose(viDefaultRM);
		return;
	}
	viPrintf(vi, "*RST\n");								//初始化器件
	
	cout<<"请输入:输出通道(1)或者输出通道(2)"<<endl;	//提示设置输出通道,输入1则通道1输出,输入2则通道2输出
	cin>>channel;										//将输入放入channel中

	//从示波器中选择任意波形
	Uamx_Uo = 8;
	switch(Uamx_Uo)
	{
		case 1:	filename="GRB_170mv_5s.arb";break;//合格,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 3:	filename="GRB_5S_10KSa_3-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 4:	filename="GRB_5S_10KSa_4-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 6:	filename="GRB_5S_10KSa_6-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 8:	filename="GRB_5S_10KSa_8-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
	}
 
	viPrintf(vi,"MMEM:CAT:DATA:ARBitrary?\n");			//查询仪器中所有文件名
	//str="MMEM:CAT:DATA:ARBitrary?""Int:\Builtin\n";
	//viPrintf(vi,str.GetBuffer(str.GetLength()));
	viRead(vi,buf,100,&iret);							//将返回的信息存放在buf数组中
    filepath=buf;										//buf数组的信息放入字符串filepath中,便于查询输出文件是否存在

	if(strstr(filepath,filename))						//查询仪器内部是否有目标输出文件
	{
		cout<<"文件存在,开始输出"<<endl;
		if(Output(vi,channel,filename))					//调用Output函数输出
			cout<<"输出波形数据成功"<<endl;
		else
			cout<<"输出波形数据失败"<<endl;
	}	
	else
	{
		 
		cout<<"文件不存在,请先下载到信号发生器"<<endl;
		strData=LoadData(filename);//调用LoadData函数,将arb文件内容提取存放在字符串中
		if(SendArbWaveform(vi,strData,filename))				//调用SendArbWaveform函数,发送波形数
		{
		    cout<<"文件装载成功"<<endl;
			if(Output(vi,channel,filename))					//调用Output函数输出
			cout<<"输出波形数据成功"<<endl;
		    else
			cout<<"输出波形数据失败"<<endl;
		}
		else
		{
		    cout<<"文件装载失败"<<endl;
		}
	}
	  
	if(vi)												//仪器连接未关
	{
		viClose(vi);									//关闭与仪器的连接
		viClose(viDefaultRM);
	}
	
	
}

2.用函数发生器合成任意波文件

代码如下(示例):

 #include <iostream.h>
#include <stdio.h>
#include "visa.h"
#include <afx.h>
ViStatus errStatus=0;
char cycle=1;
BOOL Output(ViSession vi,CString channel,CString filename)			//指定通道输出目标arb文件波形
{
    CString str;														//创建字符串str存放仪器指令
	if(vi)															//判断仪器连接状态
	{
		/*从内存加载文件*/
		str="MMEM:LOAD:DATA"+channel+" \"INT:\\"+filename+"\"\n";	//合成指令存放在str中,指令功能为将发生器中要输出的arb文件加载到指定通道的易失存储器中,其中channel存放的通道号,filename存放的arb文件名。
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
		if(VI_SUCCESS!=errStatus)
		return FALSE;
  
		Sleep(1000);		
		str="SOUR"+channel+":FUNC ARB\n";							//合成指令存放在str中,指令功能为设置指定通道的输出波形类型为任意波
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
		if(VI_SUCCESS!=errStatus)  
		return FALSE;

		/*选择加载的文件*/
		Sleep(1000);
        str="SOUR"+channel+":FUNC:ARB \"INT:\\"+filename+"\"\n";	//合成指令存放在str中,指令功能为选中要输出的波形,channel存放的通道号,filename存放的arb文件名。
	    errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
	    if(VI_SUCCESS!=errStatus)  
		return FALSE;

		str = "AM:INT:FUNC SIN\n";
        errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));
		if(VI_SUCCESS!=errStatus)  
		return FALSE;

		/*设置频率1200hz*/
		str = "AM:INTernal:FREQ 1.2E+03\n";
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));
		if(VI_SUCCESS!=errStatus)  
		return FALSE;
		
		/*选择振幅调制模式- 双边带抑制载波(ON) 或具有边带的AM 调制载波(OFF)。*/
		str = "AM:DSSC on\n";
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));
		if(VI_SUCCESS!=errStatus)  
		return FALSE;

		/*启动调制*/
		str = "AM:STAT on\n";
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));
		 if(VI_SUCCESS!=errStatus)  
		return FALSE;

		str="OUTP"+channel+" 1\n";									//合成指令存放在str中,指令功能为指定通道输出
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//将指令传递给仪器
		Sleep(1000);
		if(VI_SUCCESS!=errStatus)  
		return FALSE;

		return TRUE;
	}
	return FALSE;
}
CString LoadData(CString path)							//加载path文件,将文件中所有内容形成字符串并返回
{
	CString str;										//创建字符串str,用来存放文件的一行内容
	CString strcommand;									//创建字符串str,用来存放文件的所有内容
	CStdioFile myfile;
	cout<<"数据加载中..."<<endl;
	if(myfile.Open(path,CFile::typeText|CFile::modeNoTruncate|CFile::modeRead|CFile::modeCreate))//打开文件
	{	
		myfile.ReadString(str);							//读取文件一行内容放在str中
        while(str!="")									//读到文件末尾停
		{
			str+="\n";									//每行字符串末尾加上换行
			strcommand+=str;							//将新读的一行加到字符串strcommand末尾
		    myfile.ReadString(str);	
		}
		strcommand+="\n";								//strcommand末尾加上回车
		myfile.Close();									//关闭文件
	}
	return strcommand;
}
BOOL SendArbWaveform(ViSession vi,CString strCommand,CString path)	//给仪器发送数据
{
   CString str,Count,Length;										//由于仪器指令需要,创建字符串str存放仪器指令,Length存放字符串的字符个数,Count存放Length的位数
   int count=1;														//位数默认值为1
   int length=strCommand.GetLength();								//获取字符串字符数
   while(length/10>=1)												//计算位数
   {
	length=length/10;
	count++;
   }
	cout<<"数据发送中..."<<endl;
	str="MMEM:DOWN:FNAM \"INT:\\"+path+"\"\n";						//将指令合成存放在str中,这条指令的功能是在信号发生器中INT路径下创建同名arb文件。其中path存放的是计算机中arb文件的名字(包括后缀)					
	if(vi)															//仪器连接中
	{	
		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength())); 		//发送指令给仪器
		if(VI_SUCCESS!=errStatus)  
			return FALSE;
		Count.Format("%d",count);									//将位数的类型转化为字符串用于指令合成
		Length.Format("%d",strCommand.GetLength());					//将字符数的类型转化为字符串用于指令合成
	
		str="MMEM:DOWN:DATA #"+Count+Length+strCommand+"\n";		//指令合成存放在str中,将字符串strCommand内容存放在上一步指定的文件中。

		errStatus=viPrintf(vi,str.GetBuffer(str.GetLength()));		//发送指令给仪器
		if(VI_SUCCESS!=errStatus)
			return FALSE;
		return TRUE;
	}
	return FALSE;
}

void main()
{
	char Uamx_Uo;
	ViSession viDefaultRM=NULL;
	ViSession vi;
	char channel;
	unsigned long iret=0;
	unsigned char buf[100];
	//CString strData,filename,str,filepath,strAddress="TCPIP::169.254.5.21::5025::SOCKET";
	CString strData,filename,str,filepath,strAddress="TCPIP::192.168.0.88::5025::SOCKET";//仪器地址
	cout<<strAddress<<endl;
	errStatus=viOpenDefaultRM(&viDefaultRM);
	if(VI_SUCCESS!=errStatus)
		return;
	errStatus=viOpen(viDefaultRM,strAddress.GetBuffer(strAddress.GetLength()+1),VI_NULL,VI_NULL,&vi);//打开会话
	if(VI_SUCCESS!=errStatus)
	{
		viClose(viDefaultRM);
		return;
	}
	viPrintf(vi, "*RST\n");								//初始化器件
	cout<<"请输入:输出通道(1)或者输出通道(2)"<<endl;	//提示设置输出通道,输入1则通道1输出,输入2则通道2输出
	cin>>channel;//将输入放入channel中						
				
	/*从示波器中选择任意波形*/
	Uamx_Uo = 6;
	switch(Uamx_Uo)
	{
		case 1:	filename="GRB_170mv_5s.arb";break;//合格,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 3:	filename="GRB_5S_10KSa_3-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 4:	filename="GRB_5S_10KSa_4-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 6:	filename="GRB_5S_10KSa_6-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
		case 8:	filename="GRB_5S_10KSa_8-1.arb";break;//,要输出的arb文件名!注意:文件名不能有中文,否则函数发生器内不能识别,出现乱码。
	}
	
	viPrintf(vi,"MMEM:CAT:DATA:ARBitrary?\n");			//查询仪器中所有文件名
	viRead(vi,buf,100,&iret);							//将返回的信息存放在buf数组中
    filepath=buf;										//buf数组的信息放入字符串filepath中,便于查询输出文件是否存在
	if(strstr(filepath,filename))						//查询仪器内部是否有目标输出文件
	{
		cout<<"文件存在,开始输出"<<endl;
		if(Output(vi,channel,filename))					//调用Output函数输出
			cout<<"输出波形数据成功"<<endl;
		else
			cout<<"输出波形数据失败"<<endl;
	}	
	else
	{
		 
		if(Output(vi,channel,filename))					//调用Output函数输出
			cout<<"输出波形数据成功"<<endl;
		/*strData=LoadData(filename);//调用LoadData函数,将arb文件内容提取存放在字符串中
		if(SendArbWaveform(vi,strData,filename))				//调用SendArbWaveform函数,发送波形数
		{
		    cout<<"文件装载成功"<<endl;
			if(Output(vi,channel,filename))					//调用Output函数输出
			cout<<"输出波形数据成功"<<endl;
		    else
			cout<<"输出波形数据失败"<<endl;
		}*/
		else
		{
		    //cout<<"文件装载失败"<<endl;
			cout<<"输出波形数据失败"<<endl;
		}
	}
	  
	if(vi)												//仪器连接未关
	{
		viClose(vi);									//关闭与仪器的连接
		viClose(viDefaultRM);
	}
	
	
}

该处使用的url网络请求的数据。


总结

以上就是今天要讲的内容,本文仅仅简单介绍了 函数发生器的合成操作,怎么合成任意波文件,在我的博客里面的其他文章也为,今天就到这里了。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值