前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

正点原子开拓者NiosII资料连载第二十七章GUI综合实验

qiguaw 2024-09-16 01:30:03 资源文章 20 ℃ 0 评论

1)实验平台:正点原子开拓者FPGA 开发板

2)摘自《开拓者 Nios II开发指南》关注官方微信号公众号,获取更多资料:正点原子

3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/index.html

第二十七章开拓者FPGA开发板GUI综合实验

本章将通过一个综合实例,向大家展示FPGA强大的并行处理能力以及与Nios II的协同处

理,并且可以测试开发板的大部分功能。该实验代码非常多,涉及uC/GUI、图像缩放处理、

音频播放、OV5640摄像头图像显示、手写画笔等非常多的内容,其中大部分功能在前面的实

验中都有实现过,故本章不对代码进行讲解,只介绍程序的设计思路与实现的功能。

本章包括以下几个部分:

27.1 开拓者开发板 GUI 综合实验简介

27.2 实验任务

27.3 硬件设计

27.4 软件设计

27.5 下载验证

开拓者开发板GUI综合实验简介

大家收到的开发板,默认固化的就是本次GUI综合测试实验的程序,开发板必须连接LCD

屏,才能显示UI界面以及测试开发板的外设,本次实验支持正点原子推出的所有的LCD屏。

开拓者FPGA开发板综合实验除上电自检外,总共有14大功能,分别是:按键测试、LED测

试、蜂鸣器、数码管、串口、红外遥控、EEPROM、环境光、RTC实时时钟、音乐播放、ADDA、

手写画笔、摄像头和网络通信。

按键测试:一个按键测试应用,可以测试板载的4个按键的好坏。

LED测试:一个LED测试应用,可以测试板载的4个LED的好坏。

蜂鸣器:一个蜂鸣器测试应用,可以测试蜂鸣器的好坏。

数码管:一个数码管测试应用,可以测试数码管的好坏。

串口:一个串口通信数据环回应用,通过串口助手完成和开发板的串口通信的功能。

红外遥控:一个红外遥控测试应用,可以测试板载的红外遥控的好坏。

EEPROM:向EEPROM中写入数据,写入完成后读出数据,通过比较写入的数据和读出的数

据是否一致,来判断EEPROM读写是否正确。

环境光:一个环境光传感器测试应用,读出并显示环境光传感器的光强度和距离值。

RTC实时时钟:一个RTC实时时钟测试应用,读出并显示当前的日期与时间。

音乐播放:音频信号从板载的LINE_IN接口输入,通过喇叭和PHONE接口(连接耳机)进

行播放,可以测试板载的音频芯片和喇叭的好坏。

ADDA:一个ADDA测试应用,通过DA和AD转换,测试板载ADDA的好坏。

手写画笔:在LCD屏上留下触摸后的轨迹,可以用来绘画和写字。

摄像头:通过连接OV5640摄像头,进行视频图像的实时显示。

网络通信:通过以太网的SMI接口(Serial Management Interface,串行管理接口),

读取当前网口和其它网络设备的连接状态。

以上是综合实验的14个功能简介,其中大部分功能在前面的实验中都有实现过,如果大

家有不明白的地方,可以参考前面的内容。在简介部分中,我们仅介绍新增的Qsys IP核和接

口,即缩放IP核(Scaler II – Edge Adaptive)和SMI接口。

缩放IP核(Scaler II – Edge Adaptive)

缩放IP核是Qsys系统提供的用于视频图像处理的IP核,该IP核支持输入视频流分辨率到

输出视频流分辨率的放大和缩小。我们知道,不同尺寸的LCD屏,它们的分辨率是不同的,即

使是相同尺寸的LCD屏,分辨率也可能不同,为了使综合实验能够兼容不同分辨率的LCD屏,

我们在综合实验中,添加了缩放IP核,便于兼容不同分辨率的LCD屏。

缩放IP核可选的算法有临近算法、双线性算法、双三次算法、多项式算法和边缘自适应

算法。临近算法相比于其它几种算法,其缩放效果较差,但是消耗的逻辑资源是最少的;而

其它几种算法虽然缩放效果更好,但是所消耗的逻辑资源也是相对较多的。考虑到综合实验

驱动的外设比较多,功能复杂,并且开拓者FPGA开发板上的逻辑资源有限,因此本次实验使

用的缩放算法是逻辑资源消耗最少的临近算法,同时其显示效果也能够满足我们的要求。

缩放IP核的配置界面如下图所示:


图 27.1.1 缩放IP核配置界面

? Bits per symbol:选择symbol的位数,通常是一个字节

? Symbols in parallel:选择并行发送的symbol个数

? Symbols in sequence:选择按顺序发送数据的个数,通常为1

? Enable runtime control of output frame size and edge/blur thresholds:使能运行时控制

帧输出大小和边缘/模糊阈值。

? Maximum input frame width:选择输入最大帧的宽度

? Maximum input frame height:选择输入最大帧的高度

? Maximum output frame width:选择输出最大帧的宽度

? Maximum output frame height:选择输出最大帧的高度

? 4:2:2 video data:选择帧格式是否为4:2:2格式

? No blanking in video:如果输入视频在转换到 Avalon-ST 视频协议时不包含垂直消隐,

则打开使能

? Scaling algorithm:选择缩放算法。Nearest Neighbor(临近算法)、Bilinear(双线性算

法)、Bicubic(双三次算法)、Polyphase(多项式算法)和 Edge Adaptive(边缘自适

应算法)。

其它一些不常用的参数保持默认即可,这里不作过多的介绍。

下表是缩放IP核常用的寄存器描述。

表 27.1.1 缩放IP核寄存器描述


由上表可知,地址0控制着缩放IP核是否使能;地址3和地址4控制输出视频的分辨率(宽

度和高度)。在获取到LCD屏的ID后,也就知道了LCD屏的分辨率,我们只需要将缩放IP核输

出的分辨率设置成LCD屏的分辨率即可,从而实现兼容不同分辨率的LCD屏。

Qsys系统中提供了很多VIP(Video and Image Processing,视频图像处理)的IP核,比

如:图像缩放、图像灰度校正等IP核。这些IP核在发送和接收视频数据时,都要按照Avalon

