ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LabVIEW FPGA入门实战:基于NI myRIO的硬件编程与LED控制

LabVIEW FPGA入门实战:基于NI myRIO的硬件编程与LED控制 1. 项目概述从“Hello World!”开启LabVIEW FPGA实战之旅如果你接触过编程一定对“Hello World!”这个仪式感满满的第一行代码不陌生。它象征着从零到一的突破是进入一个新世界的敲门砖。今天我们要聊的这个“Hello World!”场景有点特别——它不是运行在你的电脑CPU上而是要烧录到一块FPGA芯片里通过NI myRIO这块神奇的硬件来点亮一个LED灯。这听起来是不是比在黑色控制台里打印一行白字酷多了没错这就是LabVIEW FPGA的入门仪式。LabVIEW FPGA简单说就是用图形化的LabVIEW语言去直接编程FPGA现场可编程门阵列。FPGA是什么你可以把它想象成一块“万能橡皮泥电路板”你可以用代码在这里是图形化的“虚拟导线”和“函数”来塑造它的内部电路结构让它变成你想要的专用数字芯片比如一个高速计数器、一个电机控制器或者一个复杂的通信协议处理器。而NI myRIO则是美国国家仪器NI推出的一款集成了ARM处理器和Xilinx FPGA的嵌入式学生设计设备它把高性能计算、灵活可编程的I/O口和丰富的传感器接口打包在一个巴掌大的板子上是学习嵌入式系统和FPGA开发的绝佳平台。为什么选择从myRIO开始学LabVIEW FPGA原因很实在。首先它软硬件一体开箱即用免去了自己挑选FPGA开发板、设计外围电路、焊接调试的繁琐过程让你能立刻聚焦在FPGA编程的核心逻辑上。其次NI提供了从驱动到编译工具链的完整支持环境搭建相对友好。最后myRIO上的FPGA资源Xilinx Zynq系列对于入门和完成大多数课程项目、原型验证来说已经绰绰有余。这个“Hello World!”项目目标就是带你走通从软件编写、编译到硬件部署的完整流程亲手让一个物理LED灯按照你的代码逻辑闪烁起来从而建立起对LabVIEW FPGA开发最直观、最坚实的信心。2. 环境准备与项目创建搭建你的数字电路“手术台”工欲善其事必先利其器。在开始“捏电路”之前我们得先把“手术台”——开发环境搭建好。这个过程有点像组装一个高级乐高套装步骤明确一步错了可能后面就搭不起来。2.1 软件栈安装一个都不能少你需要安装的软件主要来自NI这是一个环环相扣的套件NI LabVIEW Development System这是核心的图形化编程环境。确保安装的版本与你的myRIO设备支持版本匹配。通常myRIO会支持多个LabVIEW版本建议选择较新的长期支持版本以获得更好的稳定性和功能。NI LabVIEW FPGA Module这是解锁LabVIEW FPGA编程能力的钥匙。没有这个模块你无法创建和编译面向FPGA的VI虚拟仪器。安装时它会自动集成到LabVIEW开发环境中。NI myRIO Toolkit这个工具包至关重要。它包含了myRIO设备的驱动程序、FPGA基础IP核如定时器、PWM、SPI、I2C等接口的预定义逻辑块以及在主机VI运行在电脑上和FPGA VI运行在myRIO的FPGA上之间进行通信的API。安装后你才能在LabVIEW的函数选板中找到“myRIO”相关的Palette。Xilinx Vivado Design Suite (由NI安装程序管理)这是背后的“重型武器”。当你编译LabVIEW FPGA代码时LabVIEW实际上会将你的图形化代码转换为硬件描述语言如VHDL然后调用Xilinx Vivado进行综合、布局布线最终生成可以下载到FPGA芯片的比特流文件。重要提示这个通常由NI安装程序自动下载和安装特定版本不建议自己单独安装以免版本冲突。整个安装过程耗时较长尤其是Vivado请耐心等待。注意安装路径请避免使用中文或特殊字符最好全部使用英文路径。安装完成后建议重启计算机确保所有驱动和服务正确加载。2.2 硬件连接与初次握手拿出你的NI myRIO用附带的USB数据线将其连接到电脑。此时Windows通常会提示发现新硬件并自动安装驱动这些驱动已包含在myRIO Toolkit中。连接成功后myRIO上的电源指示灯应该亮起。接下来我们需要让LabVIEW认识这块板子打开LabVIEW在菜单中选择“Tools” - “NI MAX”Measurement Automation Explorer。在NI MAX左侧的“My System” - “Devices and Interfaces”下你应该能看到“NI myRIO-1900”或类似型号。如果能看到并且显示为“Ready”说明驱动安装成功连接正常。你可以右键点击设备选择“Self-Test”进行简单的自检确保硬件基本功能正常。2.3 创建你的第一个FPGA项目回到LabVIEW我们开始创建项目点击“File” - “New Project”创建一个空白项目。在项目浏览器窗口中右键点击“My Computer”选择“New” - “Targets and Devices”。在弹出的对话框中根据你的连接方式USB或网络选择“Existing target or device”然后找到你的myRIO设备将其添加到项目中。添加后项目结构里会出现你的myRIO设备。展开它你会看到两个关键部分“FPGA Target”和“Real-Time (RT) Target”。我们的“Hello World”主要在“FPGA Target”上完成。右键点击“FPGA Target”选择“New” - “VI”。这就会创建一个空的FPGA VI。把它保存为“HelloWorld_FPGA.vi”。同时我们也可以右键点击“My Computer”新建一个普通的Windows VI作为我们的上位机界面保存为“HelloWorld_Host.vi”。至此你的“手术台”已经准备就绪软件环境搭建完成硬件连接正常一个空的FPGA“画布”和主机通信界面也已创建。接下来我们就要在这张画布上用图形化的方式“绘制”我们的第一个数字电路了。3. FPGA VI 编程详解用图形化代码“连接”虚拟电路现在我们打开“HelloWorld_FPGA.vi”。它的前面板Front Panel和程序框图Block Diagram看起来和普通的LabVIEW VI很像但本质截然不同。普通VI的代码是在CPU上顺序执行的而FPGA VI的代码将被转换成并行执行的数字电路。理解这一点是写好FPGA代码的关键。3.1 前面板设计定义电路的“输入输出端口”FPGA VI的前面板定义的是这个自定义芯片的“引脚”和内部寄存器。对于“Hello World”我们只需要一个输出来控制myRIO板载的LED灯。myRIO板载有多个可编程LED我们选一个比如USER LED 0。在前面板上右键点击空白处打开控件选板。由于是FPGA VI选板中会多出一个“FPGA I/O”类别。从“FPGA I/O”中找到“LED”将其拖放到前面板上。这并非一个简单的显示控件它直接映射到FPGA芯片的一个物理输出引脚上。放置后会弹出一个对话框让你选择具体的LED资源。在树状列表中找到你的myRIO设备下的“LEDs”选择“LED0”。点击OK后前面板上会出现一个带有LED图标的控件它的标签可能是“LED0”。为了更直观你可以将其显示为布尔指示灯圆形LED样式。右键点击该控件选择“Replace” - “Modern” - “Boolean” - “Round LED”。但请注意它的本质仍然是FPGA I/O节点只是外观变了。这样我们就定义好了这个FPGA电路的唯一输出连接到物理LED0的引脚。3.2 程序框图编程构建闪烁逻辑的“数字心脏”切换到程序框图这里才是魔法发生的地方。我们要实现的功能是让LED以1Hz的频率闪烁亮0.5秒灭0.5秒。定时器是核心在FPGA中没有操作系统提供的“延时”函数。所有定时都必须基于硬件时钟。LabVIEW FPGA提供了“Tick Count (ms)”和“Timed Loop”等结构来获取时间。这里我们使用一个更直观的方法用“While Loop”配合“Wait (ms)”函数错在FPGA中不能使用“Wait”函数因为它会阻塞整个FPGA逻辑。正确的方法是使用“循环定时结构Timed Loop”或者用计数器基于时钟分频。 对于简单的闪烁最经典的方法是使用一个自由运行的循环和一个计数器。但LabVIEW FPGA为我们封装了更易用的“定时循环Timed Loop”。从函数选板“Programming” - “Structures”中找到“Timed Loop”拖放到程序框图。在循环边框上右键选择“Configure Timed Loop...”。配置定时循环在弹出的配置窗口中最关键的是设置“周期Period”和“周期单位Units”。我们希望每1000ms1秒执行一次循环体。因此设置周期为1000单位为ms。这里的“源Source”通常选择“1 kHz慢速”这是一个由FPGA内部产生的1kHz时钟信号精度足够我们做秒级定时。配置好后点击OK。实现翻转逻辑在定时循环内部我们需要实现LED状态的翻转。这需要一个能记住上一次状态的单元——寄存器。在数字电路中这通常由D触发器实现。在LabVIEW FPGA中我们可以用“反馈节点Feedback Node”或“移位寄存器”来轻松创建寄存器。从函数选板“Programming” - “Structures”中找到“Feedback Node”拖入循环内。我们需要一个布尔型的寄存器来存储LED状态。初始化时我们可以让LED为熄灭状态FALSE。将Feedback Node的初始值端子在循环左侧连接一个“FALSE”常量。实现翻转将Feedback Node的输出连接到一个“非Not”函数然后将“非”函数的输出一方面连接到LED0的I/O节点另一方面反馈回Feedback Node的输入。这样就构成了一个简单的T触发器每次循环执行时都会将当前状态取反然后输出到LED并存储为新的状态。最终连线将“非”函数的输出连接到我们之前创建的“LED0”节点上。整个程序框图看起来非常简洁一个定时循环内部包含一个反馈节点、一个非门、以及到LED的输出。实操心得第一次配置定时循环时容易混淆“周期”的含义。这里设置的1000ms意味着循环体执行完一次后到下一次开始执行中间间隔1000ms。而不是执行一次需要1000ms。我们的翻转逻辑执行时间极短纳秒级所以LED亮灭的时间基本各占500ms形成精确的1Hz闪烁。如果循环体内的逻辑非常复杂执行时间超过了设定的周期会导致“超时错误”这在FPGA设计中是需要避免的。3.3 理解底层图形化代码如何变成硬件电路你可能好奇这几根线是怎么变成硬件的当你点击运行箭头时LabVIEW会做以下工作编译翻译将你的图形化代码定时循环、反馈节点、非门转换成硬件描述语言HDL比如VHDL。综合SynthesisXilinx Vivado工具将HDL代码“翻译”成FPGA内部基本逻辑单元查找表LUT、触发器FF等的连接关系网表。布局布线Place Route将网表中的逻辑单元映射到FPGA芯片上具体的物理位置并用芯片内部的连线资源把它们连接起来。生成比特流Generate Bitstream将布局布线后的结果生成一个包含所有配置信息的二进制文件.bit文件。下载Download通过USB/JTAG将这个比特流文件烧录到myRIO的FPGA配置存储器中。FPGA芯片会根据这个文件瞬间重构其内部电路你的“LED闪烁器”专用芯片就诞生了这个过程尤其是综合和布局布线耗时可能从几十秒到几十分钟不等取决于设计复杂度。我们的“Hello World”项目编译时间通常在1-3分钟。4. 主机VI设计与交互给你的硬件电路一个“遥控器”FPGA VI编译下载后就会在myRIO上独立运行即使拔掉USB线只要myRIO不断电LED就会一直闪烁。但很多时候我们需要从电脑主机上监控或控制FPGA的行为。这就需要创建一个主机VIHost VI通过某种通信方式与FPGA VI对话。4.1 建立主机与FPGA的通信链路LabVIEW为myRIO提供了非常方便的FPGA接口函数。我们需要在主机VI中通过“FPGA I/O”节点来读写FPGA VI前面板上定义的控件它们对应着FPGA内部的寄存器或I/O口。打开之前创建的“HelloWorld_Host.vi”。在其程序框图中右键打开函数选板找到“myRIO” Palette。里面会有“Open FPGA VI Reference”函数。将这个函数拖放到程序框图。配置该函数右键点击该函数选择“Configure Open FPGA VI Reference...”。在弹出的配置窗口中你需要指定要通信的FPGA VI。点击“Browse”在项目文件夹中找到并选择你编译好的“HelloWorld_FPGA.lvbitx”文件注意是编译后生成的.lvbitx文件不是.vi文件。这个文件包含了比特流和FPGA VI的接口信息。配置好后点击OK。这个函数会输出一个“FPGA Reference”引用句柄后续所有与FPGA的交互都通过它进行。4.2 设计简单的主机控制界面我们的主机VI功能可以很简单显示当前LED的状态并提供一个按钮来手动开启或关闭LED覆盖FPGA的自动闪烁逻辑。前面板设计放置一个“圆形指示灯”Modern - Boolean - Round LED命名为“LED状态显示”。放置一个“垂直摇杆开关”Modern - Boolean - Vertical Toggle Switch命名为“手动控制开关”。放置一个“停止按钮”用于退出程序。程序框图编程使用一个标准的While循环条件为“停止按钮”未按下。在循环内我们需要从FPGA读取LED状态并写入手动控制命令。这里使用“Read/Write Control”函数簇。从“myRIO” Palette中找到“FPGA Read/Write Control”函数拖入循环。将“Open FPGA VI Reference”函数输出的引用句柄连接到它的“FPGA refnum”输入端。这个函数需要两个数组输入“Controls to Read”和“Controls to Write”。我们需要创建一个控件数组。右键点击“Controls to Read”输入端选择“Create” - “Constant”。会创建一个空的数组常量。从函数选板“Programming” - “Array”中找到“Build Array”函数将其放入这个数组常量中。然后我们需要指定要读取的FPGA控件。从“myRIO” Palette中找到“FPGA Get Control”函数将其输出连接到“Build Array”的输入。配置“FPGA Get Control”函数右键点击它选择“Configure FPGA Get Control...”在弹出的浏览器中选择你的FPGA VIHelloWorld_FPGA.vi然后选择前面板上的“LED0”控件。这样我们就构建了一个读取LED0状态的请求。同理为“Controls to Write”输入端创建数组。使用“FPGA Set Control”函数来配置要写入的控件同样是LED0并将其与前面板的“手动控制开关”的值通过“Build Array”连接起来。这意味着当开关为TRUE时我们向FPGA的LED0写入TRUE亮覆盖其内部闪烁逻辑。将“Read/Write Control”函数的“Data Read”输出数组通过“Index Array”函数索引出第一个元素即LED0的状态连接到前面板的“LED状态显示”指示灯。最后在循环末尾添加一个“Wait (ms)”函数设置等待50-100ms以避免主机CPU占用率过高。这样一个简单的主机监控程序就完成了。运行主机VI它会先打开FPGA VI的引用然后在循环中不断读取LED状态并显示同时根据你的开关位置向FPGA发送控制命令。5. 编译、下载与调试将代码“烧”进硬件并验证这是最激动人心的环节我们将看到所有的图形化代码最终转化为真实的物理现象。5.1 编译FPGA VI在“HelloWorld_FPGA.vi”中点击工具栏上的“运行”箭头。由于它是FPGA VILabVIEW会首先弹出编译选项。你可以直接点击“Compile”开始编译。一个独立的编译窗口会弹出显示详细的编译进度Translating将LabVIEW代码转换为中间表示。SynthesizingVivado进行综合。进度条可能会在这里停留较长时间。Placing Routing布局布线。Generating Bitstream生成比特流。Creating Download Specification创建.lvbitx文件。编译成功后窗口会显示资源利用率报告比如查找表LUT、触发器FF、块存储器BRAM的占用百分比。对于我们的闪烁程序占用率应该极低1%这说明FPGA还有巨大的潜力可供挖掘。5.2 下载并运行编译成功后可以选择“Run”直接下载到myRIO并运行。此时你应该立刻看到myRIO板上的USER LED 0开始以1秒为周期稳定地闪烁。恭喜你你的第一个LabVIEW FPGA程序已经成功在硬件上运行了5.3 调试技巧与常见问题FPGA调试不同于软件调试你不能设置断点、单步执行。主要依靠以下几种方法前面板监控在FPGA VI运行时其前面板是可以打开的虽然响应会慢因为数据要通过通信链路传回主机。你可以将想观察的中间变量“右键 - Create - Indicator”放到前面板上在运行时查看其值。这对于调试状态机、计数器非常有用。编译报告仔细阅读编译完成后的报告特别是“Timing”部分。它会告诉你设计是否满足时序要求即信号能否在指定的时钟周期内稳定。我们的简单设计通常没问题但复杂设计可能出现“时序违例”需要优化代码或降低时钟频率。SignalTap II 逻辑分析仪仅限某些系列这是Xilinx FPGA强大的片上调试工具可以在FPGA运行时捕获内部信号的波形。在LabVIEW FPGA中可以通过“Instrument” - “SignalTap II”来添加和配置。但这属于进阶功能且会占用额外的FPGA资源。常见问题实录问题1编译失败提示“找不到Vivado”或版本不匹配。排查这通常是环境问题。打开NI MAX查看“Software”下的已安装组件确认LabVIEW FPGA Module和对应的Vivado版本已正确安装。尝试修复安装或重新安装NI myRIO Toolkit。问题2主机VI无法打开FPGA引用提示“资源未找到”或“超时”。排查首先确认myRIO通过USB连接正常且在NI MAX中可见。其次确认主机VI中“Open FPGA VI Reference”函数配置的路径指向了正确的.lvbitx文件编译后生成的文件。最后检查是否有其他程序如另一个LabVIEW实例正在独占访问该FPGA资源。问题3LED闪烁频率不准明显快于或慢于1秒。排查检查定时循环的配置。确认周期是1000单位是ms时钟源是“1 kHz (慢速)”。如果使用计数器分频的方式检查计数器的位宽和比较值计算是否正确。myRIO的FPGA主时钟频率是40MHz进行分频计算时需注意。问题4编译时间异常漫长超过10分钟。排查对于Hello World项目这不太正常。可能是电脑性能不足或Vivado临时文件目录空间不够。可以尝试清理LabVIEW和Vivado的临时文件Cache。在LabVIEW选项Options的“FPGA Module”里可以找到缓存目录位置。6. 项目拓展与进阶思考从闪烁灯到真实世界接口成功点亮LED只是第一步。LabVIEW FPGA的真正威力在于其能够以硬件级别的速度和确定性去处理I/O信号。基于这个“Hello World”框架我们可以进行无数拓展读取数字输入将另一个FPGA I/O节点如“DIO”配置为输入连接到myRIO的物理按钮上。在FPGA VI中读取这个按钮的状态并用它来控制LED的闪烁模式例如按下时快闪松开时慢闪。这让你学会了处理外部数字信号。生成PWM信号PWM脉冲宽度调制是控制电机速度、LED亮度、舵机角度的基础。你可以用FPGA实现一个精度极高的PWM发生器。核心是一个计数器和比较器计数器从0累加到周期值然后清零将计数器的值与一个“占空比”寄存器比较小于占空比时输出高电平否则输出低电平。将这个输出连接到某个DIO引脚就能驱动外部设备。高频计数器/编码器接口FPGA擅长处理高频信号。你可以编写代码直接对来自光电编码器或高频脉冲发生器的信号进行计数频率可以轻松达到MHz级别这是普通微控制器难以企及的。这常用于速度、位置的高精度测量。自定义通信协议你可以用FPGA实现SPI、I2C、UART甚至更复杂的协议主站或从站逻辑。由于是硬件实现其时序可以极其精确和稳定。与RT系统协同myRIO还有一个实时处理器RT。你可以设计FPGA部分负责高速、确定性的数据采集或信号生成然后将处理后的数据通过DMA直接内存访问或中断的方式传递给RT系统进行更复杂的算法处理如滤波、控制律计算RT系统再通过主机接口与上位机通信。这是NI嵌入式平台的经典架构。从“Hello World”出发每一次拓展都是对“软件定义硬件”这一概念的深化。你会发现用LabVIEW FPGA开发就像在更高的抽象层次上设计电路无需关心VHDL/Verilog的语法细节却能享受到硬件并行执行带来的性能和确定性优势。当然这也要求你具备一定的数字电路思维理解时钟、寄存器、状态机这些基本概念。当你习惯了这种思维方式myRIO和LabVIEW FPGA将成为你实现各种高要求嵌入式原型和项目的强大工具。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进