原创 零基础学FPGA(十)牛刀小试——串行口通信电路设计

2014-6-11 03:29 4222 8 22 分类: FPGA/CPLD 文集: FPGA/CPLD

      以前在学单片机的时候,觉得串口通信其实很简单,只要一个指令数据就能轻易的接收或者发送。前几天试着用FPGA实现,发现里面的学问还不少,并没有想象的那么简单。当然代码肯定是参考别人的,不过我还是认真研究了整段代码的,下面的程序就是我在看懂了别人代码后自己敲的,花了也不少时间,理解的也差不多,下面我就在这里给那些和我一样的初学者介绍一下吧,解释的不对的地方还望各位大神指正,大家好一起学习~

     1、顶层模块

      写程序都一样,不能多有的程序都写在一个模块里,那样看起来很麻烦,出了错误也不好维护,对于一些小的程序我们可以写在一个模块里,但程序一旦复杂起来还是要懂得模块化编程的,对于顶层模块,最好是只写接口就好了,例如:

 

360桌面截图20140611024920.jpg
 
 
     这段代码中,rx_232是我们的底层模块名,后面跟着的那个rx呢是我们自己取的名字,是任意的。后面的一大串呢就是接口,为了直观呢,建议大家采用我的这种写法,看上去比较清楚明白,括号里面的接口是我们顶层文件的接口,括号外面的是我们调用底层模块的接口,这些接口要一一对应正确才能保证数据之间的传输。
     在顶层模块中,我们只定义了数据输入接口,用来接收数据,数据输出接口,用于发送数据,时钟接口,和复位接口。这四个接口是有输入输出关系的,对于其他的接口,是属于我们整个模块内部的接口,是模块与模块之间的接口,既非输入,也非输出,相当于一根导线一样,所以我们把他们定义成wire型变量
 
 
360桌面截图20140611025725.jpg
 
 
  2、波特率选择模块
       单片机或者计算机在串口通信时的传输速率用波特率表示,9600bps表示的就是每秒钟传送9600位的数据
这里之所以计数到5027,在这里算一下。
  1秒传送9600位,那么传送一位的时间就可以算出,即1s=1000_000_000ns,所以传送一位数据需要1000_000_000/9600=
104166ns,而我们的时钟周期为20ns,因此需要计数到104166/20=5028个时钟周期
 
下面是串口通信时序图
360桌面截图20140611025958.jpg
 
我再来解释一下这个图吧,我当时学单片机的时候还真是没怎么重视这张图,只知道只要一个指令就可以发送,没有真正搞清楚是怎么发送和接受的,那就在这里复习一下吧
   计算机和单片机之间进行通信,这里用的是rs232通信方式,即通信之前,计算机和单片机之前要设定好相同的波特率,只有波特率相同了才能进行通信。
    其次,计算机发送数据时要先发送一个起始位,一般是低电平,后面跟着的是8位数据位,奇偶校验位,停止位等,当起始位低电平信号传送到我们的接收端口时,在接收模块中会发送一个命令给波特率时钟计数器,开始计时,计时到一半的时候会产生一个采样高脉冲信号,当接收模块检测到这个高脉冲之后就会将数据存到寄存器中,当检测到第11个脉冲信号时,也就是代表一帧的数据接收完毕,发送模块就给波特率选择模块发送一个停止信号告诉它停止计时。同时,当数据接收完毕之后也会产生一个信号告诉发送模块,信号已经接收完毕,准备发送,这个时候发送模块再给波特率计时模块发送一个信号开始计时,计数到某一位的中间时产生一个采样信号,当发送模块检测到采样信号之后就将寄存器里的数据送到发送端,每次只送一位,这样就实现了数据的接收与发送。
 
下面是波特率计时模块的主要程序部分
360桌面截图20140611031456.jpg
 
 
3、数据接收模块
 
      在接收模块中,为了准确的检测计算机发送来的数据起始位的那个低电平信号,用到了边沿脉冲检测法,可以有效的避免毛刺现象带来的问题
360桌面截图20140611031721.jpg
下面是发送部分的主要程序段
 
360桌面截图20140611031941.jpg
    4、数据发送模块
 
