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

    科技2022-08-13  110

    文章目录

    前言一、函数发生器是什么?二、使用步骤1.直接上程序,加载任意波的文件用的2.用函数发生器合成任意波文件 总结


    前言

    提示: 之前查找很多资料,都是国外的,怎么用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网络请求的数据。


    总结

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

    Processed: 0.009, SQL: 8