《基于FPGA的串口通信设计与实现》由会员分享,可在线阅读,更多相关《基于FPGA的串口通信设计与实现(13页珍藏版)》请在金锄头文库上搜索。
1、基于 FPGA的 UART设计与实现0引言通用异步收发器(Universal Asynchronous ReceiverTransmitter,UART)可以和各种标准串行接口,如 RS 232和 RS 485等进行全双工异步通信,具有传输距离远、成本低、可靠性高等优点。一般 UART由专用芯片如 8250,16450 来实现,但专用芯片引脚都较多,内含许多辅助功能,在实际使用时往往只需要用到 UART的基本功能,使用专用芯片会造成资源浪费和成本提高。一般而言 UART和外界通信只需要两条信号线 RXD和 TXD,其中 RXD是 UART的接收端,TXD 是 UART的发送端,接收与发送是全双
2、工形式。由于可编程逻辑器件技术的快速发展,FPGA 的功能日益强大,其开发周期短、可重复编程的优点也越来越明显,在 FPGA芯片上集成 UART功能模块并和其他模块组合可以很方便地实现一个能与其他设备进行串行通信的片上系统。FPGA(Field Programmable Gate Array)现场可编程门阵列在数字电路的设计中已经被广泛使用。这种设计方式可以将以前需要多块集成芯片的电路设计到一块大模块可编程逻辑器件中,大大减少了电路板的尺寸,增强了系统的可靠性和设计的灵活性。1 UART 功能设计1.1 UART的工作原理异步通信时,UART 发送接收数据的传输格式表 1所示,一个字符单位由开
3、始位、数据位、停止位组成。表 1 UART发送接收数据的传输格式START D0 D1 D2 D3 D4 D5 D6 D7 P STOP起始位 数 据 位 较验位 停止位异步通信的一帧传输经历以下步骤:(1)无传输。发送方连续发送信号,处于信息“1”状态。(2)起始传输。发送方在任何时刻将传号变成空号,即“1”跳变到“O”,并持续 1位时间表明发送方开始传输数据。而同时,接收方收到空号后,开始与发送方同步,并期望收到随后的数据。(3)奇偶传输。数据传输之后是可供选择的奇偶位发送或接收。(4)停止传输。最后是发送或接收的停止位,其状态恒为“1”。发送或接收一个完整的字节信息,首先是一个作为起始位
4、的逻辑“0”位,接着是 8个数据位,然后是停止位逻辑“1”位,数据线空闲时为高或“1”状态。起始位和停止位的作用是使接收器能把局部时钟与每个新开始接收的字符再同步。异步通信没有可参照的时钟信号,发送器可以随时发送数据,任何时刻串行数据到来时,接收器必须准确地发现起始位下降沿的出现时间,从而正确采样数据。设计时可参考由专用芯片实现的 UART的功能并进行一定精简,如可以用FPGA的片内 RAM替代 UART的 FIFO,不用单独在 UART模块中实现。设计的基本原则是保留最主要的功能,基于 FPGA的 UART系统波特率时钟发生器、接收器和发送器 3个子模块组成,如图 1所示。数据寄存器 移位寄
5、存器控制逻辑数据寄存器 移位寄存器控制逻辑接收器波特率时钟发生器发送器R X DT X D数据 I / O 缓存器图 1 基于 FPGA的 UART组成模块1.2 接收器设计 接收器的工作过程如下,如图 2所示,在接收数据寄存器被读出一帧数据或系统开始工作以后,接收进程被启动。接收进程启动之后,检测起始位,检测到有效起始位后,以约定波特率的时钟开始接收数据,根据数据位数的约定,计数器统计接收位数。一帧数据接收完毕之后,如果使用了奇偶校验,则检测校验位,如无误则接收停止位。停止位接收完毕后,将接收数据转存到数据寄存器中。图 2 数据接收图为确保接收器可靠工作,在接收端开始接收数据位之前,处于搜索
6、状态,这时接收端以 16倍波特率的速率读取线路状态,检测线路上出现低电平的时刻。因为异步传输的特点是以起始位为基准同步的。然而,通信线上的噪音也极有可能使传号“1”跳变到空号“0”。所以接收器以 16倍的波特率对这种跳变进行检测,直至在连续 8个接收时钟以后采样值仍然是低电平,才认为是一个真正的起始位,而不是噪音引起的,其中若有一次采样得到的为高电平则认为起始信号无效,返回初始状态重新等待起始信号的到来。找到起始位以后,就开始接收数据,最可靠的接收应该是接收时钟的出现时刻正好对着数据位的中央。由于在起始位检测时,已使时钟对准了位中央,用 16倍波特率的时钟作为接收时钟,就是为了确保在位宽的中心
7、时间对接收的位序列进行可靠采样,当采样计数器计数结束后所有数据位都已经输入完成。最后对停止位的高电平进行检测,若正确检测到高电平,说明本帧的各位正确接收完毕,将数据转存到数据寄存器中,否则出错。采用有限状态机模型可以更清晰明确地描述接收器的功能,便于代码实现。接收器的状态转换图如图 3所示,为突出主要过程,图中省略了奇偶校验的情况。接收器状态机由 5个工作状态组成,分别是空闲状态、起始位确认、采样数据位、停止位确认和数据正确,触发状态转换的事件和在各个状态执行的动作见图中的文字说明。空阻状态起始位确认采样数据位数据正确停止位确认未检测到起始位检测到起始位虚假起始位起始位正确采样计数器计数结束停
8、止位有效停止位错误丢弃数据数据装入数据寄存器图 3 接收器状态转换图根据状态图其主要的程序如下所示:else if( RX_En_Sig )case ( i )4d0 :if( H2L_Sig ) begin i = i + 1b1; isCount = 1b1; end 4d1 : if( BPS_CLK ) begin i = i + 1b1; end4d2, 4d3, 4d4, 4d5, 4d6, 4d7, 4d8, 4d9 :if( BPS_CLK ) begin i = i + 1b1; rData i - 2 = RX_Pin_In; end4d10 :if( BPS_CLK )
9、begin i = i + 1b1; end4d11 :if( BPS_CLK ) begin i = i + 1b1; end4d12 :begin i = i + 1b1; isDone = 1b1; isCount = 1b0; end4d13 :begin i = 4d0; isDone = 1b0; endendcase其中起始位检测正确会触发 RX_En_Sig,一次的定时采集时第 0 、1 位数据(起始位) ,保持忽略态度。定时采集的是八位数据位,每一位数据位会依低位到最高位储存入 rData寄存器。此时程序前两位省略取 2-9位就是传送的数据1.3波特率发生器设计波特率发生器实
10、质是设计一个分频器,用于产生和 RS 232通信同步的时钟。在系统中用一个计数器来完成这个功能,分频系数 N决定了波特率的数值。该计数器一般工作在一个频率较高的系统时钟下,当计数到 N2 时将输出置为高电平,再计数到 N2 的数值后将输出置为低电平,如此反复即可得到占空比50的波特率时钟,具体的波特率依赖于所使用的系统时钟频率和 N的大小。如系统时钟频率是 50 MHz,要求波特率是 9600,N=1/50MHz=5208,如果从零开始算起就是 5207个计数。然而,采集数据要求“在周期的中间”,那么结果是5208/2,结果等于 2604。基本上 rx_bps_module.v只有在 Coun
11、t_Sig拉高的时候,模块才开始计数。利用 verlog 所写的具体代码如下:module rx_bps_module(CLK, RSTn,Count_Sig, BPS_CLK);input CLK;input RSTn;input Count_Sig;output BPS_CLK;/*/reg 12:0Count_BPS;always ( posedge CLK or negedge RSTn )if( !RSTn )Count_BPS = 13d0;else if( Count_BPS = 13d5207 )Count_BPS = 13d0;else if( Count_Sig )Coun
12、t_BPS = Count_BPS + 1b1;elseCount_BPS = 13d0;/*/assign BPS_CLK = ( Count_BPS = 12d2604 ) ? 1b1 : 1b0;/*/endmodule1.4发送器设计图 4发送数据原理图当发送数据时,对于每一个数据的发送,每一位采用的是定时发送。假设,配置的波特率是 9600bps,那么当有一个发送标志位时,数据将会以1/9600 的节拍将数据一位一位的发送出去。一帧数据有 11位,需要 12次定时。主要代码为:always ( posedge CLK or negedge RSTn ) if( !RSTn )begi
13、ni = 4d0;rTX = 1b1;isDone = 1b0;endelse if( TX_En_Sig )case ( i )4d0 :if( BPS_CLK ) begin i = i + 1b1; rTX = 1b0; end4d1, 4d2, 4d3, 4d4, 4d5, 4d6, 4d7, 4d8 :if( BPS_CLK ) begin i = i + 1b1; rTX = TX_Data i - 1 ; end4d9 :if( BPS_CLK ) begin i = i + 1b1; rTX = 1b1; end4d10 :if( BPS_CLK ) begin i = i +
14、 1b1; rTX = 1b1; end4d11 :if( BPS_CLK ) begin i = i + 1b1; isDone = 1b1; end4d12 :begin i = 4d0; isDone = 1b0; endendcase2 数据传输仿真Modelsim仿真工具是 Model公司开发的。它支持 Verilog、VHDL 以及他们的混合仿真,它可以将整个程序分步执行,使设计者直接看到他的程序下一步要执行的语句,而且在程序执行的任何步骤任何时刻都可以查看任意变量的当前值,可以在 Dataflow窗口查看某一单元或模块的输入输出的连续变化等,比quartus自带的仿真器功能强大的
15、多,是目前业界最通用的仿真器之一。2.1仿真串口发送模块编写一个仿真激励程序用于单独仿真串口发送模块。步骤 0的时候,将数据 8h2E 发送至串口发送模块后使能串口发送模块,然后等待串口发送模块反馈完成信号。同样的动作也有 . 步骤 1是发送数据 8h3f, 然而步骤 2是发送数据 8hdd。步骤 3是停止动作图 5 发送数据仿真放大第二个数据 0x3f的发送过程,如下图所示。可以看出串口发送模块,发送数据的格式是一帧 11 位。0开始位-逻辑 0,1:8数据位,9校验位没有需要可以随便填,这里填逻辑 1,10停止位逻辑 1。图 6 发送过程仿真结果图 7 发送数据的延时仿真串口发送模块配置的波特率是 9600kbps ,所以一个数据逗留的时间是大约 104us。在仿真结果中,在 B0B1 是数据0, B1B2 是数据1 . B10B11 是数据10。BxBx 之间的时间大约是 104us。2.2仿真串口接收模块用串口发送模块作为串口接收模块的刺激,亦即串口接收模块的输入(复杂输入) 。用串口发送模块作为串口接收模块的刺激,亦即串口接收模块的输入(复杂输入) 。下图是仿真虚拟环境 env_rx_module.v 它组合了串口发送模块和串口接收模块。