刚把ADC采样跑通,一接串口数据就丢、就乱。问题通常不在ADC,也不在UART,而是中间"高速域→低速域"这段搬运链路没拆清楚。下面按工程顺序拆五步。
第一步:ADC数据怎么进来
ADC与FPGA的接口分三类:SPI/I2C(低速,如AD7685)、并行总线(中高速,如AD9281)、高速串行(JESD204)。入门最常见的是SPI:片选拉低→时钟振荡→数据移位→片选释放,一个周期完成一次转换。SCLK频率和片选脉冲宽度直接决定采样率上限。
第二步:数据先存哪里
ADC出数据速率(比如500kHz)远大于UART吞吐(115200bps下约11.5KB/s),不能采一个发一个,必须加缓冲。工程上常用FIFO:写端挂在采样时钟,读端挂在UART发送时钟。若ADC出16bit而UART一次发8bit,还要做位宽拆分,把高字节、低字节依次入FIFO。
第三步:跨时钟域怎么过
FIFO本身就是跨域桥梁,但要选对类型。两端时钟同源用同步FIFO;不同源用异步FIFO(格雷码指针)。若只同步单比特信号(如FIFO非空标志),两级触发器够用,但要理解亚稳态窗口。ADC采样时钟和UART TX时钟大概率不同源,异步FIFO是稳妥选择。
第四步:UART发送怎么触发
轮询:发完一帧等FIFO非空,读一字节点发,状态机持续空转。中断:FIFO水位到阈值触发TX中断,PS端在中断服务里搬字节。纯PL设计没有PS,就用状态机轮询加发送间隔计数器控制节奏。
第五步:怎么调通
每接一层抓一层波形。ADC端用ILA抓SCLK和数据线;FIFO写端、读端各抓一次确认位宽没错位;UART TX线量起始位、数据位、停止位是否对齐。哪段乱了查哪段,别一口气从头调到尾。
会。500kHz×16bit就是8Mbps原始数据率,115200bps的UART扛不住。两条路:提高波特率到921600以上,或在ADC侧做抽稀(每N个样本取一个)。更常见的工程做法是数据先存BRAM或DDR,上位机走以太网批量拉取,串口只留调试控制通道。
取决于跨的是什么。单比特控制信号用两级触发器同步即可。多比特数据(ADC采样值)必须用FIFO,因为多比特直接两级同步会出现总线撕裂——高位已更新、低位还在旧值,读出来一个不存在的数。FIFO内部格雷码指针天然解决多比特跨域。
ADC→FIFO→CDC→UART,四步拆完链路就通了。你手头的ADC是几位采样、串口锁死多少bps?带着参数来聊。
拿不准ADC该配SPI还是并行口、FIFO深度算多大、波特率怎么定才不丢包——点开页面右下角客服窗口,直接和我们FPGA方向的教研老师对接,报上芯片型号,给你参数级的落地建议。
未经许可,禁止转载!