6. 基于sdram的tft_lcd图像显示

在上面章节,我们将串口RS232、SDRAM控制器和VGA驱动控制、HDMI驱动控制相结合,实现了串口发送较大图片的VGA、HDMI显示,在本章节,我们使用TFT_LCD实现串口较大图片的TFT_LCD显示。

6.1. 理论学习

有关本章节涉及串口RS232、SDRAM读写控制器和TFT的相关理论知识,我们在前面章节已经做过详细讲解。读者若有忘记请回顾查阅,在此不再做过多讲解。

6.2. 实战演练

6.2.1. 实验目标

在PC机上使用串口助手助手发送一幅分辨率为480*272的图片数据给FPGA,FPGA以外接SDRAM做缓存,将接收到的图片数据通过TFT显示屏显示出来。

6.2.2. 硬件资源

详见“TFT_LCD显示器驱动设计与验证”、“串口RS232”、“SDRAM读写控制器的设计与验证”章节的“硬件资源”介绍。

6.3. 程序设计

6.3.1. 整体框图

SDRAMT002

图 56‑1 SDRAM – TFT图像显示整体框图

由图可知,本实验工程共调用5个模块(sdram_top视为一个模块),顶层模块为uart_sdram_tft_pic模块,内部实例化4个功能子模块,连接各子模块对应信号,外部接收数据读写请求、读写地址和读写数据,输出SDRAM控制信号、地址、数据,以及TFT行场同步信号、时钟信号、使能信号、背光控制 信号和图像数据;顶层模块内部实例化的4个功能子模块分别为 clk_gen、uart_rx、sdram_top和tft_ctrl。各部分功能描述,具体见表格 56‑1。

表格 56‑1 各模块功能描述

模块名称

功能描述

uart_sdram_tft_pic

SDRAM –TFT图像显示顶层模块

clk_gen

时钟生成模块

uart_rx

串口数据接收模块

sdram_top

SDRAM读写控制器

tft_ctrl

TFT_LCD驱动控制

6.3.1.1. 顶层模块

模块框图

本实验工程调用的子功能模块在前面章节均作了详细介绍,读者若有遗忘,可回顾相关章节。这里只介绍一下顶层模块。顶层模块模块框图,具体见图 56‑2;模块输入输出端口功能描述,具体见表格 56‑2。

SDRAMT003

图 56‑2 顶层模块框图

表格 56‑2 输入输出端口功能描述

信号

位宽

类型

功能描述

sys_clk

1Bit

Input

系统时钟,频率50MHz

sys_rst_n

1Bit

Input

复位信号,低有效

rx

1Bit

Input

串口数据接收端口

rgb_tft

16Bit

Output

TFT_LCD显示图像信息

hsync

1Bit

Output

行同步信号

vsync

1Bit

Output

场同步信号

tft_clk

1Bit

Output

TFT像素时钟

tft_de

1Bit

Output

TFT数据使能

tft_bl

1Bit

Output

TFT背光信号

sdram_clk

1Bit

Output

SDRAM写时钟

sdram_cke

1Bit

Output

SDRAM时钟有效信号

sdram_cs_n

1Bit

Output

SDRAM片选信号

sdram_ras_n

1Bit

Output

SDRAM行选通信号

sdram_cas_n

1Bit

Output

SDRAM列选通信号

sdram_we_n

1Bit

Output

SDRAM写使能信号

sdram_ba

2Bit

Output

SDRAM逻辑Bank地址

sdram_addr

13Bit

Output

SDRAM地址总线

sdram_dqm

2Bit

Output

SDRAM数据掩码

sdram_dq

16Bit

Output

SDRAM数据总线

代码编写

顶层模块参考代码,具体见代码清单 56‑1。

