EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
大侠好,欢迎来到FPGA技术江湖。本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。 / c" X# p5 n- f, ~8 y! Y
系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。本次带来Vivado系列,UART驱动教程。话不多说,上货。
& i8 {) N/ `# |. m. r: j5 p
UART 驱动教程
1 j% z5 F/ x) d9 }) q) [
UART即通用异步收发器,是一种通用串行数据总线,用于异步通信。该总线为双向通信,可以实现数据的接收与发送。 # j5 D/ u8 g" Z( z4 J
在数据传输过程中,我们需要解释一下串行通信。假设现在我们传输数据的双方为A和B,每次传输8bit数据,这8bit的数据在传输时按照A与B之间的连线分为串行通信和并行通信。串行通信即A与B之间仅有一根数据线,在传输数据时需要一次发送1bit,总共发送8次。并行通信即A与B之间有8根线,传输数据时,将8bit数据通过8根线一起传输,这样一次就可以全部传输完成。
. A/ P! X8 c; `
数据传输时,接收方和发送方使用的时钟不是同一个时钟域,这也就是异步传输。 ; o$ G6 @& l, X, f0 n/ J
在通信双方传输数据之前,需要通过串口线进行连接,然后再传输数据,常用的串口线为DB9接口,但是由于这种接口体积大,不易携带等缺点而慢慢淘汰。我们在B04的开发板上使用到的是一个USB转串口的芯片,这样我们的MINI USB接口不仅可以给开发板供电,还可以进行串口数据传输。芯片为CP2102(USB <-->UART(LVCMOS/LVTTL)),对于开发者来说,就不需要关注电平标准了。 2 ?9 R2 }# w, _' c) F3 T+ h
芯片电路图如图所示: ; S/ d. b C- l' x4 h
8 W/ U. [: |0 Y, v3 U4 c
2 c1 |! i5 ?% H8 b
在电路图中我们可以发现,串口接口只有两根数据线,分别为RXD和TXD。那么在进行通信之前,我们需要先了解一下串口的传输规则。
) R8 D' T' U& N V( F. V
在发送者没有发送数据时,接收方如果一直接收数据,那就会导致数据出错,所以,接收方在接收数据时需要有标志信号,然后启动接收。在我们的串口协议中是这样规定的: ! j7 J6 q# y! |" d3 E: m
1、空闲态数据线上为高电平。 2、发送数据时,先发送起始位,逻辑电平为低。 3、起始位结束之后,发送8bit数据,从低位开始传输。 4、数据传输完毕,是1bit的校验位,采用奇偶校验法。(可不使用) 5、停止位,为高电平,可以是1bit、1.5bit或者2bit。
" H/ b/ y' R/ @$ m
那么我们清楚了数据传输规则之后,我们还需要明白一个内容,那就是1bit数据的时间长度。在算这个时间之前,我们需要了解一下波特率。波特率的单位是bit/s,也就是1秒时间内,传输的bit数。我们串口常用的波特率有9600、14400、19200等等。这个波特率是传输数据的双方,提前规定好的。那么在同一速度下传输数据,就会简单很多。那么根据波特率我们可以计算出来1bit数据的时长为104166ns。在清楚这些之后,接下来我们做一个回环测试。 首先我们先新建一个工程: ' L6 c. ?0 A( ?& r' Q" l
c v2 N/ U, B5 v* e+ N2 c
% \4 L$ D- l$ j- d8 Z& r
选好代码存放位置,修改工程名字为uart。 选择我们的芯片型号:XC7A35TFGG484-2。
; U8 \* K, d2 `/ `
; M# {$ Z& ~! F8 q1 H* [
( l5 P% `4 g! _5 n4 y
新建好工程后,开始新建文件写代码。
: ]9 K& ~ p0 J9 S1 g5 \
; f' H. u1 b5 L4 W2 l- `! e/ I' ]' s7 t3 e9 ]
3 F1 D8 s# I' ~" Y2 P
/ D4 ]- Z# n& y5 t* x/ a! D
( v+ E% ?( x; A* U9 _& a% u0 @9 t8 F1 k; ]/ X. Z
点击OK,顶层文件新建完成,后续各个模块新建方式相同。接收代码如下: 1 t1 S1 w' ^: g. T3 }4 b, b& `
6 t; d$ T/ R! b* Z E. q2 Q* K$ X. d l) d/ Q) f% t) P( |
发送数据时,跟接收基本类似,按照数据格式发送数据,代码如下:
4 @' W/ u7 {; E2 q5 J
' y. Z5 _. |( z+ N+ V \
& T! f. s0 U& L* J i+ w
其中读使能我们只需在数据发送前将数据读出即可。$ ^& N2 n1 O$ D! A) L
在做完两个模块之后,我们还需要使用一个FIFO来做数据缓存,FIFO配置参数如下: % L& t& F5 h l
% U* {" A, D( Z& O. D$ z* X+ m
4 z4 s8 k9 q6 b6 H
我们使用异步FIFO,深度选择2048,位宽为8,复位信号暂时不使用。
6 e# q; H' Z$ k- l6 G) D, Y* ]; v
% k9 m& e9 h5 o% b
3 E* N8 `$ `2 T# d9 m9 V7 ]
生成FIFO后,将各个模块例化到顶层当中,代码如下:
8 e" m X0 R7 S0 H9 v! A
5 B/ \/ \ M% A- E$ {
" G8 ^0 z7 h; n
功能部分写完之后,我们写一个仿真进行逻辑验证,写仿真时,我们按照数据顺序模拟给值,每1bit持续104166ns的时间。代码如下:
1 c4 t, G. [/ \, i/ l+ s
. c; T$ x9 Q2 I$ q' n
1 g. o7 s. _7 M3 i) O) ]
打开仿真波形:
) S& p. Z5 U* V+ B9 d" {; D
) }6 I% Y$ |( `2 \6 k
, n: o8 J) U/ B" ]7 V- S4 {) P8 d: n6 e, C
如图,我们可以看到,当我们的接收模块接收到数据时,会将数据写入FIFO,FIFO中有数据时,发送模块就会将数据读出并发送,仿真现象正确。 下板现象: $ N. d% i, W* V) m" _/ o) J
9 _5 J2 [/ L, b" T
3 }( J5 A+ c, I9 A' y. G7 S7 P E8 S7 H9 f& N) c
我们随便写入几个数据,会发现我们的发送模块和接收模块的数据完全一致,即接收和发送正常。 0 v8 {, T: |; s, ~5 R
|