概述
1)实验平台:正点原子开拓者FPGA 开发板
2)摘自《开拓者 Nios II开发指南》关注官方微信号公众号,获取更多资料:正点原子
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/index.html
第十三章通过Nios II写彩条LCD显示实验
在前面的实验中,我们成功地在MCU TFT-LCD上实时显示出了摄像头采集的图像。本章我
们将使用FPGA开发板实现:使用Nios II往SDRAM里写彩条数据,并在现有的RGB/MCU TFT-LCD
液晶屏上显示出来。
本章包括以下几个部分:
13.1 简介
13.2 实验任务
13.3 硬件设计
13.4 软件设计
13.5 下载验证
简介
在此次实验中,我们需要通过LCD来显示SDRAM中的彩条数据,这就要求SDRAM送出数据的
速度比较快。因此我们选择使用具有突发读写能力的Avalon-MM Pipeline Bridge IP核来和
SDRAM进行数据通信。所以接下来我们将介绍这个IP核。
Avalon-MM流水线读传输,给需要多个周期才能为首次访问返回数据的从设备提高了吞吐
量。这些从设备通常可以在以后的一段时间内,每个周期返回一个数据。新流水线式读传输可
以在上一次传输的readdata返回之前,开始新的传输。流水线的读传输具有地址阶段和数据阶
段。主机在地址阶段通过供给地址来发起传输。从机在数据阶段通过交付数据来完成传输。一
个新的传输(或多个传输)的地址阶段,可以在前一个传输的数据阶段完成之前开始。
如图所示是Pipeline Bridge IP核的配置界面:
图 13.1.1 Pipeline Bridge IP核配置界面
接下来,我们介绍需要配置的几个设置:
⚫ Data width:传输数据的位宽
⚫ Symbol width:一个symbol的位宽,通常是一个字节(保持默认)
⚫ Address width:地址信号的位宽,与存储器的存储空间大小有关(此次我们使用的是
SDRAM)
⚫ Address units:地址单位。主端口处的地址单位默认是symbol,在从端口的地址单位为
word
⚫ Maximum burst size(字):一次突发的最大数据量(字个数)
⚫ Maximum Pending Read Transactions:最大等待读传输。对于从机来说,这个常量是从
机能够允许的等待中的、最大的读请求个数。也就是能被允许的未被处理的读请求个
数。对于输出有readdatavalid信号的从机来说,这个值不能为0。(保持默认)
⚫ Line wrap bursts:一种突发传输模式,由突发传输个数以及数据位宽,来决定突发传
输的地址区间。由于本次实验用到的是地址递增型的突发模式,这里就不做详细介绍
了。(保持默认)
⚫ Pipeline command signals:流水线命令信号(主端口的控制信号,保持默认)
⚫ Pipeline response signals:流水线响应信号(从机的响应信号,保持默认)
接下来我们了解一下这个IP核留给用户的信号端口,如下图所示:
图 13.1.2 留给用户的信号端口
图中紫色的信号是留给用户的信号端口,其中burstcount、writedata、address、write、
read、byteenable、debugacess信号是用户可以操作的主端口信号,waitrequest、readdata、
readdatavalid信号是从机输出的不可操作信号。我们将在下表对这些信号的作用进行说明。
图 13.1.3 信号说明
实际的配置如下图所示:
图 13.1.4 IP核的参数配置
由于我们使用的SDRAM中的数据位宽是16bit的,所以,这里的Data width应该设置为16。
这里Address units(地址单元)使用的默认设置symbol,而symbol通常代表一个字节。由于
SDRAM的存储空间比较大,因此地址位宽比较大,这里设置为26位。为了让SDRAM送出数据更快
些,这里使用了IP核的突发读写功能,将Maximum burst size的值设置成512,也就是一次突
发读SDRAM里的512个存储单元。其它的参数使用默认设置即可。接下来我们了解一下实验中将
使用到的突发功能。
在一次处理多个数据传输的时候,突发读可以增加从端口(例如SDRAM)的数据吞吐量,
大大提高数据传输的效率。支持读、写操作的Avalon-MM突发接口一定支持突发读、写操作。
如果从机包含burstcount输入接口,那么它一定支持突发操作。
突发操作要求
在一次突发的开始阶段,从机必须获取一次(仅一次)address、burstcount信号。也就
是在一个时钟周期的上升沿,将address、burstcount信号送给主机相应的信号端口。
突发读操作相应的规则:
⚫ 一次读突发的起始阶段(地址阶段),需要发送一个周期的read(高电平)、address、
burstcount信号。然后在这次的读突发阶段里,read信号需要保持低电平
⚫ 一个读突发传输中出现了多个周期的read信号高电平,这表示主机发送了多个读突发
传输请求
⚫ 主机发送的burstcount值有多大,从机就需要返回相应个数的数据(readdata)来完成
数据传输。当burstcount的值为0时,从机不会响应读命令。(用户不用考虑从机相关
的问题,主机发送完正确指令后,从机会自动反应)
⚫ 从机在输出readdata的时候,相应还会拉高readdatavalid信号一个时钟周期。从机通过
这种方式来输出数据。从机拉低readdatavalid信号会延迟,但是不会终止突发数据传
输
⚫ 当burstcount的值大于1的时候,intel建议将byteenables的所有位置1
突发写操作相应的规则:
⚫ 在突发的开始阶段,在主端口处需要发送burstcount信号。那么从机必须接收相应个数
的writedata来完成突发操作(在主端口往从机发送writedata)。主从对之间的连接保
持锁定,直到突发完成。此锁定保证其他主机无法操作从机,直到写突发结束。
⚫ 当write信号拉高时,主机需要给从机发送writedata。读突发期间,拉低write信号表示
延迟突发操作而不是终止突发。此时其他主机仍然无法操作从机。拉低write信号会降
低传输效率
⚫ 当byteenable = 8'b11110000,32位的主机在往64位从机突发写数据的时候,会在从机
的地址4开始写数据,但在从机看来是从地址0开始写的数据
实验任务
本节实验任务是使用开发板,通过Nios II往SDRAM里写彩条数据,在正点原子推出的
RGB/MCU TFT-LCD液晶屏模块上显示出来,支持2.8寸320*240、3.5寸480*320、4.3寸800*480、
7寸800*480这些尺寸/分辨率的MCU TFT-LCD屏幕,还支持4.3寸480*272、7寸800*480、7寸
1024*600、10.1寸1280*800这些尺寸/分辨率的RGB TFT-LCD屏幕。
硬件设计
本章实验任务的系统框图如下所示:
图 13.3.1 OV5640摄像头RGB TFT-LCD显示系统框图
如图所示,PLL时钟模块为LCD模块以及Qsys模块、sdram_bridge_control模块提供驱动时
钟;Qsys模块则负责读取连接在开拓者开发板上的LCD的ID,并以ID号来判断是MCU TFT-LCD还
是RGB TFT-LCD。若是MCU TFT-LCD,则开始配置MCU TFT-LCD的寄存器,即初始化LCD。若是
RGB TFT-LCD , 则 在 定 义 完 屏 幕 分 辨 率 之 后 , 直 接 输 出 ID 以 及 初 始 化 完 成 信 号 ;
sdram_bridge_control模块用于从SDRAM读取彩条像素数据,并且把数据写入FIFO中;LCD模块
负责从FIFO中读取像素数据,并驱动LCD显示屏;SDRAM则负责存放彩条数据,以及Qsys运行所
需的代码和处理数据;
顶层模块的原理图如下图所示:
图 13.3.2 顶层模块原理图
由上图可知,FPGA顶层模块(lcd_all_colorbar)例化了以下5个模块:PLL时钟模块(pll)、
SDRAM桥控制模块(sdram_bridge_control)、FIFO缓存模块(fifo)、LCD模块(lcd_top)、
Qsys模块(qsys)。
PLL时钟模块(pll):PLL时钟模块通过调用锁相环(PLL)IP核实现,总共输出3个时钟,
频率分别为100Mhz(SDRAM桥控制模块以及Qsys驱动时钟)、100Mhz(SDRAM相位偏移时钟)和
50Mhz(LCD分频用)时钟。第一个100Mhz时钟驱动了SDRAM桥控制模块以及Qsys,第二个100Mhz
时钟驱动了SDRAM,最后一个50Mhz时钟作为LCD模块的驱动时钟。
SDRAM桥控制模块(sdram_bridge_control):SDRAM桥控制模块(sdram_bridge_control)
通过给Pipeline Bridge IP核读请求信号、SDRAM地址、突发读写长度来读取SDRAM中的像素数
据。
FIFO缓存模块(fifo):FIFO缓存模块将SDRAM桥控制模块(sdram_bridge_control)读
取到的像素数据进行缓存,并供给LCD模块(lcd_top)读取、显示到LCD上。
LCD模块(lcd_top):LCD模块下例化了以下四个模块:LCD信号选择模块(lcd_signal_sel)、
分频模块(clk_div)、MCU TFT-LCD驱动模块(mlcd_driver)、RGB TFT-LCD驱动模块
(rlcd_driver)。LCD模块负责与LCD进行数据交互、驱动LCD屏幕显示从fifo中读取的像素数
据。
Qsys模块(qsys):Qsys模块负责读取LCD的ID,若连接在开发板上的是MCU TFT-LCD,则根据读取到的ID来配置LCD屏幕的寄存器,完成初始化LCD屏幕的任务。另外,Qsys模块还将读
取到的ID、初始化完成信号输出给LCD模块;Qsys系统的搭建如图 11.3.3所示,用到的IP核有:
Nios II Processor、System ID Peripheral、Jtag Uart、EPCS/EPCQx1 Serial Flash Control、
Pio、SDRAM Controller、Pipeline Bridge。有关这些IP核的详细介绍及使用方法,请参考Nios
开发指南前面章节的内容。
我们是在开拓者Nios II开发指南的“OV5640摄像头MCU TFT-LCD显示实验”基础上完成这
个实验的,相对于该实验,我们在Qsys系统中添加了Pipeline Bridge IP核。
图 13.3.3 Qsys系统的搭建
我们在顶层代码里例化了五个模块,如下所示:
1 module lcd_all_colorbar(
2
3 //时钟和复位接口
4 input sys_clk, //晶振时钟
5 input sys_rst_n, //按键复位
6
7 //SDRAM 接口
8 output sdram_clk,
9 output [12:0] sdram_addr,
10 output [ 1:0] sdram_ba,
11 output sdram_cas_n,
12 output sdram_cke,
13 output sdram_cs_n,
14 inout [15:0] sdram_dq,
15 output [ 1:0] sdram_dqm,
16 output sdram_ras_n,
17 output sdram_we_n,
18
19 //EPCS Flash 接口
20 output epcs_dclk,
21 output epcs_sce,
22 output epcs_sdo,
23 input epcs_data0,
24
25 //LCD接口
26 output lcd_rst , //LCD复位信号
27 output lcd_bl , //LCD背光控制
28 output lcd_de_cs , //LCD RGB:DE MCU:CS
29 output lcd_vs_rs , //LCD RGB:VS MCU:RS
30 output lcd_hs_wr , //LCD RGB:HS MCU:WR
31 output lcd_clk_rd , //LCD RGB:CLK MCU:RD
32 inout [15:0] lcd_data //LCD DATA
33 );
34
35 //reg define
36
37 //wire define
38 wire clk_100m_shift;
39 wire sys_clk_100m;
40 wire clk_50m_pll;
41 wire lcd_clk;
42 wire pll_locked;
43 wire rst_n;
44
45 //读写 SDRAM 桥接信号
46 wire bridge_write;
47 wire bridge_read;
48 wire [15:0] bridge_writedata;
49 wire [15:0] bridge_readdata;
50 wire [25:0] bridge_address;
51 wire [ 9:0] bridge_burstcount;
52 wire bridge_waitrequest;
53 wire bridge_readdatavalid;
54
55 //source_st_fifo信号
56 wire [9:0] source_fifo_wrusedw;
57
58 //LCD驱动模块接口信号
59 wire lcd_data_req;
60 wire [15:0] lcd_pixel_data;
61
62 //LCD初始化完成
63 wire lcd_init_done ;
64 wire [15:0] lcd_id ;
65 wire mlcd_cs_n_init ;
66 wire mlcd_wr_n_init ;
67 wire mlcd_rd_n_init ;
68 wire mlcd_rst_n_init ;
69 wire mlcd_rs_init ;
70 wire mlcd_bl_init ;
71 wire mlcd_data_dir_init;
72 wire [15:0] mlcd_data_out_init;
73 wire [15:0] mlcd_data_in_init ;
74
75 //*****************************************************
76 //** main code
77 //*****************************************************
78
79 assign rst_n = sys_rst_n & pll_locked ;
80 assign sdram_clk = clk_100m_shift;
81
82 //例化锁相环模块
83 pll u_pll (
84 .inclk0 (sys_clk ),
85 .areset (~sys_rst_n),
86 .c0 (sys_clk_100m), //QSYS 系统时钟
87 .c1 (clk_100m_shift), //SDRAM 时钟
88 .c2 (clk_50m_pll), //LCD 驱动时钟
89 .locked (pll_locked)
90 );
91
92 //例化QSYS系统
93 qsys u_qsys(
94
95 //时钟和复位
96 .clk_clk (sys_clk_100m),
97 .reset_reset_n (rst_n),
98
99 //EPCS
100 .epcs_flash_dclk (epcs_dclk ),
101 .epcs_flash_sce (epcs_sce ),
102 .epcs_flash_sdo (epcs_sdo ),
103 .epcs_flash_data0 (epcs_data0),
104
105 //SDRAM
106 .sdram_addr (sdram_addr),
107 .sdram_ba (sdram_ba),
108 .sdram_cas_n (sdram_cas_n),
109 .sdram_cke (sdram_cke),
110 .sdram_cs_n (sdram_cs_n),
111 .sdram_dq (sdram_dq),
112 .sdram_dqm (sdram_dqm),
113 .sdram_ras_n (sdram_ras_n),
114 .sdram_we_n (sdram_we_n),
115
116 //读写SDRAM的桥
117 .sdram_bridge_slave_waitrequest (bridge_waitrequest),
118 .sdram_bridge_slave_readdata (bridge_readdata),
119 .sdram_bridge_slave_readdatavalid (bridge_readdatavalid),
120 .sdram_bridge_slave_burstcount (bridge_burstcount),
121 .sdram_bridge_slave_writedata (bridge_writedata),
122 .sdram_bridge_slave_address (bridge_address),
123 .sdram_bridge_slave_write (bridge_write),
124 .sdram_bridge_slave_read (bridge_read),
125 .sdram_bridge_slave_byteenable (2'b11),
126 .sdram_bridge_slave_debugaccess (),
127
128 //PIO 输入输出
129 .mlcd_cs_n_export (mlcd_cs_n_init),
130 .mlcd_wr_n_export (mlcd_wr_n_init),
131 .mlcd_rd_n_export (mlcd_rd_n_init),
132 .mlcd_rst_n_export (mlcd_rst_n_init),
133 .mlcd_rs_export (mlcd_rs_init),
134 .mlcd_bl_export (mlcd_bl_init),
135 .lcd_data_in_export (mlcd_data_in_init),
136 .lcd_data_out_export (mlcd_data_out_init),
137 .lcd_data_dir_export (mlcd_data_dir_init),
138 .lcd_init_done_export (lcd_init_done), //LCD初始化完成
139 .lcd_id_export (lcd_id) //LCD ID
140 );
141
142 //读写 SDRAM 桥 控制模块
143 sdram_bridge_control u_bridge_ctrl(
144 .clk (sys_clk_100m),
145 .rst_n (rst_n & lcd_init_done),
146
147 .bridge_write (bridge_write),
148 .bridge_read (bridge_read),
149 .bridge_address (bridge_address),
150 .bridge_burstcount (bridge_burstcount),
151 .bridge_waitrequest (bridge_waitrequest),
152 .bridge_readdatavalid (bridge_readdatavalid),
153
154 .lcd_id (lcd_id),
155 .source_fifo_wrusedw (source_fifo_wrusedw)
156 );
157
158 // FIFO:缓存SDRAM中读出的数据供LCD读取
159 fifo u_fifo(
160 .wrclk (sys_clk_100m),
161 .rdclk (lcd_clk),
162
163 .wrreq (bridge_readdatavalid),
164 .data (bridge_readdata),
165 .wrusedw (source_fifo_wrusedw),
166
167 .rdreq (lcd_data_req),
168 .q (lcd_pixel_data),
169 .rdempty (),
170
171 .aclr (~(rst_n & lcd_init_done))
172 );
173
174 //RGB LCD 和 MCU LCD驱动
175 lcd_top u_lcd_top(
176 .clk (clk_50m_pll),
177 .rst_n (rst_n & lcd_init_done),
178 .pixel_data (lcd_pixel_data),
179 .pixel_en (lcd_data_req),
180 .lcd_clk (lcd_clk),
181
182 .lcd_rst (lcd_rst),
183 .lcd_bl (lcd_bl),
184 .lcd_de_cs (lcd_de_cs),
185 .lcd_vs_rs (lcd_vs_rs),
186 .lcd_hs_wr (lcd_hs_wr),
187 .lcd_clk_rd (lcd_clk_rd),
188 .lcd_data (lcd_data),
189
190 .mlcd_cs_n_init (mlcd_cs_n_init),
191 .mlcd_wr_n_init (mlcd_wr_n_init),
192 .mlcd_rd_n_init (mlcd_rd_n_init),
193 .mlcd_rst_n_init (mlcd_rst_n_init),
194 .mlcd_rs_init (mlcd_rs_init),
195 .mlcd_bl_init (mlcd_bl_init),
196 .mlcd_data_dir_init (mlcd_data_dir_init),
197 .mlcd_data_out_init (mlcd_data_out_init),
198 .mlcd_data_in_init (mlcd_data_in_init ),
199 .lcd_init_done (lcd_init_done),
200 .lcd_id (lcd_id)
201 );
202
203 endmodule
最后
以上就是温暖机器猫为你收集整理的段码lcd开发设计_正点原子开拓者 Nios II资料连载第十三章彩条LCD显示实验(一)...的全部内容,希望文章能够帮你解决段码lcd开发设计_正点原子开拓者 Nios II资料连载第十三章彩条LCD显示实验(一)...所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复