1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-301505-1-1.html 4)对正点原子FPGA感兴趣的同学可以加群讨论:994244016 5)关注正点原子公众号,获取最新资料更新
串口是“串行接口”的简称,即采用串行通信方式的接口。串行通信将数据字节分成一位一位的形式在一条数据线上逐个传送,其特点是通信线路简单,但传输速度较慢。因此串口广泛应用于嵌入式、工业控制等领域中对数据传输速度要求不高的场合。本章我们将使用ZYNQ开发板上的UART串口完成上位机与ZYNQ PL的通信。 本章包括以下几个部分: 1.1 UART串口简介 1.2 实验任务 1.3 硬件设计 1.4 程序设计 1.5 下载验证 1.1 UART串口简介 串行通信分为两种方式:同步串行通信和异步串行通信。同步串行通信需要通信双方在同一时钟的控制下,同步传输数据;异步串行通信是指通信双方使用各自的时钟控制数据的发送和接收过程。 UART是一种采用异步串行通信方式的通用异步收发传输器(universal asynchronous receiver-transmitter),它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。 UART串口通信需要两根信号线来实现,一根用于串口发送,另外一根负责串口接收。UART在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、奇偶校验位和停止位,如图 7.5.13.1所示。其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。校验位分为奇校验和偶校验,用于检验数据在传输过程中是否出错。奇校验时,发送方应使数据位中1的个数与校验位中1的个数之和为奇数;接收方在接收数据时,对1的个数进行检查,若不为奇数,则说明数据在传输过程中出了差错。同样,偶校验则检查1的个数是否为偶数。
图 7.5.13.1 异步串行通信数据格式 UART通信过程中的数据格式及传输速率是可设置的,为了正确的通信,收发双方应约定并遵循同样的设置。数据位可选择为5、6、7、8位,其中8位数据位是最常用的,在实际应用中一般都选择8位数据位;校验位可选择奇校验、偶校验或者无校验位;停止位可选择1位(默认),1.5或2位。串口通信的速率用波特率表示,它表示每秒传输二进制数据的位数,单位是bps(位/秒),常用的波特率有9600、19200、38400、57600以及115200等。 在设置好数据格式及传输速率之后,UART负责完成数据的串并转换,而信号的传输则由外部驱动电路实现。电信号的传输过程有着不同的电平标准和接口规范,针对异步串行通信的接口标准有RS232、RS422、RS485等,它们定义了接口不同的电气特性,如RS-232是单端输入输出,而RS-422/485为差分输入输出等。 RS232接口标准出现较早,可实现全双工工作方式,即数据发送和接收可以同时进行。在传输距离较短时(不超过15m),RS232是串行通信最常用的接口标准,本章主要介绍针对RS-232标准的UART串口通信。 RS-232标准的串口最常见的接口类型为DB9,样式如图 7.5.13.2所示,工业控制领域中用到的工控机一般都配备多个串口,很多老式台式机也都配有串口。但是笔记本电脑以及较新一点的台式机都没有串口,它们一般通过USB转串口线(图 7.5.13.3)来实现与外部设备的串口通信。
图 7.5.13.2 DB9接口
图 7.5.13.3 USB串口线 DB9接口定义以及各引脚功能说明如图 7.5.13.4所示,我们一般只用到其中的2(RXD)、3(TXD)、5(GND)引脚,其他引脚在普通串口模式下一般不使用,如果大家想了解,可以自行百度下。
图 7.5.13.4 DB9接口定义 1.2 实验任务 本节实验任务是上位机通过串口调试助手发送数据给Zynq,Zynq PL端通过RS232串口接收数据并将接收到的数据发送给上位机,完成串口数据环回。 1.3 硬件设计 领航者ZYNQ开发板上RS232串口部分的原理图如下所示:
图 7.5.13.1 领航者RS232串口原理图 由于ZYNQ PL端串口输入输出引脚为TTL电平,用3.3V代表逻辑“1”,0V代表逻辑“0”;而计算机串口采用RS-232电平,它是负逻辑电平,即-15V-5V代表逻辑“1”,+5V+15V代表逻辑“0”。因此当计算机与ZYNQ通信时,需要加电平转换芯片SP3232,实现RS232电平与TTL电平的转换。 从图 7.5.13.1中可以看到,SP3232芯片端口的U2_RX和U2_TX并没有直接和ZYNQ的引脚相连接,而是连接到了P1排针上。RS232串口和RS485串口共用P1排针的UART2_TX和UART2_RX,而UART2_TX和UART2_RX是直接和ZYNQ的引脚相连接的。在使用时,使用跳线帽选择与ZYNQ相连接的串口类型,这样的设计方式实现了有限IO的复用。因此,在做RS232的通信实验时,需要使用杜邦线或者跳线帽将U2_RX和UART2_TX连接在一起,U2_TX和UART2_RX连接在一起。 本实验中,系统时钟、按键复位以及串口的接收、发送端口的管脚分配如下表所示: 表 16.3.1 串口通信实验管脚分配 信号名 方向 管脚 端口说明 电平标准
sys_clk input U18 系统时钟,50M LVCMOS33
sys_rst_n input N16 系统复位,低有效 LVCMOS33
uart_rxd input K14 串口接收 LVCMOS33
uart_txd output M15 串口发送 LVCMOS33
对应的XDC约束语句如下所示:
create_clock -period 20.000 -name clk [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
set_property -dict {PACKAGE_PIN K14 IOSTANDARD LVCMOS33} [get_ports uart_rxd]
set_property -dict {PACKAGE_PIN M15 IOSTANDARD LVCMOS33} [get_ports uart_txd]
1.4 程序设计 根据实验任务,我们不难想象本系统应该有一个串口接收模块,用来接收上位机发送的数据;还要有一个串口发送模块,用于将数据发回上位机;另外还应该有一个对数据进行环回控制的模块,它负责把从串口接收模块接收到的数据送给串口发送模块,以实现串口数据的环回。由此可以画出本次实验的系统框图,如下所示:
图 7.5.13.1 系统框图 由系统总体框图可知,ZYNQ PL部分包括四个模块,顶层模块、接收模块、发送模块和数据环回模块。其中在顶层模块中完成对另外三个模块的例化,顶层模块原理图如下所示:
图 7.5.13.2 顶层模块原理图 在图 7.5.13.2中,uart_recv为串口接收模块,从串口接收端口uart_rxd来接收上位机发送的串行数据,并在一帧数据接收结束后给出通知信号uart_done。 uart_send为串口发送模块,以uart_en为发送使能信号。uart_en的上升沿将启动一次串口发送过程,将uart_din接口上的数据通过串口发送端口uart_txd发送出去。 uart_loop模块负责完成串口数据的环回功能。它在uart_recv模块接收完成后,将接收到的串口数据发送到uart_send模块,并通过send_en接口给出一个上升沿,以启动发送过程。 在编写代码之前,我们首先要确定串口通信的数据格式及波特率。在这里我们选择串口比较常用的一种模式,数据位为8位,停止位为1位,无校验位,波特率为115200bps。则传输一帧数据的时序图如下图所示:
图 7.5.13.3 串口通信时序图 顶层模块的代码如下:
1 module uart_loopback_top(
2 input sys_clk, //外部50M时钟
3 input sys_rst_n, //外部复位信号,低有效
4
5 input uart_rxd, //UART接收端口
6 output uart_txd //UART发送端口
7 );
8
9 //parameter define
10 parameter CLK_FREQ = 50000000; //定义系统时钟频率
11 parameter UART_BPS = 115200; //定义串口波特率
12
13 //wire define
14 wire uart_recv_done; //UART接收完成
15 wire [7:0] uart_recv_data; //UART接收数据
16 wire uart_send_en; //UART发送使能
17 wire [7:0] uart_send_data; //UART发送数据
18 wire uart_tx_busy; //UART发送忙状态标志
19
20 //*****************************************************
21 //** main code
22 //*****************************************************
23
24 //串口接收模块
25 uart_recv #(
26 .CLK_FREQ (CLK_FREQ), //设置系统时钟频率
27 .UART_BPS (UART_BPS)) //设置串口接收波特率
28 u_uart_recv(
29 .sys_clk (sys_clk),
30 .sys_rst_n (sys_rst_n),
31
32 .uart_rxd (uart_rxd),
33 .uart_done (uart_recv_done),
34 .uart_data (uart_recv_data)
35 );
36
37 //串口发送模块
38 uart_send #(
39 .CLK_FREQ (CLK_FREQ), //设置系统时钟频率
40 .UART_BPS (UART_BPS)) //设置串口发送波特率
41 u_uart_send(
42 .sys_clk (sys_clk),
43 .sys_rst_n (sys_rst_n),
44
45 .uart_en (uart_send_en),
46 .uart_din (uart_send_data),
47 .uart_tx_busy (uart_tx_busy),
48 .uart_txd (uart_txd)
49 );
50
51 //串口环回模块
52 uart_loop u_uart_loop(
53 .sys_clk (sys_clk),
54 .sys_rst_n (sys_rst_n),
55
56 .recv_done (uart_recv_done), //接收一帧数据完成标志信号
57 .recv_data (uart_recv_data), //接收的数据
58
59 .tx_busy (uart_tx_busy), //发送忙状态标志
60 .send_en (uart_send_en), //发送使能信号
61 .send_data (uart_send_data) //待发送数据
62 );
63
64 endmodule
在顶层模块中完成了对其余各个子模块的例化。需要注意的是,顶层模块中第10、11行定义了两个变量:系统时钟频率CLK_FREQ与串口波特率UART_BPS,使用时可以根据不同的系统时钟频率以及所需要的串口波特率设置这两个变量。我们可以尝试将串口波特率UART_BPS设置为其他值(如9600),在模块例化时会将这个变量传递到串口接收与发送模块中,从而实现不同速率的串口通信。 串口接收模块的代码如下所示:
1 module uart_recv(
2 input sys_clk, //系统时钟
3 input sys_rst_n, //系统复位,低电平有效
4
5 input uart_rxd, //UART接收端口
6 output reg uart_done, //接收一帧数据完成标志
7 output reg [7:0] uart_data //接收的数据
8 );
9
10 //parameter define
11 parameter CLK_FREQ = 50000000; //系统时钟频率
12 parameter UART_BPS = 9600; //串口波特率
13 localparam BPS_CNT = CLK_FREQ/UART_BPS; //为得到指定波特率,
14 //需要对系统时钟计数BPS_CNT次
15 //reg define
16 reg uart_rxd_d0;
17 reg uart_rxd_d1;
18 reg [15:0] clk_cnt; //系统时钟计数器
19 reg [ 3:0] rx_cnt; //接收数据计数器
20 reg rx_flag; //接收过程标志信号
21 reg [ 7:0] rxdata; //接收数据寄存器
22
23 //wire define
24 wire start_flag;
25
26 //*****************************************************
27 //** main code
28 //*****************************************************
29 //捕获接收端口下降沿(起始位),得到一个时钟周期的脉冲信号
30 assign start_flag = uart_rxd_d1 & (~uart_rxd_d0);
31
32 //对UART接收端口的数据延迟两个时钟周期
33 always @(posedge sys_clk or negedge sys_rst_n) begin
34 if (!sys_rst_n) begin
35 uart_rxd_d0
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?