本文为明德扬原创文章,转载请注明出处!
1.1 总体设计
1.1.1 概述
液晶显示器是一-种通过液晶和色彩过滤器过滤光源,在平面面板上产生图像的数字显示器。LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置薄膜晶体管,.上基板玻璃上设置彩色滤光片,通过薄膜晶体管上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。与传统的阴极射线管相比,LCD具有占用空间小,低功耗,低辐射,无闪烁,降低视觉疲劳等优点。现在LCD已渐替代CRT成为主流,价格也已经下降了很多,并已充分的普及。
本设计的主要任务是基于FPGA的LCD显示控制器设计,兼顾程序的易用性,方便此后模块的移植和应用。采用VHDL硬件描述语言在QUARTUS II软件平台上实现FPGA对LCD的控制,在LCD模块上实现任意彩色图片的显示,与此同时还须实现实时刷新数据的功能。这将有助于采用FPGA的系列产品的开发,特别是需要用到LCD而采用FPGA的产品的开发。不但缩短了FPGA的开发周期,也使更多采用FPGA设计的产品上出现LCD,增加了人机之间的交互性。
1.1.2 设计目标
此设计通过fpga给lcd发送图片信息,然后直接在LCD显示矩形动画,矩形的宽从2变化到600,矩形的高从2变化到400
1.1.3信号列表
信号名
| 接口方向 | 定义 |
clk_50m | 输入 | 系统时钟 |
rst_n | 输入 | 低电平复位信号 |
lcd_hsync | 输出 | 行同步信号 |
lcd_vsync | 输出 | 场同步信号 |
lcd_de | 输出 | 行和场同时显示时序段
有效显示数据段信号 |
lcd_rgb | 输出 | 显示颜色RGB
[23:16]:表示的是R[7:0]
[15:8]:表示的是G[7:0]
[7:0]:表示的是B[7:0] |
lcd_dclk | 输出 | 像素时钟信号 |
1.1.4 设计思路
设计行显示时序段和场显示时序段,来确定矩形边框的宽度,根据各种颜色的数值来确定lcd显示屏显示出的边框颜色
行时钟计数器cnt_hys:用来计算行同步信号的帧长,加一条件是1,结束条件为数到1056个像素就结束
场时钟计数器cnt_vys:用来计算场同步信号的帧长,加一条件是场信号每数到1056个像素(即为一行结束的时刻),结束条件为数到525行就结束
1.1.5参考代码
a.
module mdyLcdDispDynaRect(
b.
c.
clk_50m ,
d.
e.
rst_n ,
f.
g.
h.
i.
lcd_hsync ,
j.
k.
lcd_vsync ,
l.
m.
lcd_de ,
n.
o.
p.
q.
r.
s.
lcd_rgb ,
t.
u.
lcd_dclk
v.
w.
x.
y.
);
z.
aa.
ab.
ac.
input clk_50m ;
ad.
ae.
input rst_n ;
af.
ag.
output lcd_hsync ;
ah.
ai.
output lcd_vsync ;
aj.
ak.
output lcd_de ;
al.
am.
an.
ao.
output [23:0] lcd_rgb ;
ap.
aq.
output lcd_dclk ;
ar.
as.
at.
au.
av.
aw.
reg [30:0] h ;
ax.
ay.
reg [30:0] v ;
az.
ba.
bb.
bc.
reg lcd_hsync ;
bd.
be.
reg lcd_vsync ;
bf.
bg.
bh.
bi.
reg [23:0] lcd_rgb ;
bj.
bk.
bl.
bm.
bn.
bo.
parameter LINE_PR = 1056 ;
bp.
bq.
parameter FRAME_PER = 525 ;
br.
bs.
bt.
bu.
bv.
bw.
parameter H_SYNC = 20 ;
bx.
by.
parameter V_SYNC = 10 ;
bz.
ca.
cb.
cc.
parameter HDE_START = 46 ;
cd.
ce.
parameter HDE_END = 846 ;
cf.
cg.
parameter VDE_START = 23 ;
ch.
ci.
parameter VDE_END = 503 ;
cj.
ck.
cl.
cm.
cn.
co.
cp.
cq.
reg [12:0] cnt_hsy ;
cr.
cs.
reg [12:0] cnt_vsy ;
ct.
cu.
reg hsync_de ;
cv.
cw.
reg vsync_de ;
cx.
cy.
cz.
da.
wire display_area ;
db.
dc.
wire e_area ;
dd.
de.
wire add_cnt_hsy ;
df.
dg.
wire end_cnt_hsy ;
dh.
di.
wire add_cnt_vsy ;
dj.
dk.
wire end_cnt_vsy ;
dl.
dm.
reg [ 7:0] cnt0 ;
dn.
do.
wire add_cnt0 ;
dp.
dq.
wire end_cnt0 ;
dr.
ds.
reg [15:0] cnt1 ;
dt.
du.
wire add_cnt1 ;
dv.
dw.
wire end_cnt1 ;
dx.
dy.
dz.
ea.
eb.
ec.
assign clk = clk_50m ;
ed.
ee.
assign lcd_dclk = ~ clk_50m ;
ef.
eg.
assign lcd_de = hsync_de & vsync_de ;
eh.
ei.
ej.
ek.
el.
em.
en.
eo.
ep.
eq.
always @ (posedge clk or negedge rst_n)begin
er.
es.
if(!rst_n)begin
et.
eu.
cnt_hsy <= 0;
ev.
ew.
end
ex.
ey.
else if(add_cnt_hsy)begin
ez.
fa.
if(end_cnt_hsy)
fb.
fc.
cnt_hsy <= 0;
fd.
fe.
else
ff.
fg.
cnt_hsy <= cnt_hsy + 1;
fh.
fi.
end
fj.
fk.
end
fl.
fm.
fn.
fo.
assign add_cnt_hsy = 1;
fp.
fq.
assign end_cnt_hsy = add_cnt_hsy && cnt_hsy == LINE_PR -1;
fr.
fs.
ft.
fu.
fv.
fw.
always @ (posedge clk or negedge rst_n)begin
fx.
fy.
if(!rst_n)begin
fz.
ga.
cnt_vsy <= 0;
gb.
gc.
end
gd.
ge.
else if(add_cnt_vsy)begin
gf.
gg.
if(end_cnt_vsy)
gh.
gi.
cnt_vsy <= 0;
gj.
gk.
else
gl.
gm.
cnt_vsy <= cnt_vsy + 1;
gn.
go.
end
gp.
gq.
end
gr.
gs.
gt.
gu.
assign add_cnt_vsy = end_cnt_hsy;
gv.
gw.
assign end_cnt_vsy = add_cnt_vsy && cnt_vsy == FRAME_PER - 1;
gx.
gy.
gz.
ha.
hb.
hc.
always @ (posedge clk or negedge rst_n)begin
hd.
he.
if(!rst_n)begin
hf.
hg.
lcd_hsync <= 1'b0 ;
hh.
hi.
end
hj.
hk.
else if(end_cnt_hsy)begin
hl.
hm.
lcd_hsync <= 1'b0;
hn.
ho.
end
hp.
hq.
else if(add_cnt_hsy && cnt_hsy == H_SYNC-1 )begin
hr.
hs.
lcd_hsync <= 1'b1;
ht.
hu.
end
hv.
hw.
end
hx.
hy.
hz.
ia.
always @ (posedge clk or negedge rst_n)begin
ib.
ic.
if(!rst_n)begin
id.
ie.
hsync_de <= 1'b0;
if.
ig.
end
ih.
ii.
else if(add_cnt_hsy && cnt_hsy == HDE_START-1)begin
ij.
ik.
hsync_de <= 1'b1;
il.
im.
end
in.
io.
else if(add_cnt_hsy && cnt_hsy == HDE_END-1)begin
ip.
iq.
hsync_de <= 1'b0;
ir.
is.
end
it.
iu.
end
iv.
iw.
ix.
iy.
iz.
ja.
always @ (posedge clk or negedge rst_n)begin
jb.
jc.
if(!rst_n)begin
jd.
je.
lcd_vsync <= 1'b0 ;
jf.
jg.
end
jh.
ji.
else if(add_cnt_vsy && cnt_vsy == V_SYNC-1 )begin
jj.
jk.
lcd_vsync <= 1'b1;
jl.
jm.
end
jn.
jo.
else if(end_cnt_vsy)begin
jp.
jq.
lcd_vsync <= 1'b0;
jr.
js.
end
jt.
ju.
jv.
jw.
end
jx.
jy.
jz.
ka.
kb.
kc.
always @ (posedge clk or negedge rst_n)begin
kd.
ke.
if(!rst_n)begin
kf.
kg.
vsync_de <= 1'b0;
kh.
ki.
end
kj.
kk.
else if(add_cnt_vsy && cnt_vsy == VDE_START-1)begin
kl.
km.
vsync_de <= 1'b1;
kn.
ko.
end
kp.
kq.
else if(add_cnt_vsy && cnt_vsy ==VDE_END-1)begin
kr.
ks.
vsync_de <= 1'b0;
kt.
ku.
end
kv.
kw.
end
kx.
ky.
kz.
la.
lb.
lc.
assign display_area = hsync_de && vsync_de;
ld.
le.
lf.
lg.
lh.
li.
assign blue_area = (cnt_hsy >= HDE_START + 400-h) && (cnt_hsy<HDE_START+400+h) &&
lj.
lk.
(cnt_vsy >= VDE_START + 240-v) && (cnt_vsy<VDE_START+240+v) ;
ll.
lm.
ln.
lo.
lp.
lq.
lr.
ls.
always @(posedge clk or negedge rst_n)begin
lt.
lu.
if(rst_n==1'b0)begin
lv.
lw.
h<=1;
lx.
ly.
end
lz.
ma.
else if(end_cnt_vsy && h<300)begin
mb.
mc.
h<=h+2;
md.
me.
end
mf.
mg.
end
mh.
mi.
mj.
mk.
always @(posedge clk or negedge rst_n)begin
ml.
mm.
if(rst_n==1'b0)begin
mn.
mo.
v<=1;
mp.
mq.
end
mr.
ms.
else if(end_cnt_vsy && v<200)begin
mt.
mu.
v<=v+1;
mv.
mw.
end
mx.
my.
end
mz.
na.
nb.
nc.
nd.
ne.
always @ (posedge clk or negedge rst_n)begin
nf.
ng.
if(!rst_n)begin
nh.
ni.
lcd_rgb <= 0;
nj.
nk.
end
nl.
nm.
else if(display_area)begin
nn.
no.
if(blue_area)begin
np.
nq.
lcd_rgb <= 24'h00_00_ff ;
nr.
ns.
end
nt.
nu.
else begin
nv.
nw.
lcd_rgb <= 24'hff_ff_ff ;
nx.
ny.
end
nz.
oa.
end
ob.
oc.
else begin
od.
oe.
lcd_rgb <= 0;
of.
og.
end
oh.
oi.
end
oj.
ok.
ol.
om.
on.
oo.
op.
oq.
endmodule
or.
os.
ot.
复制代码
1.2 效果和总结
本案例我们设计了蓝色的矩形,蓝色矩形的场信号是从2行变到400行、行信号是从2个像素变到600个像素;
在这个设计案例中,至简设计法和明德扬计数器模板发挥了至关重要的作用,使我能够快速准确完成设计。希望有兴趣的同学可以运用至简设计法和明德扬模板尝试一下拓展设计哦。
设计教学视频和工程源代码,请到明德扬论坛(www.fpgabbs.cn)学习:http://www.fpgabbs.cn/thread-1156-1-1.html
温馨提示:明德扬2023推出了全新课程——逻辑设计基本功修炼课,降低学习FPGA门槛的同时,增加了学习的趣味性,并组织了考试赢积分活动
http://www.mdy-edu.com/ffkc/415.html
(点击→了解课程详情☝)感兴趣请联系易老师:13112063618(微信同步)