LabWindows/CVI 教程:从入门到实践
第一部分:什么是 LabWindows/CVI?
1 核心概念

LabWindows/CVI 是由 National Instruments (NI) 开发的一款用于测试测量和自动化系统的集成开发环境,它使用标准的 C 语言作为编程语言,并结合了图形化用户界面设计工具、丰富的仪器驱动库和强大的调试功能。
核心特点:
- C 语言编程: 如果你熟悉 C 语言,上手会非常快,它提供了对硬件的底层访问能力,同时保持了 C 语言的高效性。
- 事件驱动编程模型: 程序的执行由用户的操作(如点击按钮、输入数据)或系统事件(如定时器触发、数据到达)来驱动。
- 图形化用户界面 设计器: 你可以通过拖拽控件(如按钮、图表、旋钮)来快速创建专业、美观的仪器面板。
- 内置仪器驱动: NI 提供了大量常用仪器的驱动程序(IVI-C),让你无需关心复杂的通信协议,就能轻松控制示波器、万用表、信号发生器等设备。
- 强大的数据分析库: 内含高级分析库,可以进行信号处理、曲线拟合、统计分析等复杂计算。
- 灵活的编译和部署: 可以生成独立的
.exe文件,方便在没有安装 LabWindows/CVI 的计算机上运行。
2 典型应用领域
- 自动测试系统: 电子产品生产线上的功能测试、校准。
- 数据采集与监控: 实时采集传感器数据并进行可视化监控。
- 虚拟仪器: 在计算机上模拟传统物理仪器的功能。
- 实验室自动化: 控制实验设备,自动执行实验流程并记录数据。
第二部分:开发环境概览
启动 LabWindows/CVI 后,你会看到几个核心窗口:

- 工程窗口: 管理整个项目的所有文件,包括源代码文件、头文件、用户界面文件、库文件等,一个完整的 CVI 项目通常包含
.uir(界面),.c(代码), 和.h(头文件)。 - 用户界面窗口: 这是你的“仪器面板”,你可以在这里拖放控件(如按钮、LED、图表、文本框)并设置它们的属性。
- 源代码窗口: 这是编写 C 代码的地方,CVI 会根据你在界面窗口中的操作,自动生成框架代码,你只需要在特定的函数中添加你的逻辑即可。
- 输出窗口: 显示编译、链接和运行时的信息,包括错误和警告。
第三部分:第一个项目 - Hello, World!
让我们通过一个最简单的例子来熟悉 CVI 的开发流程。
目标: 创建一个窗口,上面有一个按钮,点击按钮后,在弹出的消息框中显示 "Hello, World!"。
步骤 1:创建新工程
- 打开 LabWindows/CVI。
- 选择
File -> New -> Project。 - 选择
Project(.prj),给你的工程命名(如HelloWorld),并选择一个位置保存。
步骤 2:创建用户界面
- 在工程窗口中,右键点击工程名,选择
Add File -> User Interface (*.uir)。 - 给界面文件命名(如
HelloWorld.uir),并点击 "OK",此时会打开用户界面窗口。 - 从工具箱 中拖拽一个 Command Button 到面板上。
- 双击这个按钮,打开其属性窗口,将
Callback Function Name设置为OnButtonClick,然后点击 "OK",这个名字将是我们按钮点击事件处理函数的名称。
步骤 3:添加代码
- 在工程窗口中,双击
HelloWorld.c文件(如果不存在,CVI 可能会提示你创建)。 - 你会看到一个自动生成的框架代码,找到
int CVICALLBACK OnButtonClick (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)这个函数。 - 在
switch (event)语句的case EVENT_COMMIT:分支中,添加以下代码:case EVENT_COMMIT: // 弹出一个消息框 MessagePopup("Greeting", "Hello, World!"); break;
步骤 4:运行和测试
- 按下
Ctrl + F5或点击工具栏上的运行按钮。 - 程序会编译并运行,显示你设计的界面。
- 点击 "Command Button",你应该会看到一个标题为 "Greeting",内容为 "Hello, World!" 的消息框。
恭喜!你已经成功创建了你的第一个 LabWindows/CVI 应用程序。
第四部分:核心概念深入
1 事件驱动编程
与顺序执行的脚本不同,CVI 程序大部分时间都在“等待”,它等待用户或系统触发某个事件。
- 事件: 用户交互(点击、输入)、系统消息(定时器、窗口关闭)、数据到达(硬件中断)等。
- 回调函数: 每个控件(如按钮)或事件(如定时器)都可以关联一个特定的 C 函数,当事件发生时,CVI 会自动调用这个函数,这就是
OnButtonClick函数的作用。
2 控件与面板
- 面板: 整个用户界面的窗口。
- 控件: 面板上的元素,如按钮、旋钮、图表、字符串等。
- 控件属性: 每个控件都有属性,如名字、标签、颜色、大小、回调函数名等,可以通过代码或界面编辑器来修改。
3 面板函数
这是 CVI 编程的核心,通过面板函数,你可以在代码中控制界面元素。
- 设置控件值:
SetCtrlVal(int panelHandle, int controlID, double value);panelHandle: 面板句柄(通常通过GetPanelHandle函数获取)。controlID: 控件的 ID(在界面编辑器中可以看到)。value: 要设置的值(可以是整数、浮点数、字符串等)。
- 获取控件值:
GetCtrlVal(int panelHandle, int controlID, double *value);需要一个指针来接收从控件读取的值。
示例:
假设你有一个名为 USER_INPUT 的文本输入框,ID 为 5,你想获取用户输入的数字:
double userNumber;
int panelHandle = GetPanelHandle("HelloWorld.uir"); // 获取面板句柄
// 获取控件5的值到userNumber变量中
if (GetCtrlVal(panelHandle, 5, &userNumber) == 0) {
// 成功获取
printf("User entered: %f\n", userNumber);
} else {
// 获取失败
MessagePopup("Error", "Failed to get control value.");
}
第五部分:进阶项目 - 简单的数据采集器
让我们做一个更复杂的项目:从 NI-DAQ 设备读取一个电压值,并实时显示在图表上。
目标:
- 创建一个面板,包含一个“开始采集”按钮,一个“停止采集”按钮,一个图表。
- 点击“开始”,每秒从 DAQ 读取一个电压值,并添加到图表中。
- 点击“停止”,停止采集。
步骤 1:设计界面
- 创建新工程和新界面文件(如
DataLogger.uir)。 - 添加以下控件:
- 一个 Graph (图表),命名为
GRAPH。 - 一个 Command Button,命名为
START_BUTTON,回调函数为OnStartButtonClick。 - 一个 Command Button,命名为
STOP_BUTTON,回调函数为OnStopButtonClick。
- 一个 Graph (图表),命名为
步骤 2:编写代码
1 添加必要的头文件和变量
在 DataLogger.c 的顶部添加:
#include <userint.h> #include <ansi_c.h> #include <formatio.h> #include <nidaqmx.h> // NI-DAQmx 库头文件 // 定义面板句柄 int mainPanel; // 定义任务句柄和通道 TaskHandle readTask; const char* physicalChannel = "Dev1/ai0"; // 根据你的硬件修改,"PCIe-6320/ai0" // 定义定时器ID int timerId; // 定义数据数组 double dataBuffer[100]; int dataCount = 0;
2 主函数 main()
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0 