ST的视频标准进行传输,Avalon-ST的视频标准定义了传输的信号线,如图 27.1.2所示:


图 27.1.2 Avalon-ST视频格式信号线

图中为两个VIP IP核通过Avalon-ST的视频标准传输数据的示意图,从图中可以看到

Avalon-ST视频标准的端口信号,接下来我们介绍下这些端口信号分别代表什么含义。

startofpacket:开始包,用于表示一帧视频传输的开始,高电平有效。

endofpacket:结束包,用于表示一帧视频传输的结束,高电平有效。

data:视频流数据。

empty:可选的空标志信号,当单次传输超过一个像素点的时候,会增加一个空标志信

号,用于表示哪些数据是无效的。

valid:有效信号,用于表示data是否有效。

ready:准备完成信号,当ready信号拉高时,此时发送端开始发送数据。

Avalon-ST视频包传输时序图如所示:


图 27.1.3 Avalon-ST视频包传输时序图

由上图可知,在时钟(clock)的驱动下,当发送端检测到ready信号为高电平时,此时

开始传输数据,发送端拉高开始包信号(startofpacket)和数据有效信号(valid),此时

第一次传输数据。需要注意的是,图中一个时钟周期传输的数据量为24位,分3个通道传输,

对应缩放IP的设置为:Bits per symbol设置为8,Symbols in parallel设置为3。当单帧数

据传输结束后,此时拉高结束包信号(endofpacket)。

VIP IP核传输数据遵循Avalon-ST的视频标准,同时为了适配不同的视频流传输,这个标

准也是一个可配置的协议,包含视频包、控制包和用户包,我们称之为VIP视频协议。VIP视

频协议规定,在传输视频包之前,必须先传输控制包,而用户包是可选的,一般用来传输和

用户相关的内容,如帧ID信息、音频等。

包的类型是由包的ID来指定的,包起始传输的D0[3:0]即为包的类型,用于表示后面传输

的类型为视频包、控制包或者用户包。包传输ID与包传输类型的对应关系由下表所示:

表 27.1.2 包类型定义


在包传输的类型中,常用的就是控制包和视频包,从名字中我们就可以看出,控制包主

要用来传输一些配置信息的,而视频包用来传输视频数据,控制包数据的详细定义如下表所

示:

表 27.1.3 控制包数据定义

下图为扫描方式与具体值的对应关系。

图 27.1.4 扫描方式定义

图中Interlacing表示隔行扫描,Progressive为逐行扫描,本次实验所使用的为逐行扫

描,所以参数要设置为4’b0010。

由此可知,我们在使用缩放IP核时,必须按照VIP视频协议来传输数据,协议规定了传输

数据时包括控制包和视频包,同时在传输控制包和视频包之前,要先传输包类型ID,作为包

类型的标志。而在传输控制包和视频包时,要符合Aavlon-ST的视频流标准,最终我们缩放IP

核才能实现输入视频流分辨率到输出视频流分辨率的调整。

在介绍完缩放IP核后,接下来我们再来学习下SMI管理接口。

SMI管理接口

SMI串行管理接口,也被称作MDC/MDIO接口,可以用来读写PHY的寄存器。在“以太网通

信实验”章节中,实际上我们只用到了以太网的MII接口,并没有使用MDC/MDIO接口。

RTL8201CP芯片的参数可以通过MDC/MDIO接口来配置,由于其默认的参数就可以实现MII接口

的自适应10M/100M收发数据,因此可不必对芯片做配置。我们本次网络通信实验完成的功能

是读取网口和其它网络设备的连接状态,这个就需要通过MDC/MDIO接口来完成。

SMI串行管理接口包括MDC和MDIO两条信号线,MDC是时钟信号,由主机(FPGA)发送给从

机(PHY芯片),最大不超过2.5MHz;MDIO是双向数据信号,和IIC接口有些类似,但是其传

输的时序有些区别。SMI接口的写时序图和读时序图分别如图 27.1.5和图 27.1.6所示:

图 27.1.5 SMI接口写时序


图 27.1.6 SMI接口读时序

Preamble:前导码,DMIO至少保持32个时钟周期的高电平,用于同步PHY芯片。

ST(Start of Frame):2位帧开始信号,使用“01”作为帧开始信号。

OP(Operation Code):2位操作码,即读写控制信号,10:读;01:写。

PHYAD(PHY Address):5位物理地址,由PHY芯片引脚的9、10、12、13、15决定。

REGAD(Register Address):5位寄存器地址。

TA(Turnaround):2位的TA,在读命令中,MDIO在此时由MAC驱动改为PHY驱动,并等待

一个时钟周期准备发送数据;在写命令中,不需要MDIO方向发生变化,则只是等待两个时钟

周期准备写入数据。

DATA:16位数据,在读命令中,PHY芯片将读到的寄存器的数据写到Data中;在写命令

中,MAC将要写入寄存器的值写入Data中。

IDLE:空闲状态,此时MDIO处高阻状态。

PHY芯片是在MDC时钟的上升沿采集和输出MDIO数据的,为了保证数据的可靠传输,FPGA

在MDC的下降沿更新和采集MDIO的数据。

需要注意的是,PHY Address由PHY芯片引脚的9、10、12、13、15决定,这几个引脚一方

面表示PHY芯片的物理地址,另一方面也用于指示连接状态的LED灯,如果通过RJ45接口,连

接其它网络设备的话,虽然硬件上引脚接地,也可能出现高电平的情况。开拓者FPGA开发板

连接其它网络设备后,PHY地址为9。

PHY芯片的寄存器比较多,表 27.1.4和表 27.1.5列出了程序中用到的两个寄存器,至于

其它寄存器的详细信息可以参考RTL8201CP的数据手册。

表 27.1.4 寄存器地址1详细信息

这里我们主要读取寄存器地址1的Bit[2],来获取当前PHY芯片有没有和其它网络设备进

行连接。

表 27.1.5 寄存器地址3详细信息

寄存器地址3可以用来读取当前PHY芯片是否为RTL8201。

实验任务

本章我们要在开拓者FPGA开发板上,搭配LCD屏,完成一个综合测试实验,包括上电自检

