原创 串口RS232通信程序(Verilog)

2009-4-13 18:15 13747 9 15 分类: FPGA/CPLD

串口RS232通信程序(Verilog<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


      串口有9个管脚,其中只有三个是最重要的,分别是


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


fca62ca1-a2f9-4a93-b38e-e2df0eec137e.jpg


 


pin 2: RxD (receive data). 接收数据


pin 3: TxD (transmit data). 发送数据


pin 5: GND (ground).     


 


串行通信时序


   我们先来看看字节0x55的发送


 


014b6e50-367c-4585-b8f6-d50829b72045.jpg



 


 0x55的二进制代码是01010101,但发送时由低字节开始的,因此发送次序依次为1-0-1-0-1-0-1-0.


 


串行通信电平


·                     "1" is sent using -10V (or between -5V and -15V).


·                     "0" is sent using +10V (or between 5V and 15V).


 由于计算机RS232的电平与电路板(通常+5V)之间电平的不同所以要用到转换芯片


如果PCB板电源+-5V的话用MAX232


如果PCB板(FPGA)电源是+-3.3V的话用MAX3232



 


f4f527dc-2202-4efa-a045-0a9859a31902.jpg


  


 这个图的串口如果采用母头的话,要用交叉公母线,保证是PCB板上这边的RxD连计算机的TxD3 Pin),PCB板这边的TxD连计算机的RxD(2 Pin).


 



8f6f5779-b540-489e-828f-1dd19b9cb0eb.jpg


 


串行通信波特率


这里要弄清楚波特率与比特率的差别


比特率是数字信号的传输速率,它用单位时间内传输的二进制代码的有效位(bit)数来表示,其单位为每秒比特数bit/s(bps)、每秒千比特数(Kbps)或每秒兆比特数(Mbps)来表示(此处KM分别为10001000000,而不是涉及计算机存储器容量时的10241048576)


波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,其单位为波特(Baud)


 


 波特率与比特率的关系为:比特率=波特率X单个调制状态对应的二进制位数


 


两相调制(单个调制状态对应1个二进制位)的比特率等于波特率;


四相调制(单个调制状态对应2个二进制位)的比特率为波特率的两倍;


八相调制(单个调制状态对应3个二进制位)的比特率为波特率的三倍;


依次类推。


 


对于串行通信来说,或者说是对于普通的数字电路来说,都是两相调制(单个调制状态对应1个二进制位),因此波特率=比特率(通常叫波特率)。


 


PS:可以看看下面图就知道什么是四相调制。


 


点击看大图


 


如果系统时钟是1.8432MHz ,那16分频就得到115200Hz




reg [3:0] BaudDivCnt;
always @(posedge clk) BaudDivCnt <= BaudDivCnt + 1;

wire BaudTick = (BaudDivCnt==15);


      但通常系统的时钟不是刚刚好是波特率的整数倍,如果不采用DCM对系统进行倍频的话,可以采用下面程序进行处理,设系统时钟为2MHz=2000000Hz


2000000/115200=17.36111


1024/59= 17.356


2000000/115200≈1024/59


两个频率很接近,可以采用下面程序产生我们要的波特率。



// 10 bits for the accumulator ([9:0]), and one extra bit for the accumulator carry-out ([10])
reg [10:0] acc;          // 11 bits total!

always @(posedge clk)
  acc <= acc[9:0] + 59;


 // use only 10 bits from the previous result, but save the full 11 bits

wire BaudTick = acc[10]; // so that the 11th bit is the carry-out


当系统时钟为2MHz的时候,计算得到的波特率的值为115234,与115200只有0.03%的误差。


我们怎么得到“59”呢,可以看下面的推导


 


12b44a00-4622-4eb0-b0a1-241437d54865.jpg


 

其中Baud<<BaudGeneratorAccWidthBaud左移BaudGeneratorAccWidth位,相当于Baud乘以2BaudGeneratorAccWidth次方。


参照上面的程序与公式推导可以把程序修改如下:



