0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【经验分享】玩转FPGA串口通信:从“幻觉调试”到代码解析

电子发烧友论坛 ? 2025-06-05 08:05 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

原文地址:?https://bbs.elecfans.com/jishu_2489801_1_1.html?

作者:@王钊

引言:FPGA开发,思路先行!

玩FPGA板子,读代码是基本功!尤其对从C语言转战FPGA的“宝贝们”来说,适应流水线(pipeline)编程可能需要点时间。

上篇点灯代码解读了基础,而如果能亲手写出串口通讯代码,恭喜你,FPGA的大门算是真正踏入了!

本文旨在帮初学者梳理FPGA开发的核心思维流程——思路对了,后面的路才顺畅,这可是重中之重!

一:感性认知 - 烧录 & 看效果

废话不多说,先烧程序,眼见为实!

cf60add0-41a0-11f0-986f-92fbcf53809c.png

在Ubuntu下,等程序烧录完成后,打开gtkterm,通过USB转串口设备节点与板子通讯。

本次烧录的实例实现的是“回显”(Echo):你键盘输入什么,板子就原样发回什么。

cf7a3764-41a0-11f0-986f-92fbcf53809c.png

这种时候我们可能会以为出现了幻觉(这效果对吗?)

好办!在回显代码里“加个1”,把接收到的数据+1再发送

cf8f5c16-41a0-11f0-986f-92fbcf53809c.png

再次烧录以后,测试发现,按键输入123变成了234。果然不是幻觉,我们可以继续看代码了。

经验上讲以上步骤还是必要的,这证明代码是对的,以免被坑。


二:硬件连接 - 原理图 & 管脚对一对

回到代码,Top顶层模块走起!

d04dc444-41a0-11f0-986f-92fbcf53809c.png

输入脚有个25m的时钟,输出有个灯,这跟点灯程序一样。然后串口有收发两个脚。然后我去对一下原理图。

d068e788-41a0-11f0-986f-92fbcf53809c.png

找到原理图第三页,底板的原理图,供电的Type-C口其实连到了CH340 USB转串口芯片(单片机玩家老朋友了!)

这个原理图其实看着有点晕,反正大致意思就是串口发送接收接到了H10和H11这两个脚上。

d08d11ee-41a0-11f0-986f-92fbcf53809c.png

管脚配置瞧一瞧:外部时钟脚和led的脚跟之前点灯的程序一样,下面就是多了H10和H11两个脚,分别对于串口的RX和TX。

然后它们的电平是3.3V的。如果这里看着难受的话可以把它改到其他脚上,然后接一个自己的USB转串口的板子上,自己的串口板只需要多接个GND地线,无需接3.3V电源,加上RX和TX一共3根线,注意RX和TX可能需要反一下。


三:协议基础 - 磨刀不误砍柴工

到这里又要啰嗦一下,FPGA调一个接口,首先就是我们需要清楚的知道接口有个的数据定义,协议等知识。不能上来就研究代码,否则可能会迷糊。

d0a2f9aa-41a0-11f0-986f-92fbcf53809c.png