发送模块原理上和接受模块是一样的,不同点就是接收模块通过边沿检测法检测起始位低电平信号来启动接收数据,而发送模块是通过检测数据发送完毕后,我们认为的置一个低电平信号,发送模块通过检测这个低电平信号来启动发送。见下图
 
360桌面截图20140611032357.jpg
 
下面是生成的RTL视图
 
 
360桌面截图20140611032513.jpg
 
 
下面是测试结果
 
360桌面截图20140611032629.jpg
 
 
下面提供源代码
 
 

 

 

 

文章评论14条评论)

登录后参与讨论

用户3624175 2016-5-4 22:25

很赞,博主

用户1869406 2016-1-22 16:41

新手,试用了下,然而并没有接收到数据,不过对于学习还是很有用的。有很大帮助!!!

用户1868439 2016-1-21 22:21

正在学习,谢谢分享!

用户1076115 2016-1-2 18:26

谢谢分享!找了好久,终于找到你了,谢谢 !

用户1728664 2015-8-11 16:36

一起努力吧

用户1841005 2015-7-25 09:01

请问波特率选择模块中 计数到初始位脉冲宽度的一半的 2603是怎么计算得来的啊

用户1821079 2015-6-24 21:25

写的非常好,拯救初学者了

用户1479666 2015-4-11 11:14

谢谢分享 菜鸟表示非常感谢

用户1832834 2015-3-26 10:37

继续加油,跟你一起学!

584642877_350004634 2015-1-6 21:09

是的,采样脉冲主要是用来脉冲计数的,当起始位发来的时候我们进行一次采样,表示即将有数据发送过来,在接下来有8次脉冲采样,分别记录8位的数据,当收到的数据为8时,停止采样,所以在中间附近采样点都是可以的
相关推荐阅读
小墨同学 2015-09-10 10:28
零基础学FPGA( 三十二) 写在京城,多级FIR半带滤波器的FPGA实现
        每次到京城来总不能忘了出去逛逛吧,偌大的北京城去哪呢?炙热的大太阳烤的哪都不想去了,幸好这次有亲戚来北京旅游,搭个顺风车便出去转了一下。这次的闲逛可没有上次那么感叹,上次主要是去的...
小墨同学 2015-08-29 15:19
零基础学FPGA(三十三)多相结构抽取滤波器笔记
        前两篇文章已经介绍过了,在多速率信号处理中,CIC滤波器和FIR半带滤波器应用的非常广泛,由于CIC滤波器的特殊结构,使得它非常适合采样速率远远大于信号速率的情况时的抽取跟内插滤波...
小墨同学 2015-08-29 15:18
零基础学FPGA(三十一)写在京城,Hogenauer CIC抽取滤波器的FPGA实现笔记
         实习完还没几天,突然接到北京至芯雷总的电话,让我赶往北京来做一些事情,就这样,我的又一趟北京之旅开始了。         上次来北京还是今年1月份,冬天嘛,京城光秃秃的一片,...
小墨同学 2015-08-05 20:50
【博客大赛】零基础学FPGA (二十六)必会! 从静态时序分析到SDRAM时序收敛(上篇)
    好像小墨有这么一个习惯啊,就是每篇文章的开头总喜欢叨叨几句啊~既然这样,那我们今天也聊几句好了,总感觉直接就开始学习专业知识有点让人看不进去~     今天我们就说说生活吧~时间很快啊,...
小墨同学 2015-07-26 21:57
[博客大赛]零基础学FPGA(三十) IIR数字滤波器的FPGA实现笔记
      然而暑假已经过了快一半,想想也是挺快的,前一段时间学校安排实习,在长沙待了一段时间,说是实习,感觉却是像是度假,住着酒店,100多号人,想想都觉的热闹。实习搞得是Java安卓,当然我也...
小墨同学 2015-06-17 09:50
[博客大赛] 零基础学FPGA (二十九)滤波器开篇,线性相位FIR滤波器的FPGA实现
        也是有一段时间不写博客了啊,主要是这学期的实验课太多,每天都是在写预习报告,实验报告中度过,也快到考试月了啊,感觉又要忙起来了,今天就抽点时间来开个头,开什么头呢?对!就如标题所示...
我要评论
14
8
关闭 站长推荐上一条 /2 下一条