以及14个应用功能,应用功能分别是:按键测试、LED测试、蜂鸣器、数码管、串口、红外遥

控、EEPROM、环境光、RTC实时时钟、音乐播放、ADDA、手写画笔、摄像头和网络通信,该实

验可以测试开发板的大部分功能。

硬件设计

首先,我们把综合实验的功能实现划分为两部分,“外设的驱动”和“用户界面的绘

制”。其中用户界面的绘制比较复杂,适合用软件来实现,即在嵌入式处理器Nios II中采用

C语言来设计。而驱动外设的选择性比较灵活,对于通信速率或者处理速度要求较高的外设来

说,必须使用硬件来实现,即采用Verilog HDL来设计,如OV5640摄像头图像的采集以及LCD

屏的显示;对于其它通信速率或者处理速度要求较低的外设来说,既可以使用硬件来实现,

也可以使用软件来实现。

使用硬件来驱动外设的话,会消耗比较多的逻辑资源,而采用软件驱动外设只需消耗很

少的逻辑资源,只在固化程序时,受限于EPCS Flash存储器的存储资源。Qsys系统搭建Nios

II处理器以及缩放IP核,会消耗比较多的逻辑资源,受限于FPGA逻辑资源的大小,本次实验

将部分通信速率较低的外设使用Nios II处理器来驱动,而其余的外设驱动使用硬件来实现。

在软硬件划分之后,我们来看一下整个系统的实现方案,如图 27.3.1所示。OV5640摄像

头图像采集及LCD显示对处理速度的要求较高,因此和图像显示相关的功能使用硬件来实现。

OV5640摄像头的数据先写入FIFO,然后SDRAM桥控制模块通过Qsys系统生成的SDRAM控制器,

写入显存SDRAM中。需要注意的是,OV5640摄像头的图像数据无法直接通过SDRAM控制器写入

SDRAM中,因此本次实验通过SDRAM桥控制模块和SDRAM控制器实现SDRAM的读写操作。

用户界面的绘制由Nios II处理器来完成,为了提高UI界面的开发效率,UI界面的绘制我

们将在Nios II中采用uC/GUI来实现,这样将会大大提高UI界面的开发效率以及降低UI 界面

绘制的复杂度。与此同时,显存SDRAM也用作UI绘制过程中的显存,SDRAM桥控制模块会根据

Nios II处理器的控制,从SDRAM中读出UI界面或者摄像头的图像数据,并最终转换成VIP协议

的视频流,连接至Qsys系统中的缩放IP核;图像数据经缩放IP核后,输出调整分辨率之后的

图像,然后转换成FIFO接口的数据以便于LCD驱动模块来读取,最终将图像数据显示在LCD液

晶屏上。

由系统框图可知,红外接收驱动模块、数码管驱动模块、ADDA驱动模块以及触摸驱动模

块是由硬件来实现的,Nios II处理器通过Avalon-MM端口来写入和读出模块中的数据,比如

红外接收到的数据、数码管显示的数值等。

图 27.3.1 GUI综合实验系统框图

整个系统的设计方案确定之后,我们还需要完成用户界面的设计。根据实验任务的要

求,用户界面应该包含上电自检界面、主界面以及14个应用功能的子界面。这里只列出LCD主

界面的显示图,如图 27.3.2所示:

图 27.3.2 LCD显示主界面

上面的UI设计我们将在Nios II中采用uC/GUI来实现,这部分内容会在接下来的软件设计

中讨论,我们先对照着图 27.3.1来看一下底层硬件中各个模块的设计思路。

OV5640驱动模块

OV5640驱动模块(ov5640_dri)主要负责摄像头的配置、图像采集,并输出图像数据,

其模块接口定义如下图所示:


图 27.3.3 OV5640驱动模块及其接口定义

模块的输入端为8位的图像数据(cam_data),输出端为写使能信号(wr_en)和写16位

图像数据信号(wr_data),图像数据为RGB565格式,写使能和写数据信号连接到FIFO模块

(ov5640_fifo)。除此之外,模块还输出了摄像头初始化完成信号(cam_init_done)和摄

像头的ID标志(ID_flag),这个标志可以用来判断当前连接的摄像头是否为OV5640,如果不

是的话,即没有检测到OV5640摄像头,ID_flag为低电平。

OV5640驱动模块内部例化了3个子模块,分别为OV5640配置模块

(i2c_ov5640_rgb565_cfg)、OV5640 I2C驱动模块(i2c_dri_ov5640)和图像采集模块

(cmos_capture_data),如下图所示:


图 27.3.4 OV5640驱动模块框图

图像采集模块负责将输入的8位数据转成16位的RGB565数据;OV5640配置模块寄存了

OV5640需要配置的寄存器地址和数据,在开始配置之前,先对摄像头的ID进行读取,从而判

断出开发板是否连接OV5640摄像头;OV5640 I2C驱动模块(i2c_dri_ov5640)负责驱动摄像

头的配置总线,即SCCB总线,由于本次实验增加了读取摄像头ID的功能,而SCCB接口的读操

作和IIC接口的读操作有些许差别,因此OV5640 I2C驱动模块在IIC驱动模块上做了一些修

改,即将读操作的重新开始(restart),改为先停止后开始。

需要注意的是,通过SCCB接口读取摄像头的ID时,由于配置接口的SCL和SDA信号线没有

接上拉电阻,因此在Quartus II软件中,需要将这两根信号线连接上拉电阻。

管脚设置成弱上拉的步骤如下:打开工程的管脚分配界面,在界面端口设置信息的空白处

右击,选择Customize Columns,如图 27.3.5所示:


图 27.3.5 管脚分配界面

双击左侧的Weak Pull-Up Resistor,将其添加至右侧的列表中(如果已经出现在右侧列

表中,可忽略此步骤),并点击【OK】按钮,如下图所示:


图 27.3.6 添加弱上拉的选项

此时在管脚分配界面可以看到Weak Pull-Up Resistor的选项,在对应cam_scl端口和

cam_sda端口,设置成On即可。如下图所示:

图 27.3.7 设置成弱上拉

为了适配不同LCD屏的显示,本次实验添加了缩放IP核,缩放之前的分辨率固定为

