资讯动态

FPGA数据采集系统设计:64路模拟信号分时复用与NAND Flash存储

发布时间:2026/10/29 12:32:27 来源:尧图企业网站定制
简介这份资源是一份面向电子信息、测控技术与仪器等专业本科生及FPGA初学者的毕业设计文档围绕“基于FPGA的数据采集系统”展开帮助读者理解如何以FPGA为核心搭建多通道实时采集与存储方案。压缩包内共1个doc文件约526KB为完整的本科毕业设计说明书涵盖绪论、系统硬件设计等章节可据此梳理课题背景、整体设计方案与硬件电路结构。文档重点讨论六十四路模拟信号、八路无源开关量信号及一路数字脉冲信号的采集实现涉及电压跟随器、模拟开关、A/D转换、FPGA中心控制、存储器与并口通信等模块并给出系统框图和采集通道设计思路。已有638人学习适合需要参考选题框架、方案论证与硬件设计表述的读者对照使用。1. 数据采集系统为什么 64 路模拟信号不能各配一个 ADC拆开任何一台工业现场的数据采集设备你大概率会看到一块 FPGA 旁边挂着一颗 ADC前面串着一片模拟开关。这个组合看起来平平无奇但它背后藏着一个非常现实的工程约束64 路模拟信号如果每路都配一套运放加 ADC板子面积、功耗和成本会直接翻三倍以上而且大多数场景下根本没必要——因为被测物理量变化没那么快分时复用完全够用。数据采集系统的本质是把物理世界的连续量搬进数字世界而搬运动作里最贵的不是“搬”是“同时搬”。这套基于 FPGA 的采集方案核心思路就是用一片 FPGA 做时序总指挥让 64 路模拟量、8 路开关量、1 路数字脉冲共用一条量化通道再统一压进 NAND Flash。搞懂它为什么这么设计比会画原理图更有价值因为你在别的采集项目里踩的坑八成也来自这几个取舍点。2. 模拟通道64 路信号怎么挤进一颗 ADC2.1 电压跟随器不是摆设它解决的是阻抗打架传感器输出的 05V 模拟信号内阻往往不小有的到几十千欧。这种信号直接怼进模拟开关开关的导通电阻ADG506 典型 200Ω会和源内阻串起来分压采样值当场就偏了。更麻烦的是模拟开关的寄生电容在通道切换瞬间会抽走电荷源内阻越大建立时间越长采到的就是上一个通道的残影。所以每路入口先过一个 LM324 接成的电压跟随器。跟随器的输入阻抗高、输出阻抗低把“高阻信号源”翻译成“低阻信号源”后面模拟开关和 ADC 看到的就是一个稳稳的 05V。这里有个容易被忽略的细节LM324 是四运放单电源供电时输出摆幅到不了真正的 0V 和 5V靠近轨道的几十毫伏会被削掉。如果被测信号恰好落在这个区间量化结果就会贴死在码值两端。常见的处理是给运放加一点负电源或者选轨到轨运放但本科设计里用 LM324 图的是便宜好买代价就是量程两端要留余量。2.2 模拟开关的选型账通道数、导通电阻、泄漏电流三者互斥ADG506 是 16 选 1 的 CMOS 模拟开关四片级联正好覆盖 64 路。选它不是因为性能多强而是参数刚好卡在需求线上导通电阻 200Ω、泄漏电流 20pA 典型值、导通和关断时间各 200ns。这三个参数其实互相牵制——通道数越多芯片内部并联的开关管越多寄生电容和漏电流就越大想要低导通电阻开关管就得做宽寄生电容跟着涨切换速度反而下降。实际接线时A0A3 四根地址线由 FPGA 给出负责在 16 个通道里选一个A6 是使能拉高才工作。四片 ADG506 的使能端分别由 FPGA 的另外几根 IO 控制同一时刻只让一片导通其余三片处于高阻。这里有个血泪经验如果四片的使能切换和地址变化不是严格错开的会出现两个通道短暂同时导通的瞬间两路信号在汇合点打架采到的值既不是 A 也不是 B。稳妥的做法是地址先稳定等几十纳秒再拉使能关断时反过来先撤使能再改地址。2.3 采样时序谁先动、谁后动决定了数据对不对整个模拟通道的节拍由 FPGA 统一发号施令顺序大致是这样// 简化示意单通道采集节拍 // ch_addr 变化 - 等待建立 - 启动 ADC - 等转换完成 - 锁存数据 always (posedge clk) begin case (state) IDLE: begin ch_addr ch_addr 1; // 切换模拟开关地址 state SETTLE; end SETTLE: begin if (settle_cnt SETTLE_TICKS) state CONV_START; // 等信号稳定后再启动转换 end CONV_START: begin adc_clk_en 1b1; // 给 AD9221 提供时钟 state WAIT_DONE; end WAIT_DONE: begin if (adc_ready) begin data_buf adc_data; // 锁存 12 位并行输出 state IDLE; end end endcase endSETTLE_TICKS这个等待窗口是整个时序里最需要拿捏的参数。等太短模拟开关和 ADC 采样保持电路的建立过程没走完数据跳变等太长64 路轮询一圈的时间被拉长等效采样率掉下来。工程上的估算方法是看模拟开关的导通时间加上运放的压摆率再留一倍余量。AD9221 是流水线结构内部有多级转换同时推进所以它的“转换完成”信号有固定延迟FPGA 必须按数据手册给的时序窗口去锁存早一个时钟沿读到的就是上一级流水线的中间结果。3. 数字量与开关量电平不匹配为什么必须隔离3.1 12V 脉冲进 3.3V 存储器的钳位逻辑系统要采一路数字脉冲形式可能是 TTL也可能是高电平 12V 的脉冲。而 Flash 的 IO 是 3.3V 域12V 直接灌进去就是烧片。最省事的做法是用一颗 3.3V 稳压管做钳位输入高于 3.3V 时稳压管反向击穿把节点电压摁在 3.3V低于 3.3V 时稳压管不导通信号原样通过。这个电路便宜到可以忽略成本但它有个隐含前提——前级得有限流电阻否则稳压管在钳位瞬间承受的功率会把它自己烧掉。另外稳压管的钳位不是硬拐点接近 3.3V 时有一段软过渡高频脉冲的边沿会被磨圆如果后级对边沿敏感还得补一级施密特整形。3.2 光耦隔离地电位差才是开关量采集的隐形杀手8 路无源开关量来自现场现场的地和采集板的地往往不共地两地之间的电位差可能几伏甚至几十伏。这个差值会顺着信号线灌进采集电路轻则读数乱跳重则打坏 IO。光耦的作用就是把“电”的联系切断只留“光”的联系输入侧发光二极管亮灭输出侧光敏三极管跟着导通截止两边电气上完全隔离隔离电压可以做到千伏级。电路里两个电阻的取值是有讲究的。R71 是发光二极管的限流电阻决定导通电流一般取几毫安太小了光耦寿命受影响太大了光敏三极管驱动不足。R72 是输出侧上拉它和光耦的电流传输比 CTR 挂钩CTR 是输出电流与输入电流之比输入高电平时要让输出拉到低电平R72 必须小于“电源电压除以CTR 乘以输入电流”。R72 取大了拉电流能力弱带不动后级取小了光敏三极管的暗电流在高电平时会往下拽高电平就不干净。这个取舍没有公式能一步到位通常是按 CTR 的最小值算一遍再留一倍裕量实测。3.3 74HC14 施密特整形把“脏边沿”变成干净时钟开关量经过光耦之后边沿往往已经变得很缓尤其是机械开关或者长线传输过来的信号上升沿可能几百微秒。这种边沿直接进 FPGA会在阈值附近来回抖FPGA 采到一串 0 和 1 交替的假跳变。74HC14 是带施密特输入的反相器它的正向阈值和负向阈值不重合中间有一段回差缓慢变化的输入只要没越过回差带输出就不动等于把抖动的边沿一次性整形成陡峭的方波。它同时还是个反相器所以逻辑极性要在 FPGA 里再翻一次这个细节如果忘了采到的开关状态就是反的。4. FPGA 中心控制一片芯片怎么当整个系统的节拍器4.1 为什么不用一堆 74 系列搭控制逻辑这套系统要产生的控制信号包括模拟开关的地址和使能、ADC 的时钟和启动、Flash 的命令/地址/数据时序、与 PC 并口的握手。如果全用分立逻辑芯片搭板子上得铺几十片 74 系列走线密密麻麻任何一处时序要改都得重新飞线。FPGA 把这些逻辑全部收进一片芯片内部改时序只是改代码重新烧录板子不用动。这是 FPGA 在采集系统里最实在的价值——不是算得快是改得动。4.2 时钟域与数据缓冲FIFO 是采集和存储之间的缓冲垫ADC 按自己的节拍往外吐数据Flash 的写入却是页为单位、有忙周期的两者速度对不上。如果 ADC 数据来了直接往 Flash 写Flash 一忙数据就丢了。所以中间必须有个 FIFO 做缓冲ADC 侧只管往 FIFO 里塞Flash 侧有空了再从 FIFO 里取。FPGA 内部用块 RAM 实现 FIFO深度按“Flash 最长忙时间乘以 ADC 速率”来估。这个深度估小了高速采集时 FIFO 溢出丢的是整段数据估大了浪费片内资源。实际调试时一般先给个保守值跑一遍看溢出标志有没有亮再往下压。4.3 Flash 时序命令、地址、数据为什么要分四个周期喂K9F1G08 是 128M×8bit 的 NAND Flash它的 IO 口是复用的命令、地址、数据都走同一组 8 根线靠 CLE 和 ALE 两根信号区分当前传的是什么。一次页读或页编程要先发命令CLE 高再发地址ALE 高地址还要分四个周期——两个列地址、两个行地址因为 128 字节的物理空间需要 28 位地址8 位一组正好四拍。最后才发数据。这个“分时复用”的设计把引脚数压到了最少代价是控制逻辑必须严格按周期数走少一拍地址芯片就寻址到别的地方去了。// NAND Flash 页编程的时序骨架简化 // 命令 - 4 拍地址 - 数据 - 确认 task flash_page_program; input [7:0] cmd; input [27:0] addr; begin flash_cle 1; flash_ale 0; // 命令周期 flash_io cmd; pulse_we; flash_cle 0; flash_ale 1; // 地址周期共 4 拍 flash_io addr[7:0]; pulse_we; flash_io addr[15:8]; pulse_we; flash_io addr[19:12]; pulse_we; // 行地址低 flash_io addr[27:20]; pulse_we; // 行地址高 flash_ale 0; // 数据周期 // ... 逐字节写入每字节一个 WE 脉冲 wait_ready; // 等 R/B 拉高 end endtaskwait_ready那一步不能省。NAND 的编程和擦除是内部电荷泵在干活耗时毫秒级期间 R/B 引脚拉低。如果 FPGA 不等它变高就发下一条命令芯片直接忽略数据静默丢失——这种错误最难查因为逻辑上看不出问题只是偶尔少一页数据。5. 避坑与排查采集系统最容易翻车的几个地方5.1 采到的模拟值整体偏移现象所有通道读数比实际值系统性偏高或偏低且偏移量固定。原因多半出在电压跟随器的失调或者 ADC 的参考电压不准。LM324 的输入失调电压有毫伏级经过 12 位量化后就是好几个码值。解决先短接输入端测零点看码值是否在 0 附近偏了就查运放供电和参考源必要时在 FPGA 里做一次零点校准减法。5.2 相邻通道串扰现象某通道输入大信号时相邻通道的读数跟着动。原因是模拟开关断开时的泄漏电流和寄生电容耦合通道越多越明显。解决降低源内阻跟随器就是干这个的在通道切换后多等几个建立周期必要时在 ADC 前加一级采样保持。5.3 Flash 写入偶发丢页现象回读数据时发现某几页全是 0xFF 或者旧数据。原因通常是没等 R/B 就绪就发下一条命令或者写保护 WP 引脚在电源波动时被误触发。解决严格按 ready 信号推进状态机WP 上拉到确定电平电源加去耦。5.4 开关量读数抖动现象机械开关动作时FPGA 采到一串快速跳变。原因是开关触点弹跳光耦和施密特只能整形不能消抖。解决在 FPGA 里加计数器消抖连续 N 个时钟采样一致才认N 按弹跳时间除以时钟周期估。5.5 并口传输数据错位现象PC 端收到的数据整体错开一个字节。原因是并口握手时序里FPGA 在 PC 还没准备好时就更新了数据线。解决严格按握手信号如 nStrobe、Busy的边沿推进数据保持到对方确认后再换。6. 设计取舍为什么这套方案选 NAND 而不是 NORNAND 和 NOR 的取舍是这套系统里最能体现工程思维的一处。NOR 的随机读快、可以直接跑代码但写入和擦除慢、单元面积大、成本高NAND 的写入和擦除快得多、单元密度高、每比特成本低代价是不能随机字节寻址必须按页读写、按块擦除而且需要驱动逻辑管理坏块。这套采集系统的数据流是“连续写、事后读”写入量大、读取是整段回放正好落在 NAND 的甜区里。如果换成 NOR同样的容量成本翻几倍写入速度还拖后腿。但选 NAND 就要接受它的脾气擦除单位是块128KB 级别写之前必须先擦擦写次数有限万次量级坏块要标记跳过。这些在 FPGA 里都得用状态机兜住不能像 SRAM 那样随手写。我一般会这么理解NAND 不是“更差的 NOR”它是为顺序大块数据设计的存储介质用对了场景就是最优解用错了就是天天救火。验证这套设计是否站得住最直接的办法是拿已知信号源灌进去回读比对模拟通道灌标准直流电压看量化误差数字通道灌已知频率脉冲看计数开关量手动拨动看状态翻转。三个通道都过一遍再跑长时间连续采集看 FIFO 和 Flash 有没有溢出丢页。从那以后我每次碰采集类项目都强制先把“建立时间、就绪信号、消抖窗口”这三个参数单独拉出来实测一遍不靠纸面估算。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