代码清单 56‑1 顶层模块参考代码(uart_sdram_tft_pic.v)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
module uart_sdram_tft_pic
(
input wire sys_clk , //系统时钟,50MHz
input wire sys_rst_n , //复位信号
input wire rx , //串口接收

output wire [15:0] rgb_tft , //TFT显示数据
output wire hsync , //TFT行同步信号
output wire vsync , //TFT场同步信号
output wire tft_clk , //TFT像素时钟
output wire tft_de , //TFT数据使能
output wire tft_bl , //TFT背光信号

output wire sdram_clk , //SDRAM时钟
output wire sdram_cke , //SDRAM时钟使能
output wire sdram_cs_n , //SDRAM片选
output wire sdram_cas_n , //SDRAM列选通
output wire sdram_ras_n , //SDRAM行选通
output wire sdram_we_n , //SDRAM写使能
output wire [1:0] sdram_ba , //SDRAM Bank地址
output wire [12:0] sdram_addr , //SDRAM地址总线
output wire [1:0] sdram_dqm , //SDRAM数据掩码
inout wire [15:0] sdram_dq //SDRAM数据总线
);

////
//\* Parameter and Internal Signal \//
////
//parameter define
parameter H_PIXEL = 24'd480 ; //水平方向像素个数,用于设置SDRAM缓存大小
parameter V_PIXEL = 24'd272 ; //垂直方向像素个数,用于设置SDRAM缓存大小
parameter UART_BPS = 20'd115200 , //比特率
CLK_FREQ = 26'd50_000_000 ; //时钟频率

// wire define
//uart_rx
wire [7:0] rx_data ; //拼接后的8位图像数据
wire rx_flag ; //数据标志信号
//vga_ctrl
wire data_req ; //TFT数据请求信号
wire [15:0] data_in ; //TFT图像数据

//clk_gen
wire clk_9m ;
wire clk_50m ;
wire clk_100m ;
wire clk_100m_shift ; //pll产生时钟
wire locked ; //pll锁定信号
wire rst_n ; //复位信号

////
//\* Main Code \//
////

//rst_n:复位信号
assign rst_n = sys_rst_n & locked;

//------------- clk_gen_inst -------------
clk_gen clk_gen_inst (
.inclk0 (sys_clk ),
.areset (~sys_rst_n ),
.c0 (clk_9m ),
.c1 (clk_50m ),
.c2 (clk_100m ),
.c3 (clk_100m_shift ),
.locked (locked )
);

//------------- uart_rx_inst -------------
uart_rx
#(
.UART_BPS (UART_BPS ), //串口波特率
.CLK_FREQ (CLK_FREQ ) //时钟频率
)
uart_rx_inst
(
.sys_clk (clk_50m ), //input sys_clk
.sys_rst_n (rst_n ), //input sys_rst_n
.rx (rx ), //input rx

.po_data (rx_data ), //output [7:0] rx_data
.po_flag (rx_flag ) //output rx_flag
);