800x480,因此,摄像头输出的图像分辨率设置为800x480。

SDRAM桥控制模块

SDRAM桥控制模块(sdram_bridge_control)一方面负责从FIFO模块(ov5640_fifo)中

读出OV5640的图像数据,写入SDRAM中,写入的频率由OV5640 FIFO模块缓存的数据个数决

定;另一方面也负责从SDRAM中读出数据,读出数据的频率由fifo_2_st模块(FIFO数据转

Avalon-ST数据流模块)输出的fifo缓存个数决定。其模块接口定义如下图所示:


图 27.3.8 SDRAM桥控制模块及其接口定义

我们在前面说过,SDRAM既作为OV5640摄像头图像的显存,也作为UI界面的显存,实际上

图像显存和UI界面的显存,占用的地址空间是不一样的。当Nios II处理器发送控制信号显示

OV5640摄像头数据时,SDRAM桥控制模块读取图像的显存地址;而当Nios II处理器发送控制

信号显示UI界面时,SDRAM桥控制模块读取UI界面的显存地址,因此,当UI界面和摄像头图像

需要切换显示时,只需要修改读取SDRAM的地址,就可以实现快速的切换显示。

SDRAM桥控制模块无论读取的是摄像头图像数据的显存地址,还是UI界面的显存地址,最

终都是要经过缩放IP核改变像素的分辨率。为了方便下一级模块将16位数据转成Avalon-ST的

数据流,我们在SDRAM桥控制模块对读出的16位像素数据做了一层封装,将16位数据封装成19

位数据,这19位数据从高位到低位依次为开始包信号(source_sop)、结束包信号

(source_eop)、数据有效信号(source_valid)和16位数据(source_data)。

FIFO数据转Avalon-ST数据流模块(fifo_2_st)

FIFO数据转Avalon-ST数据流模块主要负责的是,将SDRAM桥控制模块输出的数据先写入

FIFO,然后从FIFO中读出数据时,并转成Avalon-ST格式的数据流。其模块接口定义如下图所

示:


图 27.3.9 FIFO转ST数据流模块接口及定义

该模块内部例化了FIFO模块,输入的数据之所以先经过FIFO缓存,是因为要先等待下一

级模块输出ready(准备完成)信号,才能给下一级模块输出数据,同时该模块将输入的19位

数据转成Avalon-ST的数据流格式,即开始包信号(st_source_sop)、结束包信号

(st_source_eop)、数据有效信号(st_source_valid)和16位数据(st_source_data)。

Avalon-ST数据流转VIP格式数据流

由于缩放IP模块输入的数据必须为VIP格式数据流,因此该模块主要对Avalon-ST格式的

数据流进行封装,即添加包类型以及控制包。其模块接口定义如下图所示:

图 27.3.10 ST转VIP格式模块接口及定义

我们在简介部分中有向大家介绍,VIP视频协议规定,在传输视频包之前,必须先传输控

制包,包的类型是由包的ID来指定的,包起始传输的D0[3:0]即为包的类型,用于表示后面传

输的类型为视频包、控制包或者用户包。

ST格式转VIP格式模块在传输视频包之前,先发送控制包类型(ID),ID=4’hF;然后发

送控制包的内容,即输入视频的宽度为800,高度为480,图像扫描方式为逐行扫描;接下来

发送视频包的类型(ID),ID=4’h0;最后发送视频包,即有效的图像数据。在发送包类型

(ID)的时候要拉高包开始信号(dout_startofpacket),控制包和视频包最后一位数据发

送完成后,拉高包结束信号(dout_endofpacket)。

需要注意的是,在缩放IP核的配置界面(软件设计部分会介绍)中,设置的数据位宽为

24位,即RGB888的数据格式,而输入的数据为RGB565格式,因此在输出数据的时候,各个颜

色分量的低位补1,以满足缩放IP核的格式要求,最终该模块输出的信号连接至Qsys系统的缩

放IP核模块。

VIP数据流转Avalon-ST格式数据流

缩放IP核模块输入的数据为VIP数据流格式,那么输出调整分辨率之后的数据同样也为

VIP数据流格式,因此VIP数据流转ST数据流模块实际上是对数据进行解包,其模块接口定义

如下图所示:

图 27.3.11 VIP转ST数据流模块及定义

该模块可以看成是ST格式转VIP格式模块的逆过程,将输出的Avalon-ST格式数据连接至

下一级模块。

Avalon-ST数据流转FIFO模块(fifo_2_st)

Avalon-ST数据流转FIFO模块主要将输入的ST数据流存入FIFO,根据FIFO中的数据个数来

控制读取ST数据流的速度,FIFO中的读操作接口连接至LCD驱动模块,其模块接口定义如下图

所示:


图 27.3.12 ST数据流转FIFO模块接口及定义

LCD顶层驱动模块

LCD驱动模块负责驱动LCD屏,包括MCU屏和LCD屏,其模块接口定义如下图所示:


图 27.3.13 LCD顶层驱动模块

图中有两组LCD端口信号,一组连接至顶层模块的端口信号,另一组连接至Qsys模块的端

口信号,其中Qsys模块的LCD端口信号主要用于读取LCD屏的ID,以及对MCU LCD屏进行初始

化。由于MCU LCD屏的初始化比较复杂,需要配置的寄存器非常多,所以这部分内容非常适合

软件来实现,而LCD屏的显示对处理速度要求较高,因此使用硬件来实现。

LCD顶层模块例化了以下四个模块,分别是LCD信号选择模块(lcd_signal_sel)、RGB

LCD屏驱动模块(rlcd_driver)、MCU LCD屏驱动(mlcd_driver)和时钟分频模块

(clk_div)。如下图所示:

图 27.3.14 LCD顶层模块框图

LCD信号选择模块主要对顶层模块的LCD端口信号进行连接的选择,当LCD初始化未完成

时,将顶层模块的LCD端口信号连接至Qsys模块;当LCD初始化完成,并且读到的ID为RGB LCD

屏的ID时,将顶层模块的LCD端口信号连接至RGB LCD屏驱动模块;否则连接至MCU LCD屏驱动

模块。

时钟分频模块根据输入的LCD屏的ID,选择输出不同的时钟频率,这是由于不同分辨率的

