简介:这份资源是一份面向电子信息、自动化及相关专业本科生与初学者的毕业设计文档,围绕基于FPGA的数据采集系统展开,帮助读者理解如何以FPGA为核心搭建多通道实时采集与存储方案。压缩包内共1个doc文件,约526KB,为完整的本科毕业设计说明书,涵盖绪论、系统硬件设计等章节,可据此梳理课题背景、整体设计方案与硬件实现思路。文档重点讨论六十四路模拟信号、八路无源开关量信号及一路数字脉冲信号的采集,涉及电压跟随器、模拟开关、A/D转换、FPGA中心控制、存储器与并口通信等模块,并给出系统框图和通道设计说明。已有638人学习,适合需要参考数据采集系统设计流程、撰写开题或毕设文档的读者对照查阅。
1. 从“64 路模拟信号怎么塞进一片 FPGA”说起
做数据采集毕设,最容易翻车的地方不是写代码,而是需求没定死就急着画原理图。我见过一个典型场景:被测对象有 64 路 0~5V 模拟信号、8 路无源开关量、1 路 TTL 或 12V 脉冲数字信号,要求实时采集并存储,事后回读分析。如果每个模拟通道都配一套运放加 ADC,光是器件数量和布线密度就足以让一块板子报废。所以这套方案的核心思路很明确:用多路模拟开关做通道分时复用,用一片 FPGA 统一调度 ADC 时序、存储器读写和接口传输,把“采集—转换—存储—回读”这条链路收进一个可控的时序黑匣子里。它适合正在做数据采集方向毕设或课设、需要一份从硬件结构到逻辑控制都能讲清楚的完整方案的人。
2. 需求拆解与总体架构:三类信号、四个模块的职责边界
2.1 先把被测信号分类,再谈通道设计
这套系统的输入不是单一类型,而是三类信号混在一起:64 路模拟量、8 路无源开关量、1 路数字脉冲。很多方案一上来就画大框图,结果模拟通道和开关通道的电气特性没分开,调试时互相干扰。我一般的做法是先按信号性质分三条独立通道,再在中心控制模块汇合。
模拟通道的关键约束是电压范围 0~5V、通道数多、精度要求 12 位。开关量是无源触点,需要隔离和驱动后才能进逻辑器件。数字脉冲可能是 TTL 电平,也可能是 0V/12V 脉冲,必须先做电平钳位。三条通道的采样节拍不同:模拟量靠 ADC 转换完成,开关量和数字量本质是逻辑电平锁存,可以在 FPGA 内部用更快的时钟采样。
提示:需求阶段一定要把每类信号的电压范围、通道数、采样率上限写进设计说明,后面选器件、算时序全靠这几个数。
2.2 四个模块的职责划分
整体结构由信号采集模块、中心控制模块、存储器模块、接口电路四部分组成。信号采集模块负责模拟开关切换、电压跟随、ADC 转换、电平调整、光电隔离和驱动整形;中心控制模块以 FPGA 为核心,产生 ADC 时钟、模拟开关通道选择信号、存储器读写时序和与 PC 的并口握手信号;存储器模块用 NAND Flash 完成非易失存储;接口电路采用并口方式与 PC 通信,完成数据回读。
这个划分的好处是职责清晰:采集模块只关心“信号能不能干净地变成数字量”,控制模块只关心“什么时候采、采完往哪写”,存储模块只关心“页编程和块擦除的时序”,接口模块只关心“PC 什么时候来取数”。调试时可以分模块验证,不用一上来就整板联调。
2.3 总体数据流与时序主线
数据流主线是:传感器信号 → 电压跟随 → 多路模拟开关 → ADC → FPGA 内部缓冲 → NAND Flash → 并口 → PC。FPGA 内部通常的做法是例化一个 FIFO 做速率缓冲,ADC 输出速率和 Flash 页编程速率不匹配时,FIFO 起到削峰填谷的作用。时序上,FPGA 先给出模拟开关通道地址,等待建立时间后启动 ADC 转换,转换结束把 12 位并行数据锁进 FIFO;FIFO 达到页容量后触发 Flash 页编程。开关量和数字量则通过 FPGA 内部串并转换后写入同一存储空间,回读时按预先约定的帧格式拆分。
3. 模拟采集通道设计:从运放到 ADC 的器件选型与参数计算
3.1 电压跟随与多路开关的配合
64 路模拟信号直接进模拟开关,源阻抗不一致会导致通道间串扰。通常的做法是在每路输入后加电压跟随器,本方案用 LM324 四运放做跟随,作用是稳定输入信号、提高后级输入阻抗。LM324 单电源可用、静态功耗小、价格低,适合多通道场合。64 路需要 16 片 LM324,布局时按通道分组靠近模拟开关放置,减少走线长度。
模拟开关选 ADG506,16 选 1,低泄漏典型值 20pA,导通电阻约 200Ω,导通和关断时间各约 200ns。四片 ADG506 级联可覆盖 64 路,通道地址 A1~A4 和使能 A6 全部由 FPGA 提供。这里有个容易忽略的点:导通电阻会和后级输入阻抗形成分压,如果 ADC 前端输入阻抗不够高,0~5V 信号会有跌落。所以跟随器要放在开关之前,开关之后直接进 ADC 的采样保持输入端。
// 64 路模拟通道地址扫描:4 片 ADG506,每片 16 通道 // ch_addr 低 4 位选片内通道,高 2 位选片号 reg [5:0] ch_addr; always @(posedge clk_1m) begin if (sample_en) begin ch_addr <= ch_addr + 6'd1; // 1MHz 节拍下循环扫描 64 通道 end end assign adg_a = ch_addr[3:0]; // A1~A4 通道选择 assign adg_en = (ch_addr[5:4] == 2'b00) ? 4'b0001 : (ch_addr[5:4] == 2'b01) ? 4'b0010 : (ch_addr[5:4] == 2'b10) ? 4'b0100 : 4'b1000;这段逻辑的含义是:用 6 位计数器在 64 个通道间循环,低 4 位送四片 ADG506 的公共通道地址,高 2 位译码成片选使能。参数上,clk_1m是 1MHz 扫描节拍,实际采样率还要受 ADC 转换时间和开关建立时间约束,通常的做法是每个通道地址稳定后再延迟若干个时钟才启动转换。
3.2 ADC 选型:为什么是 AD9221
ADC 类型很多,并行比较型速度快但分辨率低、功耗大;逐次逼近型速度精度均衡;积分型精度高但速度慢;流水线型兼顾速度和分辨率。本系统要求 12 位、多通道分时采集,单通道等效采样率不需要极高,但转换速率要跟得上 64 路轮询。AD9221 是 12 位、最高 1.5MSPS 的流水线型 ADC,单电源 5V 供电,输出并行接口兼容 TTL,内部带采样保持和可编程基准源,正好匹配这个场景。
选型时要算一笔账:64 路轮询,如果每路分配 10μs,一轮约 640μs,等效每通道约 1.5kSPS。AD9221 的 1.5MSPS 转换能力远高于这个需求,余量充足。分辨率 12 位对应 0~5V 满量程,最小分辨电压约 1.22mV,满足一般工业监测精度。ADC 时钟由 FPGA 提供,数据从 VINA 单端输入,12 位并行输出直接进 FPGA 的 IO 口。
// AD9221 采样控制:地址稳定后延时启动转换,转换完成锁存数据 localparam SETTLE = 8'd20; // 模拟开关建立延时,按开关时间 200ns 留足余量 reg [7:0] settle_cnt; reg adc_clk_r; always @(posedge clk_50m) begin if (ch_addr_changed) begin settle_cnt <= 8'd0; adc_clk_r <= 1'b0; end else if (settle_cnt < SETTLE) begin settle_cnt <= settle_cnt + 8'd1; end else begin adc_clk_r <= ~adc_clk_r; // 产生 ADC 转换时钟 end end assign adc_clk = adc_clk_r;这里SETTLE是通道切换后的建立延时计数,按 50MHz 主时钟算,20 个周期约 400ns,覆盖 ADG506 的 200ns 开关时间并留余量。ADC 时钟频率不能超过器件上限,实际取值要结合一轮 64 通道的总采样时间和 Flash 写入速率反推,不能拍脑袋定。
3.3 数字脉冲与开关量的前端处理
数字脉冲输入可能是 TTL 电平,也可能是 0V/12V 脉冲,而存储器 IO 是 3.3V,必须做电平调整。通常的做法是用 3.3V 稳压管做钳位:输入高于 3.3V 时被钳在 3.3V,低于 3.3V 时原样通过,再串限流电阻保护稳压管。这个电路简单,但限流电阻阻值要算:按输入 12V、稳压管工作电流几毫安来选,阻值太大钳位效果差,太小则功耗和发热上去。
8 路无源开关量需要隔离和驱动。本方案用光电耦合器做隔离,输入高低电平通过发光二极管和光敏三极管传递,电气上完全隔离,抗地电位差和电磁干扰。光耦输出再接 74HC14 施密特反相器做整形和驱动,把缓慢变化或带抖动的边沿整成陡峭逻辑电平。光耦限流电阻决定 LED 导通电流,一般取数毫安;输出侧上拉电阻要满足电流传输比条件,阻值太大会导致拉电流能力不足、暗电流影响高电平,通常的做法是按 CTR 最小值反算上限,再留一倍余量。
4. FPGA 中心控制与 Flash 存储:时序状态机怎么写才不翻车
4.1 FPGA 内部逻辑划分
中心控制模块以 FPGA 为核心,本方案选 Spartan 系列 XC2S50,配置芯片用 XC18V01,供电用 TPS70358。FPGA 内部逻辑通常划分为四个部分:采样控制状态机、FIFO 缓冲、Flash 读写控制器、并口回读接口。采样控制状态机负责通道扫描和 ADC 启动;FIFO 做跨时钟域缓冲,ADC 侧和 Flash 侧时钟不同;Flash 控制器实现命令、地址、数据的 IO 复用时序;并口接口按 PC 握手信号把存储数据送出。
用一片 FPGA 替代大量分立逻辑芯片,好处是时序可重配、板面积小、可靠性高。代价是逻辑设计必须一次想清楚,尤其是 Flash 的页编程和块擦除时序,写错一个周期就整页数据报废。
4.2 NAND Flash 的页编程与块擦除时序
存储芯片选 K9F1G08,128M×8bit NAND Flash,3.3V 单电源,非易失。NAND 的特点是写入和擦除快、单元密度高,但需要驱动和坏块管理,不能像 NOR 那样直接跑代码。它的 IO0~IO7 复用传命令、地址和数据,CLE 高时锁命令,ALE 高时锁地址,WE 上升沿锁存,RE 下降沿读有效,R/B 指示忙闲。
一页 2112 字节,其中 2048 字节主数据区加 64 字节备用区。地址需要 4 个周期:2 个列地址加 2 个行地址。页编程流程是:发写命令 80h → 发 4 周期地址 → 写数据 → 发确认命令 10h → 等待 R/B 变高。块擦除只发 2 个行地址,命令是 60h 和 D0h。下面是一个简化的页编程状态机骨架:
// K9F1G08 页编程简化状态机(命令-地址-数据-确认-等待) localparam IDLE = 3'd0, CMD_80 = 3'd1, ADDR = 3'd2, DATA = 3'd3, CMD_10 = 3'd4, WAIT_RB = 3'd5; always @(posedge clk) begin case (state) IDLE: if (page_wr_req) state <= CMD_80; CMD_80: begin flash_io <= 8'h80; flash_cle <= 1'b1; flash_we <= 1'b0; // WE 上升沿锁存命令 state <= ADDR; end ADDR: if (addr_cnt == 2'd3) state <= DATA; // 4 周期地址 DATA: if (data_cnt == 11'd2047) state <= CMD_10; CMD_10: begin flash_io <= 8'h10; flash_cle <= 1'b1; state <= WAIT_RB; end WAIT_RB: if (flash_rb) state <= IDLE; // R/B 变高表示编程完成 endcase end这段状态机只表达主干流程,实际代码里还要处理 WE/RE 的建立保持时间、IO 方向切换、写保护 WP 的上电时序。参数上,data_cnt按页主数据区 2048 字节计数,备用区是否使用要在帧格式里提前约定。R/B 是开漏输出,FPGA 侧要加上拉。
4.3 FIFO 缓冲与跨时钟域处理
ADC 输出节拍和 Flash 页编程节拍不一致,直接对接会丢数。通常的做法是在 FPGA 内部例化异步 FIFO:写侧用 ADC 转换完成信号做写使能,读侧在 Flash 空闲时按页容量突发读出。FIFO 深度按一页数据量设计,至少能缓存 2048 字节,留一定余量防止溢出。跨时钟域时,读写指针用格雷码同步,空满标志用保守判断,避免亚稳态导致误判。
注意:FIFO 满标志如果只做组合判断,在跨时钟域下可能晚一拍,导致覆盖未读数据。稳妥做法是满标志提前一个单元置位,牺牲一点容量换可靠性。
4.4 并口回读接口的握手设计
与 PC 的接口采用并口传输,字节并行。FPGA 侧实现一个简单的握手:PC 拉低读请求,FPGA 把当前字节放到数据总线并给出应答,PC 取走后释放请求。回读时要按采集时写入的帧格式解析,帧头包含通道号、信号类型和时间戳,帧尾做校验。并口线缆不宜过长,否则高速下误码率上升,通常的做法是回读速率降到采集速率的几分之一,优先保证正确性。
5. 联调避坑:五条最容易翻车的点
5.1 模拟通道串扰,换通道后数据跳变
现象是相邻通道采集值互相污染,某一路大电压会影响下一路小信号。原因通常是模拟开关通道切换后建立时间不够,或者跟随器输出阻抗与开关寄生电容形成慢建立。解决方法是加大通道切换后的延时计数,必要时在开关输出加小电容滤波,同时检查 PCB 上模拟走线是否远离数字信号线。
5.2 ADC 时钟抖动导致有效位下降
现象是静态输入时采集码值跳动几个 LSB,超出量化误差预期。原因多为 ADC 时钟由普通 IO 直接输出,边沿不够陡或存在毛刺。解决方法是时钟走专用时钟网络,输出串匹配电阻,必要时用 FPGA 内部 PLL 产生稳定时钟,并确保时钟线上没有其他信号跨割。
5.3 Flash 页编程失败,回读全 FF
现象是写入后回读全是 0xFF,或者整页数据错位。原因常见于地址周期数不对、CLE/ALE 与 WE 的时序配合错误,或者未等待 R/B 就发下一条命令。解决方法是先用单页写读对比验证状态机,再扩展到多页;用逻辑分析仪抓 CLE、ALE、WE、R/B 四根线,逐周期核对时序图。
5.4 开关量光耦输出电平不干净
现象是开关量采集出现抖动或误判。原因是光耦输出上拉电阻取值不当,CTR 离散性导致部分器件饱和不够,或者 74HC14 输入端悬空。解决方法是用 CTR 最小值反算上拉电阻上限,输入端加确定电平,施密特整形后再进 FPGA,软件上再做几次采样表决。
5.5 并口回读丢字节
现象是 PC 端收到的数据长度对不上或帧头错位。原因多为握手信号竞争,PC 侧读走数据与 FPGA 更新数据总线同时发生。解决方法是严格单向握手:FPGA 只在收到请求后更新总线,应答释放后才准备下一字节,回读时钟留足建立保持时间。
6. 验收与答辩:怎么证明这套采集系统真的能跑
验收不要只演示“灯亮了、数出来了”,要按指标逐项打表。我一般会准备一张验收记录表,现场按顺序过一遍,答辩时直接拿数据说话。
| 验收项 | 测试方法 | 合格判据 |
|---|---|---|
| 模拟通道数 | 逐路加已知直流电压,回读通道号 | 64 路全部可寻址,无串道 |
| 模拟精度 | 输入 0V、2.5V、5V 三点,回读码值 | 误差在 ±2LSB 内 |
| 开关量 | 8 路逐一短接/断开 | 状态与回读一致,无抖动 |
| 数字脉冲 | 输入 TTL 与 12V 脉冲各一组 | 计数与频率误差在约定范围内 |
| 存储完整性 | 写满一页后回读比对 | 数据逐字节一致 |
| 掉电保持 | 写入后断电再上电回读 | 数据不丢失 |
| 连续采集 | 连续运行 30 分钟 | 无丢帧、无死机 |
答辩时老师最爱问三个问题:为什么选 NAND 不选 NOR、64 路怎么保证不串扰、FPGA 里 FIFO 满了怎么办。前两个在前面章节已有答案,第三个要能说清楚满标志策略和降速回读的取舍。演示顺序建议先静态精度、再动态采集、最后掉电回读,每一步都对应表里一行,节奏稳。
血泪经验是:联调阶段一定要先做单通道闭环,再做多通道轮询,最后接 Flash。我见过直接整板联调、结果分不清是模拟开关问题还是 Flash 时序问题的情形,排查花的时间比重新分步验证多几倍。从那以后我每次做采集类项目,都强制走一遍“单通道—多通道—存储—回读”的分步验收,每一步留测试记录。希望帮到你。
本文还有配套的精品资源,点击获取