前言
提示: 之前查找很多资料,都是国外的,怎么用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网络请求的数据。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了 函数发生器的合成操作,怎么合成任意波文件,在我的博客里面的其他文章也为,今天就到这里了。