RGB LCD屏和MCU LCD屏,对应LCD的时钟频率不同。

RGB LCD驱动模块负责驱动RGB LCD屏,同时根据输入的RGB LCD屏的ID,来选择使用不同

的参数,如行同步像素数、行同步后沿像素数等。

MCU LCD驱动模块负责驱动MCU LCD屏,同样也需要根据输入的MCU LCD屏的ID,来选择使

用不同的寄存器地址与寄存器参数。

触摸屏驱动模块

触摸屏驱动模块完成对触摸屏按键的检测与触摸点坐标的获取,其模块接口定义如下图

所示:


图 27.3.15 触摸屏驱动模块接口及定义

触摸屏驱动模块支持正点原子推出的所有电阻屏和电容屏,该模块根据输入的LCD屏的

ID,来对触摸屏执行不同的配置和获取触摸点坐标。当检测到屏幕被按下后,会拉高

touch_done信号,如果touch_valid一直为高电平,则表示触摸屏一直被按下,Nios II通过

Avalon-MM接口来获取坐标值。图中page_paint_flag为Nios II输出的手写画笔界面的标志,

便于电阻屏连续检测触摸点坐标。

触摸屏驱动模块例化了三个子模块,如图 27.3.16所示。其中GT系列芯片配置模块

(touch_gt_cfg)用于初始化触摸屏(GT系列芯片包括4.3寸屏幕和10.1寸屏幕芯片),即通

过IIC接口对GT芯片进行配置,并在配置完成后拉高配置完成信号(cfg_done)。而电容触摸

驱动模块(touch_ctrl)负责控制所有电容触摸屏驱动的整个流程,包括控制触摸屏初始化

的开始、检测触摸屏是否被按下以及读取触摸点的坐标。电阻触摸驱动模块(xpt2046)负责

驱动电阻触摸屏,需要注意的是,电容触摸屏的驱动采用的是IIC协议,而电阻触摸屏采用的

是SPI协议。

图 27.3.16 触摸屏模块框图

GT系列芯片配置模块例化了以下三个模块,分别是信号切换模块(signal_switch)、

IIC驱动模块(i2c_dri_m)和i2c参数配置模块(i2c_reg_cfg),如图 27.3.17所示。

图 27.3.17 GT系列芯片配置模块框图

这里的IIC驱动模块和“EEPROM读写实验”中所使用的IIC驱动模块有些区别,在

“EEPROM读写实验”中,IIC驱动模块只支持单次读写,并不支持连续的读写。由于触摸屏的

初始化参数比较多,并且在读取触摸点坐标时也会对IIC接口进行连续的读操作,因此本次实

验在此基础上,增加了对IIC接口连续读写的功能,单次操作连续读写的次数由reg_num进行

设置,这样将会大大提高IIC读写的速度。当IIC单个地址读写完成后,IIC驱动模块会输出一

个单次完成的脉冲信号(once_done);当IIC单次操作完成后(连续地址读写完成),会输

出一个IIC操作完成的脉冲信号(i2c_done)。

IIC参数配置模块寄存了触摸屏初始化参数,由于本次试验FPGA的逻辑资源消耗很多,而

RAM资源消耗的较少,因此本次试验将GT系列的配置参数全部放在mif文件里,即存储在ROM

中。

由于电容屏驱动模块的读写操作和IIC参数配置模块的初始化操作都会用到IIC接口,因此这两个模块输出的端口信号需要先做一个选择,再连接到IIC的驱动模块中,信号选择的功

能是由信号切换模块实现的。这个模块实现的方法也比较简单,根据输入的cfg_switch信号

的高低电平进行选择。当cfg_switch为高电平时,将IIC参数配置模块的IIC操作端口信号连

接至IIC驱动模块;当cfg_switch为低电平时,将电容屏驱动模块的IIC操作端口信号连接至

IIC驱动模块。

在硬件设计部分中,主要向大家介绍了SDRAM桥控制模块的读写、缩放IP核输入数据的格

式转换与输出数据的格式转换、LCD屏幕显示驱动以及触摸驱动,而其它外设的驱动模块在前

面的实验中都有详细的讲解,这里不再重复赘述。需要说明的是,Nios II处理器通过

Avalon-MM端口来写入和读出模块中的数据,比如红外接收到的数据、数码管显示的数值等。

在介绍完各功能模块后,接下来我们在软件设计部分介绍一下如何实现UI界面的绘制,

以及如何利用触摸屏来实现与用户的交互。

软件设计

综合实验的UI界面比较复杂,包括上电自检界面、主界面以及14个应用功能子界面。为

了提高UI界面的开发效率,UI界面的绘制我们将在Nios II中采用uC/GUI来实现。Nios II除

了负责完成用户界面的绘制外,还根据触摸屏输入的触摸点坐标来实现相应的功能,为了做

到触摸点坐标的实时响应,本次实验触摸屏的驱动是在硬件中使用Verilog语言实现,Nios

II通过Avalon-MM端口来获取触摸驱动模块输出的触摸点的坐标。由于FPGA的逻辑资源有限,

Nios II处理器也负责驱动部分外设。

Qsys系统搭建

在介绍完触摸驱动模块和SDRAM桥控制模块之后,接下来我们来介绍下Qsys系统环境的搭

建,如图 27.4.1所示:

图 27.4.1 Qsys系统的搭建

Qsys系统使用的IP核,绝大多数在我们前面的实验中都有涉及,其中avalon_mm_bridge

为自定义的IP核,Nios II处理器通过Avalon-MM端口来写入和读出硬件模块中的数据;

sdram_bridge为Avalon-MM Pipeline Bridge IP核,通过SDRAM控制器来突发读写SDRAM;

pio_mdc和pio_mdio为以太网的MDC/MDIO管理接口,用于读取以太网的和其它网络设备的连接

状态;pio_cs、pio_clk、pio_mosi、pio_miso为SD卡的端口信号,用于对SD卡进行读写测

试;pio_page_paint_flag为手写画笔界面的标志,方便触摸驱动模块对连续触摸进行检测;

缩放IP核(alt_vip_cl_scl_0)用于放大和缩小图像的分辨率,以兼容不同分辨率的屏幕。

