特权同学

Nexys3学习手记8:FT232之高速UART

0
阅读(8015)

Nexys3学习手记8:FT232之高速UART

继续上一节的工程,这里要接着在XPS上扩展一个UART外设,配合板载的USB2UART芯片FT232R做个高速串口传输测试。

首先打开上一个ISE工程,然后双击顶层模块下的mycpu模块即可开启硬件开发平台XPS,如图1所示。

图1 点击进入XPS

传说中XPS上提供了两个AXI总线对应的UART外设IP核,如图2所示,即UART 16550-style和UART-Lite。本节要添加的名为UART-Lite的外设,故名思意便是精简的小身板UART外设,几番接触下来,果然如此,对于复杂的UART使用这个Lite版还确实难堪大任,不过对于我们的实验学习还是多多益善,简单才容易玩转嘛,哈哈。

图2 UART外设

双击图2的AXI UART(Lite)选项,弹出配置页面如图3所示,明白人一眼就知道,这里可设置其波特率、传输数据位和校验位等。除此以外,基本没有可以设置的选择项了,Lite就Lite在此,硬件中必须一次性设置好固定的UART传输模式,软件无法灵活的编程更改。不过据说这个UART-Lite是开源的,感兴趣朋友不妨去研究一下,把这个Lite改造得很强大也是个很不错的活儿。

图3 UART-Lite外设配置页面

点击图3右上角的pdf小图标便可查看此外设的说明文档axi_uartlite_ds741.pdf。如图4所示,UART-Lite的功能框图中示意改外设包含了4个最基本的软件可访问的寄存器,即数据接收寄存器(Receive Data FIFO)、数据发送寄存器(Transmit Data FIFO)、状态寄存器(Status Register)和控制寄存器(Control Register)。

图4 UART-Lite功能框图

在完成UART-Lite的配置后,点击OK,便会弹出如图5所示的串口。采用默认设置,意为UART-Lite外设的AXI总线接口能够自动和系统的MicroBlaze处理器上的片内AXI总线接口相匹配。

图5 例化和连接IP核

添加好新的外设组件,需要重新点击XPS的菜单HardwareàGenerate Netlist生成新的网表。新的Netlist成功生成后,回到ISE查看mycpu.xmp下对应的View HDL Instantiation Template,此时相比原来的工程多了两个信号接口axi_uartlite_0_RX_pin和axi_uartlite_0_TX_pin,即UART-Lite的收发信号。

图6 系统例化模板

重新编辑并例化顶层文件,修改后的顶层代码如下:

module testled(

clk,rst_n,

led,

uart_rx,uart_tx

);

input clk; //100MHz

input rst_n; //低电平复位信号

output[7:0] led; //连接到LED指示灯

input uart_rx; //UART数据接收

output uart_tx;//UART数据发送

wire clk_100m; //clocking输出100MHz

wire clk_50m; //clocking输出50MHz

wire clk_25m; //clocking输出25MHz

wire clk_12m5; //clocking输出12.5MHz

wire clk_locked; //clocking输出完成标志位

//---------------------------------------------------

//IP核Clocking Wizard例化

//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG

myclocking uut_myclocking

(// Clock in ports

.CLK_IN1(clk), // IN

// Clock out ports

.CLK_OUT1(clk_100m), // OUT

.CLK_OUT2(clk_50m), // OUT

.CLK_OUT3(clk_25m), // OUT

.CLK_OUT4(clk_12m5), // OUT

// Status and control signals

.RESET(!rst_n),// IN

.LOCKED(clk_locked)); // OUT

// INST_TAG_END ------ End INSTANTIATION Template ---------

//---------------------------------------------------

// 例化mysoc系统

(* BOX_TYPE = "user_black_box" *)

mysoc uut_mysoc (

.RESET(rst_n),

.LEDS_TRI_O(led),

.clock_generator_0_CLKIN_pin(clk_100m),

.axi_uartlite_0_RX_pin(uart_rx),

.axi_uartlite_0_TX_pin(uart_tx)

);

endmodule

对顶层新添加的两个信号接口进行管脚分配,将以下两条语句添加到testled.ucf中即可:

NET "uart_rx" LOC = N17;

NET "uart_tx" LOC = N18;

最后重新编译整个ISE工程并生成.bit下载文件。接下来要看软件的了,打开SDK并定位Workspace到本实例工程的SDK_workspace目录下。我们点击mysoc_hw_platform目录下的system.xml,此时发现并没有出现axi_uartlite_0这个新外设,说明目前的软件工程并没有实时的更新当前硬件工程的信息。