//------------- tft_ctrl_inst -------------
tft_ctrl tft_ctrl_inst(
.tft_clk_9m (clk_9m ), //输入时钟,频率9MHz
.sys_rst_n (rst_n ), //系统复位,低电平有效
.pix_data ({data_in[7:5],2'b0,data_in[4:2],3'b0,data_in[1:0],3'b0} ), //待显示数据

.pix_data_req(data_req ), //TFT图像数据
.rgb_tft (rgb_tft ), //TFT显示数据
.hsync (hsync ), //TFT行同步信号
.vsync (vsync ), //TFT场同步信号
.tft_clk (tft_clk ), //TFT像素时钟
.tft_de (tft_de ), //TFT数据使能
.tft_bl (tft_bl ) //TFT背光信号

);

//------------- sdram_top_inst -------------
sdram_top sdram_top_inst
(
.sys_clk (clk_100m ), //sdram 控制器参考时钟
.clk_out (clk_100m_shift ), //用于输出的相位偏移时钟
.sys_rst_n (rst_n ), //系统复位
//用户写端口
.wr_fifo_wr_clk (clk_50m ), //写端口FIFO: 写时钟
.wr_fifo_wr_req (rx_flag ), //写端口FIFO: 写使能
.wr_fifo_wr_data ({8'b0,rx_data} ), //写端口FIFO: 写数据
.sdram_wr_b_addr (24'd0 ), //写SDRAM的起始地址
.sdram_wr_e_addr (H_PIXEL*V_PIXEL), //写SDRAM的结束地址
.wr_burst_len (10'd512 ), //写SDRAM时的数据突发长度
.wr_rst (~rst_n ), //写复位
//用户读端口
.rd_fifo_rd_clk (clk_9m ), //读端口FIFO: 读时钟
.rd_fifo_rd_req (data_req ), //读端口FIFO: 读使能
.rd_fifo_rd_data (data_in ), //读端口FIFO: 读数据
.sdram_rd_b_addr (24'd0 ), //读SDRAM的起始地址
.sdram_rd_e_addr (H_PIXEL*V_PIXEL), //读SDRAM的结束地址
.rd_burst_len (10'd512 ), //从SDRAM中读数据时的突发长度
.rd_rst ( ), //读复位
.rd_fifo_num ( ), //读fifo中的数据量
//用户控制端口
.read_valid (1'b1 ), //SDRAM 读使能
.init_end ( ), //SDRAM 初始化完成标志
//SDRAM 芯片接口
.sdram_clk (sdram_clk ), //SDRAM 芯片时钟
.sdram_cke (sdram_cke ), //SDRAM 时钟有效
.sdram_cs_n (sdram_cs_n ), //SDRAM 片选
.sdram_ras_n (sdram_ras_n ), //SDRAM 行有效
.sdram_cas_n (sdram_cas_n ), //SDRAM 列有效
.sdram_we_n (sdram_we_n ), //SDRAM 写有效
.sdram_ba (sdram_ba ), //SDRAM Bank地址
.sdram_addr (sdram_addr ), //SDRAM 行/列地址
.sdram_dq (sdram_dq ), //SDRAM 数据
.sdram_dqm (sdram_dqm ) //SDRAM 数据掩码
);

endmodule

6.3.1.2. RTL视图

至此实验工程基本完成,在Quartus中对代码进行编译,编译若有错误,请读者根据错误提示信息作出更改,直至编译通过,编译通过后查看RTL视图,与顶层模块框图对比,两者一致,各信号连接正确。RTL视图,具体见图 56‑3。

SDRAMT004

图 56‑3 RTL视图

6.4. 上板调试

6.4.1. 引脚约束

仿真验证通过后,准备上板验证,上板验证之前先要进行引脚约束。工程中各输入输出信号与开发板引脚对应关系如表格 56‑3所示。

表格 56‑3 引脚分配表

信号名

信号类型

对应引脚

备注

sys_clk

Input

E1

时钟

sys_rst_n

Input

M15

复位

rx

Input

N6

串口接受数据

sdram_clk

Output

R4

SDRAM芯片时钟

sdram_cke

Output

R9

SDRAM时钟有效信号

sdram_cs_n

Output

R12

SDRAM片选信号

sdram_cas_n

Output

R10

SDRAM列地址选通脉冲

sdram_ras_n

Output

R11

SDRAM行地址选通脉冲

sdram_we_n

Output

L9

SDRAM写允许位

sdram_ba[0]

Output

R13

SDRAM的L-Bank地址线

sdram_ba[1]

Output

R14

SDRAM的L-Bank地址线

sdram_addr[0]

Output

P11

SDRAM地址总线

sdram_addr[1]

Output

P14

SDRAM地址总线

sdram_addr[2]

Output

N9

SDRAM地址总线

sdram_addr[3]

Output

N11

SDRAM地址总线

sdram_addr[4]

Output

T14

SDRAM地址总线

sdram_addr[5]

Output

T13

SDRAM地址总线

sdram_addr[6]

Output

T12

SDRAM地址总线

sdram_addr[7]

Output

T11

SDRAM地址总线

sdram_addr[8]

Output

T10

SDRAM地址总线

sdram_addr[9]

Output

P9

SDRAM地址总线

sdram_addr[10]

Output

T15

SDRAM地址总线

sdram_addr[11]

Output

N12

SDRAM地址总线

sdram_addr[12]

Output

M11

SDRAM地址总线

sdram_dqm[0]

Output

M10

SDRAM数据掩码

sdram_dqm[1]

Output

M9

SDRAM数据掩码

sdram_dq[0]

Output

R3

SDRAM数据总线

sdram_dq[1]

Output

T9

SDRAM数据总线

sdram_dq[2]

Output

R5

SDRAM数据总线

sdram_dq[3]

Output

R6

SDRAM数据总线

sdram_dq[4]

Output

R7

SDRAM数据总线

sdram_dq[5]

Output

M8

SDRAM数据总线

sdram_dq[6]

Output

R8

SDRAM数据总线

sdram_dq[7]

Output

N8

SDRAM数据总线

sdram_dq[8]

Output

P8

SDRAM数据总线

sdram_dq[9]

Output

T8

SDRAM数据总线

sdram_dq[10]

Output

T7

SDRAM数据总线

sdram_dq[11]

Output

T6

SDRAM数据总线

sdram_dq[12]

Output

T5

SDRAM数据总线

sdram_dq[13]

Output

T4

SDRAM数据总线

sdram_dq[14]

Output

T3

SDRAM数据总线

sdram_dq[15]

Output

T2

SDRAM数据总线

tft_clk

Output

L2

时钟信号

tft_de

Output

K1

使能信号

tft_bl

Output

L3

背光信号

hsync

Output

L1

行同步信号

vsync

Output

K2

场同步信号

rgb_tft [15]

Output

G1

RGB色彩信息(红)

rgb_tft [14]

Output

F5

RGB色彩信息(红)

rgb_tft [13]

Output

F3

RGB色彩信息(红)

rgb_tft [12]

Output

F2

RGB色彩信息(红)

rgb_tft [11]

Output

F1

RGB色彩信息(红)

rgb_tft [10]

Output

E5

RGB色彩信息(绿)

rgb_tft [9]

Output

D4

RGB色彩信息(绿)

rgb_tft [8]

Output

J6

RGB色彩信息(绿)

rgb_tft [7]

Output

K6

RGB色彩信息(绿)

rgb_tft [6]

Output

L6

RGB色彩信息(绿)

rgb_tft [5]

Output

J2

RGB色彩信息(绿)

rgb_tft [4]

Output

J1

RGB色彩信息(蓝)

rgb_tft [3]

Output

L4

RGB色彩信息(蓝)

rgb_tft [2]

Output

K5

RGB色彩信息(蓝)

rgb_tft [1]

Output

G5

RGB色彩信息(蓝)

rgb_tft [0]

Output

G2

RGB色彩信息(蓝)

下面进行管脚分配,管脚的分配方法在前面章节已有所讲解,在此就不再过多叙述,管脚的分配如下图 56‑4、图 56‑5所示。

SDRAMT005

图 56‑4 管脚分配

SDRAMT006

图 56‑5 管脚分配

6.4.1.1. 结果验证

如图 56‑6所示,开发板连接12V直流电源、USB-Blaster下载器JTAG端口、USB数据线、跳帽以及TFT_LCD液晶屏。线路正确连接后,打开开关为板卡上电。

SDRAMT007

图 56‑6 程序下载连线图

如图 56‑7所示,使用“Programmer”为开发板下载程序。

SDRAMT008

图 56‑7 程序下载图

程序下载完成后,TFT_LCD屏幕显示随机彩条,如图 56‑8所示;使用串口助手向开发板发送图片数据,TFT_LCD显示屏上逐行扫描出待显示图像,如图 56‑9、图 56‑10所示;扫描完毕后,TFT_LCD显示器显示完整图像,如图 56‑11所示。

SDRAMT009

图 56‑8 随机彩条

SDRAMT010

图 56‑9 串口发送图片数据

SDRAMT011

图 56‑10 TFT_LCD扫描显示图片

SDRAMT012

图 56‑11 TFT_LCD显示完整图片

6.5. 章末总结

本章节使用SDRAM做缓存,实现较大图片的VGA显示 ,对于SDRAM的相关知识,读者要做到切实掌握,灵活运用。