这里我们主要介绍下缩放IP核(alt_vip_cl_scl_0),其配置界面如图 27.4.3所示:


图 27.4.3 缩放IP核配置页面

Bits per symbol(symbol的位数)设置为8,Symbols in parallel(并行发送的symbol

个数)设置为3,Symbols in sequence(按顺序发送数据的个数)设置为1,则发送数据的位

宽为24(8*3)位。

由于本次实验需要根据LCD屏ID来调整缩放比,因此使能运行时控制帧输出大小。

缩放IP核固定输入分辨率为800x480,最大输出分辨率为1280x800(10.1寸RGB LCD

屏)。

输入视频在转换到Avalon-ST视频协议时不包含垂直消隐,因此勾选No Blanking invideo。

由于FPGA的逻辑资源有限,因此缩放算法这里选择对逻辑资源消耗最少的临近算法

(Nearest Neighbor),其余配置保持默认即可。

Nios II软件设计

在介绍完Qsys系统的搭建之后,最后我们再来介绍一下Nios II软件设计部分。

Nios II主要负责绘制上电自检界面、主界面以及14个应用功能子界面,除此之外,还需

要判断用户的触摸操作和部分外设的驱动。上电自检界面如图 27.4.4所示:


图 27.4.4 上电自检界面

在前面学习了uC/GUI相关的章节之后,相信对大家来说,绘制上图中的用户界面是比较

容易的。图中主要使用GUI_DispStringAt()函数绘制字符串,而对外设的测试方法,如

EEPROM、SD卡、AP3216C,则是向某个或某段地址写入固定值,然后读出数据,比较读出的值

和写入的值是否一致,如果一致则外设测试正确,否则外设测试出错。RTC实时时钟的测试方

法和其它外设有些区别,这里是通过读取RTC实时时钟的秒寄存器,如果在一秒时间内,秒寄

存器数值加1,则测试正确(如果数值为59,则加1后为0),否则测试错误。

在开发板上电自检完成后,接下来会进入主界面,主界面如图 27.4.5所示:

图 27.4.5 LCD显示主界面

这里需要强调的是,主界面的绘制并不是先绘制背景图片,再绘制应用图标和文字,而

是整个主界面是一幅图片,直接把图片绘制出来,就是上图中LCD显示的主界面。这里主要是

考虑到过多的字体和图片在最终固化程序时,会占用大量EPCS Flash的存储资源,而开发板

的片外存储资源是有限的,因此将主界面作为一副图片显示在主界面上。

接下来我们看下main函数的代码,了解下Nios II执行的过程,由于main函数的代码较

长,这里只贴上部分代码。

170 int main()

