段码lcd开发设计_正点原子开拓者 Nios II资料连载第十三章彩条LCD显示实验(一)...

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

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

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

939aa7d772e932efd77903c535e38dfa.png

第十三章通过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核的配置界面:

da5eabcbe0f6b04ab92f1ab21f73dac5.png

图 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核留给用户的信号端口,如下图所示:

04c3139d0a07ff2c37c8c866d37a27f9.png

图 13.1.2 留给用户的信号端口

图中紫色的信号是留给用户的信号端口,其中burstcount、writedata、address、write、

read、byteenable、debugacess信号是用户可以操作的主端口信号,waitrequest、readdata、

readdatavalid信号是从机输出的不可操作信号。我们将在下表对这些信号的作用进行说明。

图 13.1.3 信号说明

f4475bf28747b04c809269d10c481178.png
a105b40e2ba83ffc13e14ff363461961.png
9d0f7769eb2af35a246fac31e6ffc788.png
f68ccdc7bfe559a8042f9bbf23d48f0b.png

实际的配置如下图所示:

b2f1226a07cdd7d08756944daa07f88a.png

图 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屏幕。

硬件设计

本章实验任务的系统框图如下所示:

b00b2a3b59bb9e54420892f38298c77c.png

图 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运行所

需的代码和处理数据;

顶层模块的原理图如下图所示:

b8403e2cfdefc1aca86798276dcdd3bf.png

图 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核。

34838c0f109130936fcaa9334897169c.png

图 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值