QuietE

AlteraDE2试用之串口篇

0
阅读(4188)

串口算是我们认识硬件最早接触的接口了,这里我们指的是异步串行UART接口。一般mcu都会有这个uart资源。像stc的单片机是通过这个接口来下载程序,arm的芯片一般也支持串口下载。而通过FPGA实现uart通信只需要任意两个IO即可。当然,这里指的是三线接法,也即TX\RX\GND三根线,而不是全功能串口。

开发板上也支持串口通信,同样也是三线接法。clip_image002

这里,通过max232做TTL电平和RS232电平之间的转换,以实现远距离通信。这里不讨论232的具体实现,只是说一下串口逻辑。下面这张图是uart数据传输的格式clip_image004

Uart是全双工的,所以在测试串口是否有问题的时候可以直接将收发的两个接口短接,看数据有没有环回。

Uart是异步串行接口,没有同步时钟线,所以这里有一个波特率的概念,就是每秒发送的数据位数,这个很关键,在uart传输之前需要先约定波特率,这样才能正确的收发数据。

一般来说,常用的串口波特率为9600、19200、115200等,至于为什么是这些速率,跟最初的时钟有关,这些速率是通过时钟分频得来的,做2的整数倍分频最容易。

这里,我们要通过fpga来实现波特率时钟的生成。一般来说,我们可以采用最简单直接的分频方式,直接分频,比如我的主时钟是50Mhz,我的串口时钟是9600hz,那么,我的分频因数可以直接是50mhz/9600hz,如果这个数是一个整数,自然没有问题。但通常我们使用的主时钟和串口时钟不是整数倍的关系,会得到一个近似的分频因数,这样就会造成波特率误差。

从这个计算式中可以看出,在较低的传输速率或者主时钟较高时这个误差比较小,比如在50mhz和9600bps的状况下,就可以直接使用,能够正常通信。并且误差只会在传输一个字节上累计,下一个起始位相当去重新定位了。

这里要分享的是在串口时钟设计中常用的一个方法,计数分频。类似于直接频率合成的原理。相当于描点。DDS的原理如下:clip_image006

同样的我们可以利用这个原理生成串口时钟:注意下面的代码将串口时钟扩大两倍,以便正确采样

parameter CLK_FREQ = 50000000

parameter Clk_Freq_Division = (CLK_FREQ >> 1);// parameter Baud = 19200; //???

parameter BaudGeneAccWidth = 16;

reg [BaudGeneAccWidth:0] BaudGeneAcc;

wire [BaudGeneAccWidth:0] BaudGeneInc = ((Baud<<(BaudGeneAccWidth-4))+(Clk_Freq_Division>>5))/(Clk_Freq_Division>>4);/

wire BaudTick = BaudGeneAcc[BaudGeneAccWidth];

always @(posedge clk)

BaudGeneAcc <= BaudGeneAcc[BaudGeneAccWidth-1:0] + BaudGeneInc;