图7 查看system.xml

显然,目前情况下我们无法在软件中编程控制UART外设,必须先更新系统的硬件信息。在mysoc_hw_platform文件夹上右击并选择Change Hardware Platform Specification。如图8所示,将system.xml重新定位到当前工程路径下(当前工程文件夹\mysoc\__xps\system.xml)。

图8 定位system.xml

如图9所示,重新匹配后的system.xml文件中出现了当前实例新添加的axi_uartlite_0外设。

图9 查看新的system.xml

编写软件测试代码,实现查询方式(中断方式特权同学还没有搞明白,有点越弄越糊涂,以后再慢慢研究)串口数据接收,然后对接收数据取反后发送。

/* ------------------------------------------------------------ */

/* Include File Definitions */

/* ------------------------------------------------------------ */

#include

#include "xparameters.h" //The hardware configuration describing constants

#include "xgpio_l.h" //This header file contains identifiers and driver functions

#include "xil_io.h"//Contains the Xil_Out32 and Xil_In32 functions

#include "xuartlite_l.h" //

#define uchar unsigned char

#define uint unsigned short

/* ------------------------------------------------------------ */

/* main function */

/* ------------------------------------------------------------ */

int main()

{

uchar rxdb;

XUartLite_SetControlReg(XPAR_UARTLITE_0_BASEADDR,0x10);//enable interrupt

while(1)

{

if(!XUartLite_IsReceiveEmpty(XPAR_UARTLITE_0_BASEADDR))

{

rxdb = XUartLite_RecvByte(XPAR_UARTLITE_0_BASEADDR);//XUartLite_ReadReg(XPAR_UARTLITE_0_BASEADDR,0);

XUartLite_SendByte(XPAR_UARTLITE_0_BASEADDR,~rxdb);

}

}

return 0;

}

编译工程,然后参照上一节将代码烧录Nexys3中。注意此时需要两条Mini-B连接线和PC互连,一条用于连接PC与J3,即上一节提到的下载通路;另一条则用于连接PC与J13,也就是UART-Lite外设的通路。或者将JP1的跳线帽改接2-3PIN,J10连接一个5V直流电源,然后就不停的将唯一的一条Mini-B连接线在J3和J13之间来回晃荡吧,就像特权同学一样(不过这样来回热拔插不知是否会对芯片产生不良影响,尽管USB本身是支持热拔插的)。

FT232芯片是个USB转UART芯片,一端用于接USB,另一端能够接UART进行通信。所谓的USB端,物理特性上来说,肯定是真USB,直接可以连接PC的USB端口。从协议层面看,当然它也确实能够实现USB协议的数据传输,不过更简单方便的方法是用UART协议来传输数据,此时它就是个实实在在的“伪USB”——借USB跑UART。这个看似神奇的芯片也没神马特殊之处,接上PC后,若是不提示安装驱动(若是需要驱动,则可以到FTDI公司官方网站下载:http://www.ftdichip.com/Products/ICs/FT232R.htm),则默认就出现在了设备管理器的端口下,如图10所示的“USB Serial Port(COM3)”,记住这个COM3,后面用调试助手收发数据时别选错端口。

图10 设备管理器的新串口

如图11所示,设置串口调试助手端口为COM3、波特率9600、数据位8、无校验位,进行通信,则发送55AA返回AA55。

图11 串口数据收发

FT232芯片既然用USB来传UART,一定要有点过人之处才有存在的理由。当然,一方面这个芯片会解决很多新的PC没有RS232串口的尴尬,而老串口的波特率最高通常不会超过115200bps,那么这个FT232就要来挑战一下,因此特权同学也特地进行了高速传输的测试,标称最高的921600bps,折腾老半天发现不干活,这下毛了,最后特权同学干脆来个只发不收的软件测试,发现原本为AA的发送数据在PC端却变成了CA或者DA。一推理,可能外设波特率有误差,于是放低波特率到460800bps,OK了,进一步确认波特率的误差问题。由于UART-Lite外设的时钟由CPU时钟分频得到,而CPU此次波特率为50MHz,对于921600bps这种非整数倍的值进行分频肯定存在误差。以此简单的将CPU时钟调高到100MHz,问题解决了。其实这个解决办法没有本质上解决波特率误差问题,若是严谨一些,恐怕需要调算好一个961600bps整数倍的频率作为外设时钟会更合适一些,总之呢,具体问题要具体分析。事实证明这个高速UART还是靠谱的,今后就不愁UART上不了115200bps了。

Baidu
map