(图片来源:https://zhuanlan.zhihu.com/p/689643287)

这里是我搜索出来知乎的帖子,讲串口协议的,有需要的话可以补充一下底层知识。

当然相信没几个人不知道串口的,但FPGA开发它还是蛮多套路的,比如接收一帧数据该如何接收。

大致的思路是这样的,我们需要用一个比串口波特率更高的采样信号去采集,串口的RX上什么时候出现起始位,然后接收每个数据位,最后延时一个停止位,再循环检测起始位,接收下一帧数据。


四:代码解析 - 接收模块的奥秘

然后代码我就不再讲倍频和reset逻辑了,点灯程序已经讲过了。

d0c1c9c0-41a0-11f0-986f-92fbcf53809c.png

直接看接收的代码:这里看到模块的调用,可以想象成我们在板子上焊了一块芯片,它有一个clk脚rst_n脚;然后连到了top顶层的UART的RX上;收到数据后会返回一个接收完成的标志,8位的接收到的数据;最后还需要一个比波特率大的,这里是大16倍的采样时钟。

d0d6a4e4-41a0-11f0-986f-92fbcf53809c.png

进入接收模块的代码里,我们看看芯片内部是怎样实现的。这里作者用ASCCII码画了一个时序图,这个太有用了,看代码的时候需要反复的看这个图。

简单说一下这个时序图,IDLE的时候是检测起始位的状态,起始位start是bit0,这里看着它是低电平的;然后到接收数据的状态,也就是bit1到bit8这8位;最后是end停止位,回到IDLE。

所以程序的思路就有了,我们需要在16倍波特率的采样周期上,不停的检测RX脚上的电平,完成串口通讯一帧数据的接收。

d0f47ac8-41a0-11f0-986f-92fbcf53809c.png

接着看代码,作者大神首先把RX脚做了个同步,这个套路不看代码是学不到的,久了看见这种代码脑袋里面会浮现出一个时序图,大概就能看到clk和rx信号的时序,然后理解到为什么要同步。

注意这个模块有两个时钟,一个是系统时钟,一个是16倍的波特率的时钟,它这同步的是系统时钟。咱们先别晕在这里,继续往下看。

d10b7890-41a0-11f0-986f-92fbcf53809c.png

后面的代码是个状态机,这代码还有点多,我抓屏一爪还抓不完。大家可以打开代码自己对着看,反正行号可以看出是讲到哪里了。状态机跟作者的时序图是一致的,就是那些IDLE,start,end之类的状态。

这里还有个特别玄乎的套路,本人也不是大神,所以也没看明白。就是这个状态机是用系统时钟来检测的,那个16倍波特率的采样时钟是在下面用个if来判断的,就是采样信号为高的时候去检测数据信号的高低。本宝认为,为什么不直接把采样信号放在always语句上面用呢。手贱的同学可以改一下试试,看看串口会不会丢数据,试完记得告诉我结论。

d126e0a8-41a0-11f0-986f-92fbcf53809c.png

IDLE状态没什么看头,我们看看start状态。它这里有个采样的计数,一个bit采样16次。这里首先是从IDLE进入START状态需要rx管脚为低电平,并且在16次采样的中间那会不变成低电平,才认为起始信号有效。(为什么不判断全部为高?或者前半段为高?)

反正最重要的是数到16个采样就切到下一个状态,不能快也不能慢,保证时序要求。

这里还有一个套路是我们会看到那些a=a,b=b的语句,其实我感觉是可以删掉的,不知道是不是作者年级比较大,或许以前古时候的综合器不写else后面的东西,它会乱综合一些东西出来。好奇宝宝们可以写个测试程序,看看RTL电路有什么区别,同样,测试出结论以后记得告诉我……

d13b559c-41a0-11f0-986f-92fbcf53809c.png

采样状态的逻辑看了半天,也没真正做采样的事情,只是输出了一个变量rxd_cnt,这个变量表示采样的是第几个bit,还要注意的是这个变量在什么时候被锁存改变的,我们注意到是在采样计数为最后一个的时候锁存的。

d151f46e-41a0-11f0-986f-92fbcf53809c.png

停止状态啥也没干,只是保证延时一个波特率的时间而已。

d1688fd0-41a0-11f0-986f-92fbcf53809c.png

接着看代码,上面采样状态输出了一个变量rxd_cnt,然后这里才进行真正的采样操作,它同时判断了采样计数器cmp_cnt,保证是在波形中部进行采样。可能这么做是增加鲁棒性。相信看到这里有些人会表示不服,我们可以把串口线接长一点,中间再加点电磁干扰,这样比较一下如果不在中间采样会不会导致丢数据的比率变高。同样,如果有人测试了,记得把结论告诉我!!!

d1833704-41a0-11f0-986f-92fbcf53809c.png

最后一段代码是输出一帧率数据接收完成的标志,可以看到它的锁存逻辑是在停止位发送完毕的时候持续了一个采样时钟的高电平。同时锁存输出数据。

d1967c38-41a0-11f0-986f-92fbcf53809c.png

五:发送模块 - 相对简单

再往下就是看发送逻辑了,这块逻辑跟接收逻辑几乎一样。其实发送逻辑大可不必这么精细,因为接收才需要高频率的采样,发送只要保证时序就可以了。如果实在看不懂接收逻辑,我建议大家还是直接写一下发送逻辑,比如就按作者画的时序图,先用pll生成一个波特率的时钟,再按照时钟调整TX管脚的高低电平即可。最后用上面讲的接长串口线的方法测试一下数据传输的效率。

d1ab59f0-41a0-11f0-986f-92fbcf53809c.png

大半夜的不知道谁拍了我一下,我就突然看到这块代码有点不对……这个case里面的语句的等于符号前面居然没有小于符号了。这种情况奶奶没教过啊,而且它always语句里面是个*号。其实verilog我也是只学了三天,所以不太确定这是不是就是个组合逻辑电路。哎,这个迷哪位好心人回帖告诉我一声好不好。

d1bf31be-41a0-11f0-986f-92fbcf53809c.png

万一有人整篇文章都看不懂,这里有个好玩的东西,test_io这个脚是接到灯上的,它这里的逻辑是TX和RX上只要有数据变化,灯就会闪烁,实测我一直往串口输入字符a,这个灯是可以看到闪烁的,闪的比较暗,大家可以关灯看看。

终极总结:FPGA接口开发心法

总结一下,关于接口的实现,无论接口多复杂,其实也是逻辑电平的控制,但前提是需要对协议非常的熟悉,再就是一下FPGA代码的套路了,这些套路都是一点一点看众大神的代码悟出来的。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1646

    文章

    22069

    浏览量

    619731
  • 串口通信
    +关注

    关注

    34

    文章

    1641

    浏览量

    56929
  • 开发板
    +关注

    关注

    25

    文章

    5725

    浏览量

    105607
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    fpga时序分析案例 调试FPGA经验总结

    今天跟大家分享的内容很重要,也是调试FPGA经验的总结。随着FPGA对时序和性能的要求越来越高,高频率、大位宽的设计越来越多。在调试这些
    的头像 发表于 08-01 09:18 ?2542次阅读
    <b class='flag-5'>fpga</b>时序分析案例 <b class='flag-5'>调试</b><b class='flag-5'>FPGA</b><b class='flag-5'>经验</b>总结

    基于FPGA的USB串口通信设计

    用altera de2进行FPGA的USB串口通信,实现电脑和USB连接,电脑可传输信息(数字和字母)FPGA上并用lcd显示。求
    发表于 05-19 16:59

    【技术经典下载】《深入浅出玩转FPGA》-珍贵的学习经验和笔记

    `简介:《深入浅出玩转FPGA》收集整理了作者在FPGA学习和实践中的经验点滴。书中既有日常的学习笔记,对一些常用设计技巧和方法进行深入探讨;也有很多生动的实例分析,这些实例大都是以特
    发表于 06-15 17:46

    特权同学新书《勇敢的芯伴你玩转Altera FPGA》电子版 下载 (FPGA初学者首选)

    串口芯片驱动安装4.6.1驱动安装4.6.2设备识别第5章Verilog语法概述5.1语法学习的经验之谈5.2可综合的语法子集5.3代码风格与书写规范勇敢的芯伴你玩转Altera
    发表于 10-11 20:59

    赛灵思FPGA初学者 必备图书 特权同学新书《勇敢的芯伴你玩转赛灵思 FPGA

    调试7.8SRAM读写测试7.8.1SRAM读写时序解读7.8.2功能简介7.8.3代码解析7.8.4Xilinx库设置7.8.5功能仿真7.8.6FPGA在线配置7.8.7触发采样波
    发表于 11-27 12:23

    串口通信调试(PC与PC串口通信

    【LabVIEW入门精通】4.1.6 串口通信调试(PC与PC串口
    发表于 01-08 15:43 ?0次下载

    串口通信调试(PC与智能仪器串口通信

    【LabVIEW入门精通】4.1.6 串口通信调试(PC与智能仪器串口
    发表于 01-08 15:42 ?0次下载

    最详尽的——解析串口通信数据

    最详尽的——解析串口通信数据
    发表于 12-05 14:56 ?3次下载

    串口通信调试软件的功能与使用方法

    本文主要介绍了串口通信原理、串口通信结构、串口通信调试
    发表于 12-27 15:02 ?1.8w次阅读
    <b class='flag-5'>串口</b><b class='flag-5'>通信</b><b class='flag-5'>调试</b>软件的功能与使用方法

    MATLAB串口调试助手应用程序和基于MATLAB开发USB的串口通信源代码

    本文档的主要内容详细介绍的是MATLAB串口调试助手应用程序和基于MATLAB开发USB的串口通信源代码
    发表于 11-05 08:00 ?98次下载
    MATLAB<b class='flag-5'>串口</b><b class='flag-5'>调试</b>助手应用程序和基于MATLAB开发USB的<b class='flag-5'>串口</b><b class='flag-5'>通信源代码</b>

    PID算法原理_调试经验以及代码总结

    PID算法原理_调试经验以及代码总结分享。
    发表于 05-25 15:59 ?16次下载

    单片机——串口通信串口接收多位数据保存到数组,发送多位数据串口

    单片机串口通信中,接收多位数据数组,发送多位数据的代码// 下面的代码用于:单片机的串口何上位
    发表于 11-17 11:06 ?45次下载
    单片机——<b class='flag-5'>串口</b><b class='flag-5'>通信</b>(<b class='flag-5'>从</b><b class='flag-5'>串口</b>接收多位数据保存到数组,发送多位数据<b class='flag-5'>到</b><b class='flag-5'>串口</b>)

    PID算法原理、调试经验以及代码资料

    PID算法原理、调试经验以及代码资料
    发表于 11-21 10:25 ?15次下载

    单片机UART串口通信(代码亲自调试成功)

    单片机UART串口通信单片机的串口通信,一般指的就是UART串口通信(TXD,RXD)。本文实现
    发表于 11-23 17:36 ?18次下载
    单片机UART<b class='flag-5'>串口</b><b class='flag-5'>通信</b>(<b class='flag-5'>代码</b>亲自<b class='flag-5'>调试</b>成功)

    玩转ZMP110x创新串口屏的虚拟串口屏开发模式

    ZMP110x创新串口屏应用开发如何脱离硬件,仅在PC上就完成全部的UI开发和通信调试工作?下面就跟随小编步伐,一起玩转虚拟串口屏开发模式吧
    的头像 发表于 02-02 14:18 ?2255次阅读
    <b class='flag-5'>玩转</b>ZMP110x创新<b class='flag-5'>串口</b>屏的虚拟<b class='flag-5'>串口</b>屏开发模式