VC++单片机虚拟仪器测试系统 第11页
在该模块中可以完成几种基本波形的产生以及各种基本的调试功能:正弦波,三角波,方波,锯齿波,任意波等;调幅,调频,脉冲调制,频移键控;可以修改频率,幅度,偏置以及占空比;可以配置输出阻抗何同步信号。在该界面中还存在复位按钮以及硬件连接按钮,方便用户的测试。从整体上看,符合人们的操作习惯。自己认为也还可以,也不失有点人性化吧!
其实,在界面的设计过程中,也一边开始程序的构思。基本上界面是根据信号发生器的信号的产生过程及顺序以及编程的思路来进行安排的,界面的定型也就意味着自己的编程思路已经基本成型了!下面是自己的编程思路结构:
以上就是我的函数信号发生器的编程思想和设计思路。这是一个最基本的函数信号发生器模块,具备基本的功能参数。有了界面和思路之后就可以进行底下的编程操作了。
3.2.3 函数信号发生器的编程
首先,需要能使函数信号发生器根据用户的输入来产生相应的波形。我于是参看了
33250A 80MHz的函数/任意波形发生器的电子资料以及网上关于该仪器的操作的SCPI指令。
就像前面所说的那样,函数信号发生器是基于消息基,也就是说它具有自己的处理器来对用户输入的高级指令进行解释和判断以及进行执行操作。譬如,如果希望产生一个正弦波,则输入下面的语句既可:viPrintf(funcgen,"function :shape sin\n");就可以产生一个采用默认频率和幅值的正弦波了!而viPrintf()就是VISA库中的格式化输入输出操作函数,用来向仪器发送SCPI指令。在函数信号发生器的编程过程中,经常需要用到这个函数,还有格式化输入函数:viScanf()。在指令的测试过程中,也遇到了一些问题:如viPrintf(funcgen,"func:shape tri;freq 2000;volt 2\n");这条指令就有问题,只能显示三角波,但是后面的参数就没有根据我的指定来进行显示。后来才发现,原来每一个指令后面加上回车符就可以正常的执行了。譬如,下面一条语句:viQueryf(funcgen,"AM:SOUR?",buf);该语句的功能是查询AM的调制源的类型并将查询到的类型字符以%t的格式给buf。注意:该语句是没有错误,但是好像就没有起到预期的效果。而当我在"AM:SOUR?\n"加上一个回车符后,就可以执行正确了。可以看出格式化命令是以回车符作为触发命令的,只有\n才能使命令有效,舍去将视为字符串处理。(但程序本身并不提示错误)又如,产生象使用APPL命令的波形:"Appl:sin freq,volt,dcoffset\n",当使用其他函数产生时,如下:
"FUNC SIN\nFREQ freq\nVOLT volt\n…\n"或是"FUNC SIN\n;FREQ freq\n;VOLT volt\n;…\n"可以看出执行指令都加上了回车符(对于象这样的一串执行指令,也可以在末尾加\n来执行――只是需要使用分号来进行隔开,用逗号和空格均不行)
下面是复位按钮的执行代码:
图3-9
原理是通过向仪器发送IDN的SCPI指令根据函数返回值来进行判断,并给出相关的信息提示用户。除了SCPI命令外,还有IEEE 488.2命令,两种命令之间用分号隔开如下所示:
RST;OUTP:LOAD INF\n 又如:TRIG:SOUR BUS;TRG\n连接多个SCPI命令时,使用分号和冒号(冒号表示不同的命令系统)如:OUTP:LOAD 50;:APPL:RAMP
注意:函数viPrintf()和viScanf()都是单向的传送命令和数据,而函数viQueryf()则是双向的传送数据和命令。在格式化命令中不允许有两条如似的命令"FREQ?\n VOLT?\n"。在我的测试命令以及组合发送命令过程中,我遇到这样的问题:
Cstring m_sFreq,m_sVolt; viQueryf(vi,"Freq?\n","%t",m_sFreq);
viQueryf(vi,"Volt?\n","%t",m_sVolt);
SetDlgItemText(ID0,m_sFreq);
SetDlgItemText(ID1,m_sVolt);如果以这种方式执行的话,执行的结果是m_sFreq和m_sVolt是同一个值,当把语句改为如下的形式的时候就正常了:
Cstring m_sFreq,m_sVolt; viQueryf(vi,"Freq?\n","%t",m_sFreq);SetDlgItemText(ID0,m_sFreq);
viQueryf(vi,"Volt?\n","%t",m_sVolt);SetDlgItemText(ID1,m_sVolt);
这也表示SCPI查询命令不允许执行多个,只能一条一条的执行,否则,最后的结果会是以最后一条查询指令的结果。
通过反复的测试之后,理解了SCPI命令的执行的一些格式及语法之后,就开始我的编程。下面列出了函数信号发生器的部分执行代码:
//这是一个switch语句,对用户的调制方式的判断,其中nID_Select_Modul保存的是用//户选择的调制方式的ID。通过GetCheckedRadioButton()函数获得。
switch(nID_Select_Modul)//对用户通过单选按钮选择的调制参数的判断
{ case IDC_RADIO_BW://无调制情况
viPrintf(/*funcgen*/theApp.m_Session,"OUTPut:LOAD %s\n",m_nResistance);//输出端的设置
viPrintf(/*funcgen*/theApp.m_Session,"OUTPut:SYNC %s\n",m_nSignal);//设置同步信号
CheckWaveRadioButton();//这是一个自己定义的函数,对用户的波形的选择进行判断-将波形的字符串存储在m_nBaseShape中,该函数的具体代码将会在附录中给出。
//判断用户选择的波形是否是方波,并通过函数viPrintf来进行各种SCPI命令的执行
if(GetCheckedRadioButton(IDC_RADIO_SIN,IDC_RADIO_DC)==IDC_RADIO_FWAVE)
{ viPrintf(/*funcgen*/theApp.m_Session,"FUNC %s\n",m_nBaseShape);
viPrintf(/*funcgen*/theApp.m_Session,"FREQ %f\n",m_nFreq);
viPrintf(/*funcgen*/theApp.m_Session,"VOLT %f\n",m_nAmpl);
viPrintf(/*funcgen*/theApp.m_Session,"VOLT:OFFS %f\n",m_nOffs);
viPrintf(/*funcgen*/theApp.m_Session,"FUNC:SQU:DCYC %f\n",m_nDcycle);
}//判断用户选择的是否是任意波
else if(GetCheckedRadioButton(IDC_RADIO_SIN,IDC_RADIO_DC)==IDC_RADIO_ARBI)
{error=viPrintf(/*funcgen*/theApp.m_Session,"APPL:USER %f,%f,%f\n",m_nFreq,m_nAmpl,m_nOffs);
if(error!=VI_SUCCESS)
{error_handler(/*funcgen*/theApp.m_Session,error);
break;}
viPrintf(/*funcgen*/theApp.m_Session,"FUNC:USER%s\n",WaveForm.m_Arbitrary);}else
<< 上一页 [11] [12] [13] [14] [15] [16] 下一页
VC++单片机虚拟仪器测试系统 第11页下载如图片无法显示或论文不完整,请联系qq752018766