parameter ClkFrequency = 25000000; // 25MHz
parameter Baud = 115200;
parameter BaudGeneratorAccWidth = 16;
parameter BaudGeneratorInc = (Baud<<BaudGeneratorAccWidth)/ClkFrequency;

reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc;
always @(posedge clk)
  BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc;

wire BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth];


 


当要注意的是,上面程序中BaudGeneratorInc的计算公式出错,因为在Verilog语言中中间结果只能32位,而这个公式计算的结果超过了32位。所以要把这行改为



parameter BaudGeneratorInc = ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4);


 


 


9468204e-7540-4808-8787-5cfb06544979.jpg


 

     程序改变,得到的波特率不变。


 


RS232发送接收模块


     可以参考下面文档,这里就不贴出来了。


http://attach.baisi.net/getattach.php?a=RS-232%B7%A2%CB%CD%C4%A3%BF%E9.rar&b=forumid_218%2F20080615_0eac2a17adb0faa0cae54LXO9jwRbJpE.rar&c=application%2Foctet-stream


 


RS232发送模块(Verilog


RS232接收模块(Verilog


以上程序均标注了J


 


调用串口发送接收模块


`timescale 1ns / 1ps


 


module serialfun(clk, RxD, TxD);


input clk;      //系统时钟


 


input RxD;


output TxD;


 


//////////////////////////////////////////////////


wire RxD_data_ready;


wire [7:0] RxD_data;


 


async_receiver deserializer(                 //RS-232接收模块


                         .clk(clk),


                                                 .RxD(RxD),


                                                 .RxD_data_ready(RxD_data_ready),


//当接收到一个字节的数据时,"RxD_data_ready"有效一个周期


                                                 .RxD_data(RxD_data)    //接收一个字节数据


                                                 );


 


///////////////////////////////////////////////////


async_transmitter serializer(                //RS-232发送模块


                         .clk(clk),


                                                 .TxD(TxD),


                                                 .TxD_start(RxD_data_ready),    


//"TxD_start"置位后开始传输


                                                 .TxD_data(RxD_data)   //发送一个字节数据


                                                 );


 


endmodule


 


这个程序的结果是在从计算机发送八个字节到FPGAFPGA再把这八个字节转发回计算机。


要注意是如果以十六进制发送的话,就要以十六进制显示,8个字节可以发送2个字符(0~F)。如果没选以十六进制发送的话,会以ASCII码发送,只能发送一个字符(一个字符的ASCII8个字节)。


 



   47668324-5e04-4660-af66-fdf483d2d31a.jpg


 


点击看大图


 


    Spartan3E Starter Kit开发板上有两个串口,所以设置管脚时要注意选择哪个串口,选择母头的话(DCE)与计算机相连的串口线选择交叉的公母线;选择公头的话(DTE),与计算机相连的串口线选择交叉的母母线


我选择了公头,UCF文件如下(约束管脚)


 


NET "clk"  LOC = "C9" | IOSTANDARD = LVCMOS33 ;


NET "RxD"  LOC = "U8" | IOSTANDARD = LVTTL ;


NET "TxD"  LOC = "M13" | IOSTANDARD = LVTTL  | DRIVE = 8  | SLEW = SLOW ;


 


本文Xilinx ISE工程文件(在Spartan3E Starter Kit开发板上实现)https://static.assets-stash.eet-china.com/album/old-resources/2009/4/13/e7f39ea3-8253-44a6-89e0-dde5f8a51986.rar


 


参考资料:


1)     什么是波特率,比特率,调制速率?


http://blog.ednchina.com/htcx8568/94374/message.aspx


2) Serial interface (RS-232)


 http://www.fpga4fun.com/SerialInterface.html  

文章评论7条评论)

登录后参与讨论

用户377235 2016-2-4 15:22

1024是指什麼??

coyoo 2014-4-8 20:20

没错,当然不同的fpga对应不同的sof文件

用户1739054 2014-4-8 14:41

单链多FPGA(fpga不同类型)的.pof文件也是上述流程吗?

coyoo 2014-2-27 11:58

JTAG调试(或下载)本质上和ce以及nceo信号没有关系;这里的多片FPGA组成菊花链,ce和ceo会影响FPGA配置状态,所以在使用jtag调试其中一片FPGA的时候需要将整个链路上的FPGA都配置好。

用户1738735 2014-2-26 21:10

博主,您好,我觉得提问人的意思和我想问的意思是一样的,如果我一块板子上4片FPGA已用AS连接方式将nCEOK连到了nCE上,但是在JTAG时,我只能保证第一片FPGA的nCE为低电平,剩余的连到nCEO的nCE信号,在JTAG调试时也是自动跳低电平了吗?

用户1650420 2013-11-23 13:22

写的好,赞一个

用户1645455 2013-10-9 12:43

谢谢

coyoo 2013-1-11 13:14

1、如果你所说的调试是通过JTAG进行调试,那么当你调试第三片FPGA的时候其余FPGA都必须“下载程序”,这里打上引号是因为其他FPGA可以下载任意程序,其唯一目的就是为了让链上的Config_done释放,这样链路才能跳出加载状态进入用户状态,你才能进行所谓的调试。 2、你所说的硬件电路中ALTERA的任意一款支持AS模式下载模式的器件手册里都有;注意JTAG的下载优先级最高,所以你的所谓”nCE在JTAG调试时为低”根本没有必要担心。也就是你用JTAG调试的时候jtag已经掌握了主控权。调试完毕更新程序,重新上电即可。

用户310504 2013-1-11 10:46

博主你好,我想问你两个问题 1、在JTAG链上,比如我的JTAG链上有四个FPGA芯片,现在我只想调试第3个,怎么样旁路其它3个FPGA呢? 2、上电EPCS加载的时候应该是nCEO串联nCE的吧,但是JTAG调试的时候nCE必须为低,这部分硬件电路是这么设计的呢? 谢谢。

用户284249 2010-10-22 13:50

好啊
相关推荐阅读
藤井树 2015-10-12 14:43
印制电路板的抗干扰设计 zz
印制电路板的抗干扰设计     作者:中船重工集团第707所 肖麟芬   摘   要:本文以印制电路板的电磁兼容性为核心,分析了电磁干扰的产生机理...
藤井树 2013-10-22 15:32
2010.5.30 黄草梁上包饺子一日登山活动——摘韭菜篇
        上次桃花节的时候也有野韭菜,那时候的我连草和韭菜叶分不清,才回去的韭菜也不敢吃,哈哈,这次可算真正见识了韭菜,黄草梁也叫韭菜梁,因为满山遍野都是野韭菜而闻名,比较圆比较粗的就是野韭...
藤井树 2013-10-22 15:28
2010.5.30 黄草梁上包饺子一日登山活动——包饺子篇
摘韭菜回来,大家已经忙开了 我也装模作样地“工作着” 哈哈,还不让我包,包饺子是技术活,一定要皮薄馅厚才有资格包,像我这样的只能旁观了 摘的韭菜应该足够了,旁边那个袋子是我摘来带回学校的 ...
藤井树 2013-08-09 15:19
datasheet下载网站整理(查IC芯片手册)【原创】
*************************************************************************         作为电子工程师,芯片的dat...
藤井树 2010-06-04 00:21
陈伟宁王辉一家捐助渠道(北京菲亚特—英菲尼迪)
       王辉的最新消息请关注 http://chenweining.org/       目前事故责任认定已经出来了——陈家全责。        发信人: program (程序), 信区: D...
藤井树 2010-06-01 13:43
2010.5.30 黄草梁上包饺子一日登山活动——美景篇
这天不得不说的是天空,蓝蓝的天空,白白的云    绿油油的山脊  我、洪涛哥哥、huangna妹妹还有她同事小艾走在黄草梁上    在蓝天白云下合影       阳光照过来,景色真美 象鼻山,走不...
我要评论
7
9
关闭 站长推荐上一条 /2 下一条