Requisitos: Usar o software Labwindows_cvi para desenvolver todo o sistema de calibração da máquina.
Análise: Todo o sistema de calibração da máquina é um sistema de controle integrado. O hardware que precisa ser programado inclui principalmente: analisador de rede vetorial, quadro de varredura, plataforma giratória, controlador de tempo, etc. Um conjunto de processos de calibração é formado através do controle desses hardwares No momento, esses hardwares são controlados separadamente, porque o quadro de varredura, a plataforma giratória e o controlador de tempo são instrumentos não padronizados, portanto, não serão descritos em detalhes aqui. Portanto, este capítulo descreve principalmente o analisador de rede vetorial controlado por programa Labwindows_cvi baseado na linguagem c.
Este capítulo consiste principalmente em várias partes: conectar o instrumento, enviar comandos do instrumento e receber dados do instrumento.
Índice
1 Uso da biblioteca de funções VISA em Labwindows_cvi
1.3 Operações de Recursos Específicos
2 Programação Labwindows_cvi baseada em linguagem c
1 Uso da biblioteca de funções VISA em Labwindows_cvi
A biblioteca de funções VISA fornecida em Labwindows_cvi é uma implementação do VISA padrão. Abra a janela de seleção do painel de funções da biblioteca de funções VISA e você verá que ela contém 3 subclasses.
● gestão de recursos;
● modelo de recurso;
• Operações sobre recursos específicos.
A subclasse de gerenciamento de recursos implementa a localização de recursos e o controle do ciclo de vida da comunicação de interface no padrão VISA; a subclasse de modelo de recurso implementa o controle de atributo, serviço de bloqueio de recurso e mecanismo de evento no padrão VISA; a subclasse de operação de recurso específica implementa o padrão VISA Médio I /O controle.
1.1 Gestão de Recursos
O gerenciamento de recursos inclui localização de recursos e controle do ciclo de vida da comunicação. A localização do recurso é uma função viOpenDefaultRM, que realiza a localização de todos os recursos VISA na máquina e retorna o identificador de recurso do tipo ViSession por meio do ponteiro. O controle do ciclo de vida da comunicação para todos os recursos específicos é implementado por meio desse identificador. O controle do ciclo de vida da comunicação inclui recursos de abertura, localização de recursos e recursos de fechamento.
1.2 Modelo de recurso
A subclasse de modelo de recurso fornece controle de atributo VISA, serviço de bloqueio de recurso e mecanismo de evento. Esta parte do conteúdo não está refletida neste artigo, portanto, não será descrita em detalhes.
1.3 Operações de Recursos Específicos
Operações específicas de recursos incluem funções de comunicação baseadas em mensagens e funções de comunicação baseadas em registros.
1.3.1 Funções de comunicação baseadas em mensagens
Instrumentos baseados em mensagens possuem processadores separados que interpretam as informações recebidas e interpretam as informações em instruções ou dados. O VISA fornece E/S formatada e funções básicas de E/S para comunicação baseada em mensagens.
(1) Função de E/S de formato
Muito semelhante às funções de formatação padrão do C, ele pode enviar ou receber dados formatados, incluindo: viPrintf(), viScanf(), viQueryf(), viFlush().
(2) Funções básicas de E/S
O Basic I/O suporta transmissão de dados síncrona e assíncrona de duas maneiras.
A função de transmissão síncrona encerra a execução de outros programas durante o processo de chamada e não retorna até que os dados sejam recebidos ou enviados.As funções que suportam transmissão síncrona incluem viWrite, viRead, viClear, viAssertTrigger e viReadSTB.
A função de transferência assíncrona retorna imediatamente após ser chamada e um evento de conclusão de leitura e gravação assíncrona (VI_EVENT_IO_COMPLETION) é gerado após a conclusão da transferência de dados, e o evento VI_EVENT_IO_COMPLETION pode ser processado por meio de enfileiramento de eventos ou função de retorno de chamada.
1.3.2 Funções de comunicação baseadas em registro
Não elabore aqui.
1.4 Funções comuns do VISA
1.4.1 Posicionamento do gerenciador de recursos VISA - viOpenDefaultRM
Nome: ViStatus viOpenDefaultRM ( ViSession sesn);
Descrição: Esta função é utilizada para inicializar um gerenciador de recursos VISA, esta função deve ser chamada antes de qualquer outra função VISA.
Tabela 1-1 Parâmetros da função viOpenDefaultRM
parâmetro |
descrever |
som |
Retorna um ID individual do gerenciador de recursos VISA |
Tabela 1-2 valor de retorno da função viOpenDefaultRM
identificador |
valor |
descrever |
VI_SUCCESS |
0 |
VISA Explorer inicializado com sucesso. |
VI_ERROR_ALLOC |
Recursos de sistema insuficientes. |
|
VI_ERROR_INV_SETUP |
O arquivo de configuração é inválido ou não existe. |
|
VI_ERROR_SYSTEM_ERROR |
A inicialização do sistema VISA falhou. |
1.4.2 Conectando Instrumentos——viOpen
原型: ViStatus viOpen ( ViSession sesn, ViRsrc name, ViAccessMode mode, ViUInt32 timeout, ViSession vi);
Descrição: conecta-se a um dispositivo especificado e retorna um identificador de conexão que pode ser usado para chamar outras funções.
Tabela 1-3 Parâmetros da função viOpen
parâmetro |
direção |
descrever |
som |
EM |
Identificador Lógico do VISA Explorer |
nome |
EM |
nome do endereço |
modo |
EM |
Método de abertura da conexão, que pode ser os seguintes valores: VI_EXCLUSIVE_LOCK é aberto exclusivamente; VI_LOAD_CONFIG abre de acordo com o arquivo de configuração externo VI_NULL multiacesso normal aberto |
tempo esgotado |
EM |
Se for aberto exclusivamente, o parâmetro é um tempo absoluto (em ms), e um erro será retornado quando o timeout expirar. Outros métodos de conexão ignoram esse valor. |
vi |
FORA |
Retorna o identificador lógico da conexão aberta |
Tabela 1-4 valor de retorno da função viOpen
identificador |
valor |
descrever |
VI_SUCCESS |
0 |
conexão bem-sucedida. |
VI_SUCCESS_DEV_NPRESENT |
A conexão foi bem-sucedida, mas não há resposta do endereço especificado. |
|
VI_WARN_CONFIG_NLOADED |
O endereço especificado não existe ou o formato do endereço está incorreto. |
|
VI_ERROR_ALLOC |
Recursos de sistema insuficientes. |
|
VI_ERROR_INTF_NUM_NCONFIG |
O endereço especificado é válido, mas não pode ser usado. |
|
VI_ERROR_INV_ACC_MODE |
Modo de acesso ilegal. |
|
VI_ERROR__INV_RSRC_NAME |
Erro de sintaxe do nome do endereço. |
|
VI_ERROR__INV_SESSION VI_ERROR__INV_OBJECT |
inválido v. |
|
VI_ERROR_LIBRARY_NFOUND |
A biblioteca VISA não está totalmente carregada. |
|
VI_ERROR_NSUP_OPER |
Explorer visto não suporta esta função. |
|
VI_ERROR_RSRC_BUSY |
visto é válido, mas atualmente inacessível. |
|
VI_ERROR_RSRC_LOCKED |
visto é monopolizado. |
|
VI_ERROR_RSRC_NFOUND |
Informação ou recurso insuficiente não existe. |
|
VI_ERROR_TMO |
0Xbffff0015 |
A operação expirou. |
1.4.3 Enviando Comandos do Instrumento - viPrintf e viWrite
(1)viPrintf
原型:ViStatus viPrintf ( ViSession vi, ViString writeFmt, ...);
Descrição: formata uma string e envia a string formatada para o dispositivo. (A formatação de string pode se referir à função Format na classe CString no MFC.)
As funções viWrite e viPrintf não podem ser usadas simultaneamente no mesmo recurso.
Os parâmetros de algumas funções VISA são variáveis (como viPrintf, viScanf e viQueryf), o que faz com que o VB não chame. Os usuários podem usar funções equivalentes a essas funções.
O parâmetro writeFmt pode conter caracteres comuns, caracteres de formatação geral e caracteres especiais. Caracteres comuns (incluindo espaços) são escritos normalmente, sem qualquer modificação. Uma barra invertida (\) deve ser adicionada antes do caractere especial; o caractere de formato é composto por um sinal de porcentagem (%) e um sinalizador de operação, que será apresentado posteriormente.
Tabela 1-5 Caracteres especiais
\n |
Envia um caractere de nova linha ASCII e o sinalizador END é enviado automaticamente junto com ele. |
\r |
Envie um retorno de carro ASCII. |
\t |
Envie um caractere de tabulação ASCII. |
\### |
Envia um número octal especificado. |
\” |
Envie uma aspa dupla ASCII. |
\\ |
Envie uma barra invertida ASCII. |
Tabela 1-6 Parâmetros da função viPrintf
parâmetro |
direção |
descrever |
vi |
EM |
identificador de objeto |
writeFmt |
EM |
string de formato |
表1-7 viPrintf函数返回值
标识符 |
值 |
描述 |
VI_SUCCESS |
0 |
参数成功格式化。 |
VI_ERROR_ALLOC |
内存不足。 |
|
VI_ERROR_INV_FMT |
writeFmt包含无效格式化说明符。 |
|
VI_ERROR__INV_SESSION VI_ERROR__INV_OBJECT |
vi不能标志正确的连接。 |
|
VI_ERROR_IO |
位置IO错误。 |
|
VI_ERROR_NSUP_FMT |
writeFmt有不支持的格式说明符。 |
|
VI_ERROR_RSRC_LOCKED |
vi被独占。 |
|
VI_ERROR_TMO |
操作超时。 |
(2)viWrite
原型:ViStatus viWrite (ViSession vi, ViBuf buf, ViUInt32 cnt, ViPUInt32 retCnt);
描述:同步写入数据。写入的数据存储在buf中。当数据写入完毕函数才返回。任何时间都只能存在一个同步写入。
如果retCnt的值为VI_NULL,将不返回写入数据长度值。
表1-8 viWrite函数参数
参数 |
方向 |
描述 |
vi |
IN |
对象标识符 |
buf |
IN |
写入数据存放地址。 |
cnt |
IN |
指定写入长度。 |
retCnt |
OUT |
实际写入长度,如果为VI_NULL表示不关心该值。 |
表1-9 viWrite函数返回值
标识符 |
值 |
描述 |
VI_SUCCESS |
0 |
成功读取,读取到END指示器结束。 |
VI_SUCCESS_MAX_CNT |
成功读取,已经达到最大长度cnt。 |
|
VI_SUCCESS_TERM_CHAR |
成功读取,读取到特定终止符。 |
|
VI_ERROR_ASRL_FRAMING |
格式错误。 |
|
VI_ERROR_ASRL_OVERRUN |
溢出错误。 |
|
VI_ERROR_ASRL_PARITY |
同步错误。 |
|
VI_ERROR_BERR |
总线错误。 |
|
VI_ERROR_CONN_LOST |
连接丢失。 |
|
VI_ERROR_INV_SESSION VI_ERROR_INV_OBJECT |
vi不能标志正确的连接。 |
|
VI_ERROR_INV_SETUP |
设置无效,不能执行操作。 |
|
VI_ERROR_IO |
位置I/O是错误。 |
|
VI_ERROR_NCIC |
非法控制器。 |
|
VI_ERROR_NLISTENERS |
没有检测到听者。 |
|
VI_ERROR_NSUP_OPER |
vi不支持此函数。 |
|
VI_ERROR_OUTP_PROT_VIOL |
设备报告输出协议错误。 |
|
VI_ERROR_RAW_RD_PROT_VIOL |
传输时读协议被破坏。 |
|
VI_ERROR_RAW_WD_PROT_VIOL |
传输时写协议被破坏。 |
|
VI_ERROR_RSRC_LOCKED |
vi被独占。 |
|
VI_ERROR_TMO |
操作超时。 |
1.4.4 接收仪器数据——viScanf或viRead
(1)viScanf
原型:ViStatus viScanf (ViSession vi, ViString readFmt,arg1,arg2, ...);
描述:这操作从设备读取一个字符串,然后格式化后保存值arg变量中。格式化字符串包含说明符、空格字符和普通字符。
VISA中参数不确定的函数(viPrintf,viScanf,和viQueryf)不能被 VB调用。可以用功能相似的viVPrintf,viVScanf,和viVQueryf代替。
表1-10 viScanf函数参数
参数 |
方向 |
描述 |
vi |
IN |
对象标识符 |
readFmt |
IN |
格式化字符串。 |
表1-11 viScanf函数返回值
标识符 |
值 |
描述 |
VI_SUCCESS |
0 |
成功读到数据并且格式化到arg参数里。 |
VI_ERROR_ALLOC |
内存不足。 |
|
VI_ERROR_INV_FMT |
readFmt包含无效格式化说明符。 |
|
VI_ERROR__INV_SESSION VI_ERROR__INV_OBJECT |
vi不能标志正确的连接。 |
|
VI_ERROR_IO |
位置IO错误。 |
|
VI_ERROR_NSUP_FMT |
readFmt有不支持的格式说明符。 |
|
VI_ERROR_RSRC_LOCKED |
vi被独占。 |
|
VI_ERROR_TMO |
操作超时。 |
(2)viRead
原型:ViStatus viRead (ViSession vi, ViPBuf buf, ViUInt32 cnt, ViPUInt32 retCnt);
描述:同步读取数据。读取的数据存在buf中,当数据读取完毕函数才返回。任何时间都只能存在一个同步读取。遇到以下情况同步读取结束:
1)收到END指示器;
2)读取到终止符;
3)读取的数据大小达到cnt的值。
注意:必须设置读取终止符。
表1-12 viRead函数参数
参数 |
方向 |
描述 |
vi |
IN |
对象标识符 |
buf |
OUT |
返回数据存取地址。 |
cnt |
IN |
指定读取长度。 |
retCnt |
OUT |
实际读取长度,如果为VI_NULL表示不关心该值。 |
表1-13 viRead函数返回值
标识符 |
值 |
描述 |
VI_SUCCESS |
0 |
成功读取,读取到END指示器结束。 |
VI_SUCCESS_MAX_CNT |
成功读取,已经达到最大长度cnt。 |
|
VI_SUCCESS_TERM_CHAR |
成功读取,读取到特定终止符。 |
|
VI_ERROR_ASRL_FRAMING |
构架错误。 |
|
VI_ERROR_ASRL_OVERRUN |
溢出错误。 |
|
VI_ERROR_ASRL_PARITY |
同步错误。 |
|
VI_ERROR_BERR |
总线错误。 |
|
VI_ERROR_CONN_LOST |
连接丢失。 |
|
VI_ERROR_INV_SESSION VI_ERROR_INV_OBJECT |
vi不能标志正确的连接。 |
|
VI_ERROR_INV_SETUP |
设置无效,不能执行操作。 |
|
VI_ERROR_IO |
位置I/O是错误。 |
|
VI_ERROR_NCIC |
非法控制器。 |
|
VI_ERROR_NLISTENERS |
没有检测到听者。 |
|
VI_ERROR_NSUP_OPER |
vi不支持此函数。 |
|
VI_ERROR_OUTP_PROT_VIOL |
设备记录一个输出协议错误。 |
|
VI_ERROR_RAW_RD_PROT_VIOL |
传输时读协议被破坏。 |
|
VI_ERROR_RAW_WD_PROT_VIOL |
传输时写协议被破坏。 |
|
VI_ERROR_RSRC_LOCKED |
vi被独占。 |
|
VI_ERROR_TMO |
操作超时。 |
1.4.5关闭资源管理器和设备连接——viClose
原型:ViStatus viClose (ViObject vi);
描述:关闭一个资源管理器或者设备连接,并释放内存。
表1-14 viClose函数参数
参数 |
方向 |
描述 |
vi |
IN |
需要关闭的对象。 |
表1-15 viClose函数返回值
标识符 |
值 |
描述 |
VI_SUCCESS |
0 |
关闭成功。 |
VI_WARN_NULL_OBJECT |
要关闭的对象时空对象。 |
|
VI_ERROR_CLOSING_FAILED |
vi不能标识正当对话通道。 |
|
VI_ERROR__INV_SESSION VI_ERROR__INV_OBJECT |
无法释放与该对话通道相关联的内存数据结构。 |
2 Labwindows_cvi基于c语言编程
案例:以3672系列的矢量网络分析仪为例,实现矢网连接,发送命令到矢网,接收矢网数据,关闭矢网连接等功能。
2.1界面设计
界面主要包含矢网连接、发送矢网重置命令、接收矢网数据、断开矢网连接、消息提示框等功能。
图2-1 demo界面
2.2实现代码
所有功能实现代码如下:
#include <utility.h>
#include <ansi_c.h>
#include <cvirte.h>
#include <userint.h>
#include <visa.h>
#include "PNA_CONECT.h"
static int pnaConect;
ViSession defaultRM ,vi;
unsigned char Data_Mag[5000]; // 幅度测试数据
char c_currentMessage[300]; // 提示消息
void GetDateTime(void);
/*==========VISA资源管理器定位==========*/
int RMConnect(void);
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((pnaConect = LoadPanel (0, "PNA_CONECT.uir", PNA_CONECT)) < 0)
return -1;
DisplayPanel (pnaConect);
RunUserInterface ();
DiscardPanel (pnaConect);
return 0;
}
int CVICALLBACK PNA_CONECT_CALLBACK (int panel, int event, void *callbackData,
int eventData1, int eventData2)
{
switch (event)
{
case EVENT_GOT_FOCUS:
break;
case EVENT_LOST_FOCUS:
break;
case EVENT_CLOSE:
QuitUserInterface (0);
break;
}
return 0;
}
/*==========VISA资源管理器定位==========*/
int RMConnect()
{
int error,result;
error= viOpenDefaultRM(&defaultRM);
while(error)
{
result = GenericMessagePopup("Error", "VISA资源管理器定位失败!", "重试", "忽略", "", 0, 0, 0, VAL_GENERIC_POPUP_BTN1, VAL_GENERIC_POPUP_BTN1, VAL_GENERIC_POPUP_NO_CTRL);
if(result==1)
{
error= viOpenDefaultRM(&defaultRM);
}
else
break;
}
return defaultRM;
}
/* 连接矢网 */
int CVICALLBACK ConnectPna_CALLBACK (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int error, select;
switch (event)
{
case EVENT_COMMIT:
RMConnect();
error = viOpen(defaultRM, "TCPIP0::192.168.1.41::5025::SOCKET", VI_NULL,VI_NULL, &vi); //3672B
if(error==0)
{
GetDateTime() ;
strcat(c_currentMessage," 矢网连接成功!\n");
SetCtrlVal (panel, PNA_CONECT_TEXTBOX, c_currentMessage);
}
while ( error )
{
select= GenericMessagePopup ("Error", "矢网连接错误,请重试或检查连接状态", "重试", "忽略", "", 0, 0, 0, VAL_GENERIC_POPUP_BTN1, VAL_GENERIC_POPUP_BTN1, VAL_GENERIC_POPUP_NO_CTRL);
if ( select == 1 )
{
error = viOpen(defaultRM, "TCPIP0::192.168.1.41::1024::SOCKET", VI_NULL,VI_NULL, &vi);
}
else
{
GetDateTime() ;
strcat(c_currentMessage," 矢网连接错误,请重试或检查连接状态!\n");
SetCtrlVal (panel, PNA_CONECT_TEXTBOX, c_currentMessage);
}
break;
}
}
return vi;
}
//发送矢网命令
int CVICALLBACK SEND_RST_CALLBACK (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
// 矢网重置
viPrintf(vi,"*RST\n");
// 删除所有测试设置
viPrintf(vi,"CALC:PAR:DEL:ALL\n");
// 关闭所有窗口
viPrintf(vi,"DISPlay:WIND OFF\n");
// 打开新建窗口
viPrintf(vi,"DISPlay:WIND1 ON\n");
// 定义测试内容
// 定义测试内容
viPrintf(vi,"CALC1:PAR:DEF:EXT 'mytrace','S21'\n");
// 显示测试迹线
viPrintf(vi,"DISPlay:WIND1:TRAC1:FEED 'mytrace'\n");
// 选定测试迹线
viPrintf(vi,"CALC1:PAR:SEL 'mytrace'\n");
// 设置测试类型(对数幅度)
viPrintf(vi,"CALC1:FORM MLOG\n");
// 设置扫描类型为段扫描 */
viPrintf(vi,"SENS1:SWE:TYPE SEGM\n");
// 段扫描开始频率 */
viPrintf(vi,"SENS1:SEGM:FREQ:STAR 12GHz\n");
// 段扫描终止频率 */
viPrintf(vi, "SENS1:SEGM:FREQ:STOP 12GHz\n");
// 段扫描频率点数 */
viPrintf(vi,"SENS1:SEGM:SWE:POIN 1\n");
GetDateTime();
strcat(c_currentMessage," 矢网命令已发送!\n");
SetCtrlVal (panel, PNA_CONECT_TEXTBOX, c_currentMessage);
break;
}
return 0;
}
//接收矢网数据
int CVICALLBACK RECEIVE_DATA_CALLBACK (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
// 频点个数
int length=1;
switch (event)
{
case EVENT_COMMIT:
// 从通道 1 所选测量轨迹中读取格式化数据。
viPrintf(vi,"CALC1:DATA? FDATA\n");
// 读取矢网测试数据 length:频点个数
viRead (vi,Data_Mag ,length*20,VI_NULL);
GetDateTime();
strcat(c_currentMessage," ");
strcat(c_currentMessage,Data_Mag);
//将读取的数据显示
SetCtrlVal (panel, PNA_CONECT_TEXTBOX, c_currentMessage);
GetDateTime();
strcat(c_currentMessage," 数据读取完成!\n");
SetCtrlVal (panel, PNA_CONECT_TEXTBOX, c_currentMessage);
break;
}
return 0;
}
//释放矢网资源
int CVICALLBACK DISCONNECT_CALLBACK (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
viClose(vi);
viClose(defaultRM);
GetDateTime();
strcat(c_currentMessage," 已经释放矢网资源并关闭!\n");
SetCtrlVal (panel, PNA_CONECT_TEXTBOX, c_currentMessage);
break;
}
return 0;
}
//获取系统日期时间
void GetDateTime()
{
int i_hour, i_minute , i_second ;
int i_month , i_day , i_year;
char c_hour[9], c_minute[3], c_second[3];
char c_year[10], c_month[3], c_day[3];
char c_diagonal[2]="/", c_colon[2]=":",c_space[2]=" ";
char c_date[19], c_currenttime[9];
//获取系统时间
GetSystemTime(&i_hour,&i_minute , &i_second );
//获取系统日期
GetSystemDate(&i_month,&i_day, &i_year);
//将int类型数据转为字符串数据
sprintf(c_hour,"%d",i_hour);
sprintf(c_minute,"%d",i_minute);
sprintf(c_second,"%d",i_second);
sprintf(c_year,"%d",i_year);
sprintf(c_month,"%d",i_month);
sprintf(c_day,"%d",i_day);
//拼接字符串
strcpy(c_date,strcat(strcat(strcat(strcat(c_year,c_diagonal),c_month),c_diagonal),c_day));
strcpy(c_currenttime,strcat(strcat(strcat(strcat(c_hour,c_colon),c_minute),c_colon),c_second));
strcpy(c_currentMessage,strcat(strcat(c_date,c_space),c_currenttime));
}
2.3功能显示
连接的矢量网络分析仪型号时AV3672B矢量网络分析仪,展示功能如下:
图2-2 demo实现效果