171 {

172 alt_u8 key,key_pre;

173 alt_u8 i;

174

175 alt_u8 led_button;

176 alt_u8 led_num;

177

178 alt_u8 grade=vol/8; //音频的音量级别

179 alt_u8 page_5640_done = 0; //ov5640子页面绘制完成页面

180

181 MY_LCD_Init(); //LCD初始化

182

183 IOWR_ALTERA_AVALON_PIO_DATA(PIO_OV5640_EN_BASE, 0); //显示GUI界面

184 GUI_Init(); //uC/GUI初始化

185 GUI_UC_SetEncodeUTF8(); //设置汉字编码格式

186 GUI_SetFont(&GUI_FontChinese_WRYH32);

187

188 lcdgui.width = lcddev.height;

189 lcdgui.height = lcddev.width;

190 height_ave32 = lcdgui.height/32;

191 width_ave8 = lcdgui.width/8;

192

193 switch(lcddev.id){

194 case 0x9341:{

195 IOWR(ALT_VIP_CL_SCL_0_BASE,3,320); //设置缩放后图像宽度

196 IOWR(ALT_VIP_CL_SCL_0_BASE,4,240); //设置缩放后图像高度

197 break;

198 }

199 case 0x5310:{

200 IOWR(ALT_VIP_CL_SCL_0_BASE,3,480); //设置缩放后图像宽度

201 IOWR(ALT_VIP_CL_SCL_0_BASE,4,320); //设置缩放后图像高度

202 break;

203 }

204 case 0x5510:{

205 IOWR(ALT_VIP_CL_SCL_0_BASE,3,800); //设置缩放后图像宽度

206 IOWR(ALT_VIP_CL_SCL_0_BASE,4,480); //设置缩放后图像高度

207 break;

208 }

209 case 0x1963:{

210 IOWR(ALT_VIP_CL_SCL_0_BASE,3,800); //设置缩放后图像宽度

211 IOWR(ALT_VIP_CL_SCL_0_BASE,4,480); //设置缩放后图像高度

212 break;

213 }

214 case 0x4342:{

215 IOWR(ALT_VIP_CL_SCL_0_BASE,3,480); //设置缩放后图像宽度

216 IOWR(ALT_VIP_CL_SCL_0_BASE,4,272); //设置缩放后图像高度

217 break;

218 }

219 case 0x7084:{

220 IOWR(ALT_VIP_CL_SCL_0_BASE,3,800); //设置缩放后图像宽度

221 IOWR(ALT_VIP_CL_SCL_0_BASE,4,480); //设置缩放后图像高度

222 break;

223 }

224 case 0x7016:{

225 IOWR(ALT_VIP_CL_SCL_0_BASE,3,1024); //设置缩放后图像宽度

226 IOWR(ALT_VIP_CL_SCL_0_BASE,4,600); //设置缩放后图像高度

227 break;

228 }

229 case 0x1018:{

230 IOWR(ALT_VIP_CL_SCL_0_BASE,3,1280); //设置缩放后图像宽度

231 IOWR(ALT_VIP_CL_SCL_0_BASE,4,800); //设置缩放后图像高度

232 break;

233 }

234 default: ;

235 }

236

237 IOWR(ALT_VIP_CL_SCL_0_BASE,0,1); //启动缩放模块

238 IOWR_ALTERA_AVALON_PIO_DATA(PIO_LCD_INIT_DONE_BASE,1); //初始化完成

239

240 init_tp_interrupt(); //触摸屏中断初始化

241 init_touch_key_interrupt(); //触摸按键中断初始化

242 init_uart_interrupt(); //串口中断初始化

243 init_paint_interrupt(); //手写画笔中断初始化

244 disable_paint_interrupt(); //初始化关闭画笔结束中断

245

246 gui_draw_sys_test_page(); //画系统测试界面

247 gui_draw_home_page(); //画主界面

248

249 while(1)

……

在LCD屏初始化完成后,获取到LCD屏的ID,此时根据LCD屏的ID,来设置缩放IP核输出分

辨率,使能缩放IP核并拉高LCD初始化完成信号,如代码中第193至第238行所示。接下来绘制

开发板的上电自检界面,自检界面完成后,进入主界面,如代码中第246行和第247行代码所

示。进入主界面后,接下来开始根据用户的触摸操作,来切换显示各个应用子界面,这部分

内容由while循环来完成。

我们这里只简单介绍下main函数的程序,了解下Nios程序的执行过程,还需要注意的是

当触摸屏被按下后,触摸屏驱动模块有可能检测到单个触摸点坐标触发多次,此时程序会多

次进入触摸中断函数tp_interrupt(),导致功能错误的情况。为了避免这一情况,在触摸屏

驱动模块中加入了对触摸点坐标的判断,如果触摸屏一直被按下没有松开,并且当前触摸点

坐标和上一次触摸点坐标一致的话,则忽略当前触摸点的坐标。

除此之外,新起点开发板的GUI综合程序只是在开拓者开发板GUI综合程序做了简单的修

改,因为两块FPGA开发板上的外设有所区别,因此我们在draw_page.h文件中定义了开发板的

类型,如下所示:

#define BOARD_TYPE 1 //0:新起点 1:开拓者

当BOARD_TYPE = 1时,表示执行开拓者的程序;当BOARD_TYPE = 0时,表示执行新起点

的程序。另外开拓者GUI程序改成适配新起点开发板,也不仅仅修改这一个参数,同时还需要

修改主界面的显示图片。

下载验证

接下来我们把程序下载至开拓者开发板上,验证我们所完成的GUI综合实验的功能。

要测试开拓者FPGA开发板综合实验的全部功能,大家得自备1张SD卡、1根网线、OV5640

摄像头。不过,就算没有外接这些模块,综合实验还是可以正常运行的,只是有些限制而

已。

针对LCD屏这里再补充一点,GUI综合实验必须连接LCD屏才能看到显示效果,该实验基于

图像缩放算法来适配不同分辨率的LCD屏幕,图像缩放之前的原始分辨率大小为800*480,而

2.8寸屏幕和3.5寸屏幕分辨率较低,所以缩放之后,字体的显示效果会比高分辨率屏幕的显

示效果差,为了获得更好的显示效果,建议大家连接4.3寸及以上的屏幕。

这里以4.3寸RGB LCD屏为例,大家拿出开发板,先接上12V1A电源适配器给开发板供

电,RGB LCD屏和开发板是通过40P的FPC排线相连接,如下图所示:

图 27.5.1开拓者FPGA开发板与4.3寸RGB屏连接示意图

最后,按下电源开关,给开发板上电,此时开发板右下角的蓝色电源灯会亮,同时开发

板会对EEPROM、SD卡、AP3216C和RTC做读写测试,如下图所示:


图 27.5.2 开拓者FPGA开发板开机自检界面

如果开发板在上电前连接了SD卡(SD卡槽在开发板背面),在测试成功后显示OK;如果

没有连接SD卡的话,会提示Error。

接下来进入到主界面之后,就可以通过点击屏幕的图标进行各项功能测试了。主界面如

下图所示:


图 27.5.3 RGB LCD液晶屏主界面

主界面有1个页面,总共是14个图标。每个图标代表一大功能,主界面顶部是状态栏,

用于显示“正点原子”四个字和当前时间。在任何界面下,都可以通过按下TPAD触摸按键返

回上一级,直至返回主界面。PS:TPAD就是开拓者FPGA开发板上的一个触摸按键,即右下角

的白色骷髅头。

如果大家的开发板连接了VGA显示器的话,在开发板上电之后,VGA显示器会显示出彩

条。需要说明的是,LCD屏处于任何GUI界面,VGA显示器都会一直显示彩条的,如下图所示。


图 27.5.4 开拓者开发板VGA显示画面

在介绍完主界面后,接下来我们开始介绍各个功能。

1、按键测试

点击主界面的按键测试图标,进入如图 27.5.5所示的界面:


图 27.5.5 按键测试界面

上图中,左侧的图片是我们点击按键测试后进入的子界面,可以看到,图中共四个按键

图标,分别对应开拓者开发板上的KEY0~KEY3按键。当我们按下开发板上其中的一个按键后,

界面上对应的按键图标会变成红色背景,如上图中右侧图片所示;松开按键后,按键图标又

会恢复成黄色背景。

当我们想退出按键测试界面时,只需要按下开发板上的TPAD触摸按钮即可。

2、LED测试

点击主界面的LED测试图标,进入如图图 27.5.6所示的界面:

图 27.5.6 LED测试界面

上图中,左侧的图片是我们点击LED测试后进入的子界面,图中从左往右共4个LED图标,

分别对应开发板上的DS0~DS3,图标下方的按钮用来控制开发板上的LED灯的亮灭。当我们点

击界面上的其中一个按钮后,界面上对应的LED图标会变成蓝色(如上图中右侧图片所示),

同时开发板上的LED灯会点亮;再次点击按钮后,界面上对应的LED图标恢复成白色,同时开

发板上的LED灯会熄灭。

3、蜂鸣器

点击主界面的蜂鸣器图标,进入如图 27.5.7所示的界面:


图 27.5.7 蜂鸣器测试界面

上图中,左侧的图片是我们点击蜂鸣器后进入的子界面,点击界面上的“打开”按钮,

此时可以听到开发板上的蜂鸣器在鸣叫,并且按钮会显示成“关闭”(如上图中右侧图片所

示);点击界面上的“关闭”按钮,蜂鸣器即可停止鸣叫。

4、数码管

点击主界面的数码管图标,进入如图 27.5.8所示的界面:


图 27.5.8 数码管测试界面

上图中,左侧的图片是我们点击数码管后进入的子界面,图中有三个按钮,分别是

“-”、“打开”和“+”按钮。我们点击界面上的“打开”按钮,此时可以看到开发板上的

数码管显示数字,并且界面上同样也会显示数码管显示的数字(如上图中右侧图片所示),

点击界面上的“+”和“-”按钮可以对数字进行加减,点击“关闭”按钮即可关闭数码管的

显示。

5、串口

我们开拓者FPGA开发板板载两个串口,一个是USB串口,另一个是RS232串口,我们这里

测试的是USB串口。在开始测试之前,我们需要将USB线一端连接电脑,另一端与开发板上的

USB_232口相连接,需要注意的是,大家在第一次做串口实验时,需要安装USB的串口驱动程

序,该程序位于资料盘的“6_软件资料\1_软件\CH340驱动(USB串口驱动)_XP_WIN7共用”文

件夹下。串口测试需要在电脑中打开串口调试助手才能完成通信,我们资料盘中提供了几种

调试助手,本次测试使用的是“XCOM”调试助手,该软件位于“6_软件资料\1_软件\串口调

试助手\XCOM(ALIENTEK官方推荐)”文件夹下。我们本次串口通信的波特率为115200,串口

打开和设置完成后的界面如图 27.5.9所示。

图 27.5.9 串口打开界面

不同电脑的不同USB口串口号可能会不一样,大家可以根据自己的电脑进行选择,我们这

里选择的是COM5:USB-SERIAL CH340。

点击主界面的串口图标,进入如图 27.5.10所示的界面:


图 27.5.10 串口测试界面

上图是我们点击串口后进入的子界面,我们点击界面上的“发送”按钮,串口调试助手

即可接收到开发板发送的数据,如下图所示:

图 27.5.11 串口助手接收到数据

这个时候,我们点击串口调试助手的“发送”按钮,开发板界面上会显示接收到的数

据,如下图所示:


图 27.5.12 串口测试界面

6、红外遥控

点击主界面的串口图标,进入如图 27.5.13所示的界面:

图 27.5.13 红外遥控测试界面

上图中,左侧的图片是我们点击红外遥控后进入的子界面,图中第一栏是遥控器的键

值,第二栏是遥控器的符号。此时按下遥控器的按键(使用遥控器之前需要先将遥控器后部

的塑料绝缘片拔出),界面上会显示出遥控器的键值和符号(如上图中右侧图片所示)。

7、EEPROM

EEPROM是板载的电可擦除可编程只读存储器,是一种常用的非易失性存储器,点击主界

面的EEPROM图标,进入如图 27.5.14所示的界面:


图 27.5.14 EEPROM测试界面

上图中,左侧的图片是我们点击EEPROM后进入的子界面,点击“测试”按钮后,FPGA开

始向EEPROM的地址0写入数据0,数据写完后从地址0中读取数据,并将读取的数据显示在页面

中的读数据上;接着FPGA向EEPROM中的地址1中写入数据1,同样是写完后将数据读取出来,

并显示在界面上,直至写至EEPROM的地址99开始停止(如上图中右侧图片所示)。比较写入

的数据和读出的数据是相同的,说明本次EEPROM测试成功。

8、环境光

环境光传感器(AP3216C)是一个能够测量环境光强度和距离的整合型光感测距传感器。

点击主界面的环境光图标,进入如图 27.5.15所示的界面:


图 27.5.15 AP3216C测试界面

上图是我们点击环境光后进入的子界面,界面中第一栏是环境光的强度,第二栏是距离

值。环境光传感器(U7)位于开发板的左下角位置(靠近数码管),通过增加光照和接近环境

光传感器,可以在界面上看到光照值和距离值的实时变化。

9、时钟

点击主界面的时钟图标,进入如图 27.5.16所示的界面:

图 27.5.16 时钟测试界面

上图是我们点击时钟后进入的子界面,界面中显示了日期、时间、温度信息,并且在上

方区域,有一个指针式时钟显示。

同样,按下TPAD触摸按钮返回至主界面。

10、音乐播放

点击主界面的音乐播放图标,进入如图 27.5.17所示的界面:


图 27.5.17 音乐播放界面

上图是我们点击音乐播放后进入的子界面,界面中有三个按钮,分别是“-”、“打开”

和“-”按钮。首先点击“打开”按钮,启动音频播放的功能,然后使用音频线一端连接开发

板上的LINE_IN接口,另一端与播放设备相连接(电脑或者手机的耳机接口),此时开发板上

的喇叭会播放手机或者电脑播放的音乐,如果将耳机连接至开发板上的PHONE接口,在耳机中

同样可以听到音乐。

11、ADDA

点击主界面的ADDA(模数/数模转换)图标,进入如图 27.5.18所示的界面:

图 27.5.18 ADDA测试界面

上图中,左侧的图片是我们点击ADDA后进入的子界面,板载的ADDA芯片同时具有模数和

数模转换的功能,点击“测试”按钮后,DA输出的数字量从0累加至255(如上图中右侧图片

所示),此时AD采集到的模拟电压值从0累加至约3.3V说明测试成功。

12、手写画笔

点击主界面的手写画笔图标,进入手写画笔的界面。通过在白板界面滑动手指可以看到

留下的轨迹,如图 27.5.19所示。


图 27.5.19 手写画笔测试界面

同样,按下TPAD触摸按钮返回至主界面。

13、摄像头

此应用支持的摄像头模块为ALIENTEK OV5640-AF这款500W像素的CMOS摄像头模块,在进

入摄像头应用之前,需要先将OV5640插在开发板上的Camera扩展接口上(摄像头镜头方向朝

外),点击主界面的摄像头图标,进入图 27.5.20所示的界面:


图 27.5.20 摄像头采集画面

上图是我们点击摄像头后进入的子界面,接下来就可以从界面中看到摄像头采集到的画

面,按下TPAD触摸按钮返回至主界面。

14、网络通信

此应用可以读取开发板的网口是否连接网线,点击主界面的网络通信图标,进入图

27.5.21所示界面。


图 27.5.21 以太网测试界面

上图是我们点击网络通信后进入的子界面,如果此时未连接网线的话,界面中会提示

“请连接网线!”,如果已经连接了网线,界面中会提示“Check OK!”。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表