FPGA实验三 液晶屏的显示设计说明.docx
《FPGA实验三 液晶屏的显示设计说明.docx》由会员分享,可在线阅读,更多相关《FPGA实验三 液晶屏的显示设计说明.docx(46页珍藏版)》请在冰豆网上搜索。
FPGA实验三液晶屏的显示设计说明
专业:
__电子信息工程__
姓名:
_____陈华杰_____
学号:
______
日期:
___4月4日___
地点:
应电楼303桌号2组
实验报告
课程名称:
_____FPGA实验______指导老师:
__竺红卫/陈宏__成绩:
__________________
实验名称:
____液晶屏的显示设计______实验类型:
_FPGA实验_同组学生姓名:
__
一、实验目的
1.熟悉实验板上液晶屏的工作原理;
2.熟悉驱动电路的源代码。
二、实验装置
1.电脑一台;
2.实验板一块;
3.实验板电源一只;
4.实验板连接电脑的下载线一根。
三、实验原理
实验板显著的特征是2线16字符液晶显示器LCD。
尽管LCD支持8位的数据接口,为了与其它的XILINX的开发板保持兼容并且尽可能减少针脚数,FPGA仅通过4位的数据接口线控制LCD,LCD通过使用ASCII标准和自定义字符可以有效地显示多种信息。
但是,这些显示速度并不是很快。
每半秒扫描一次以测试实际清晰度的界限。
与50MHz时钟频率相比,这样的显示速度是慢的。
PicoBlaze处理器可以有效地控制显示时间和显示内容。
字符LCD的供电电压是+5V。
FPGA的I/O口信号的电压是3.3V。
但是,FPGA的输出电平是通过LCD来识别是有效的低电平还是高电平。
LCD控制器接收5VTTL信号电平,FPGA输出3.3V的LCMOS以满足5VTTL电压要求。
数据线上的390欧串联电阻,当LCD驱动一个逻辑高电平时,其用来防止了FPGA和SrtataFlsahI/O管脚的超负载。
当LCD_RW为高时,LCD驱动数据线。
在绝大多数应用中,LCD作为只读外围设备,几乎没有从显示器读数据。
四、操作方法和实验步骤
对于程序的各个步骤,如新建项目、新建VerilogHDL、新建.ucf文件、Synthesize、ImplementDesign、GenerateProgrammingFile、ConfigureTargetDevice等等,在实验一中已经展示过,每一次实验的基本操作步骤都是差不多的,故这里不再重复阐述。
本次实验总共需要做三份程序并观察现象:
1)例程
2)设计按键拨动时显示小时、分钟和秒,中间分别空一格。
3)按键拨动开始显示,10秒钟显示结束,结束时LCD上显示ABCDEF,同时八只LED灯亮。
五、实验源代码和现象
1)例程
UCF文件如下:
NET"CLK_50MHZ"LOC="C9";
NET"LCD_D<0>"LOC="R15";
NET"LCD_D<1>"LOC="R16";
NET"LCD_D<2>"LOC="P17";
NET"LCD_D<3>"LOC="M15";
NET"LCD_E"LOC="M18";
NET"LCD_RS"LOC="L18";
NET"LCD_RW"LOC="L17";
源代码如下:
modulelcd_write_number_test
(
inputCLK_50MHZ,
outputLCD_E,
outputLCD_RS,
outputLCD_RW,
output[3:
0]LCD_D
);
wireif_ready;
regif_write;
reg[31:
0]if_data;
reg[1:
0]state;
reg[31:
0]cntr;
parameterIDLE=2'b00,
IF_WRITE_1=2'b01,
SET_IF_WRITE_0=2'b10,
WAIT=2'b11;
//InstantiatetheUnitUnderTest(UUT)
lcd_write_numberuut
(
.CLK_50MHZ(CLK_50MHZ),
.LCD_E(LCD_E),
.LCD_RS(LCD_RS),
.LCD_RW(LCD_RW),
.LCD_D(LCD_D),
.if_data(if_data),
.if_write(if_write),
.if_ready(if_ready)
);
initialbegin
if_data<=32'habba0123;
state<=IDLE;
if_write<=1'b0;
cntr<=32'b0;
end
always@(posedgeCLK_50MHZ)begin
case(state)
IDLE:
if(if_ready)begin
if_data<=if_data+1'b1;
if_write<=1'b1;
state<=IF_WRITE_1;
cntr<=32'b0;
end
IF_WRITE_1:
//thisstatetokeepif_writeupfor2cycles
state<=SET_IF_WRITE_0;
SET_IF_WRITE_0:
//setif_write0andstartthecounter
begin
if_write<=1'b0;
state<=WAIT;
cntr<=32'b0;
end
WAIT:
if(cntr<25000000)//waitfor0.5seconds
cntr<=cntr+32'b1;
else
state<=IDLE;
endcase
end
endmodule
`timescale1ns/1ps
modulelcd_write_number
(
inputCLK_50MHZ,
outputLCD_E,
outputLCD_RS,
outputLCD_RW,
output[3:
0]LCD_D,
input[31:
0]if_data,
inputif_write,
outputif_ready
);
reg[7:
0]disp_data;
regdisp_rs;
reg[31:
0]disp_delay;
regdisp_write;
wiredisp_ready;
regdisp_b8;
reg[7:
0]char;
reg[1:
0]state;
reg[31:
0]number;
reginit_done;
regrunning;
reg[4:
0]shift_cntr;
regif_ready_r;
assignif_ready=if_ready_r;
lcd_displaydisplay
(.clk(CLK_50MHZ),
.rst(1'b0),
.lcd_e(LCD_E),
.lcd_rw(LCD_RW),
.lcd_rs(LCD_RS),
.lcd_d(LCD_D),
.if_data(disp_data),
.if_rs(disp_rs),
.if_delay(disp_delay),
.if_write(disp_write),
.if_ready(disp_ready),
.if_8bit(disp_b8)
);
parameterNB_CHARS=8'd12;
parameterSTART=2'b00,
WAIT_WRITE_0=2'b01,
WRITE_1=2'b10,
WAIT_WRITE_1=2'b11;
initialbegin
state<=2'b00;
char<=8'b0;
init_done<=1'b0;
if_ready_r<=1'b0;
shift_cntr<=5'b0;
end
always@(posedgeCLK_50MHZ)begin
if(init_done&&char>8'd16)begin
if(disp_ready)
if_ready_r<=1'b1;
if(if_write)begin
char<=4'd8;//resetthedisplay
end
endelseif(char<=8'd16)begin
if_ready_r<=1'b0;
case(state)
START:
if(disp_ready)begin
disp_write<=1'b1;
state<=WAIT_WRITE_0;
end
WAIT_WRITE_0:
state<=WRITE_1;
WRITE_1:
begin
disp_write<=1'b0;
state<=2'b11;
end
WAIT_WRITE_1:
begin
state<=START;
char<=char+8'b1;
end
endcase//case(state)
end//else:
!
if(!
running)
end//always@(posedgeCLK_50MHZ)
always@(negedgeCLK_50MHZ)begin
//thesenextstepsinitializetheLCDdisplay:
case(char)
0:
begin
disp_b8<=1'b0;
disp_data<=8'h30;
disp_delay<=32'd10000000;
disp_rs<=1'b0;
end
1:
disp_data<=8'h30;
2:
begin
disp_data<=8'h30;
disp_delay<=32'd1000000;
end
3:
begin
disp_data<=8'h20;
disp_delay<=32'd20000;
end
4:
begin
disp_b8<=1'b1;
disp_data<=8'h28;
end
5:
disp_data<=8'h06;
6:
disp_data<=8'h0C;
7:
begin
disp_data<=8'h01;
disp_delay<=32'd1000000;
init_done<=1'b1;
shift_cntr<=5'd9;
end
8:
//thisstateprovidesanentrypointtoresetthedisplayandthen
//goontothedefaultstatethatwritesthenumber
begin
disp_rs<=1'b0;
disp_data<=8'h01;
disp_delay<=32'd1000000;
shift_cntr<=5'b0;
number<=if_data;
end
default:
//statemachinetoprinta32-bitnumberout
if(disp_ready&&state==START)begin
if(shift_cntr<5'd8)begin
disp_rs<=1'b1;
disp_delay<=32'd20000;
if(number[31:
28]<4'b1010)
disp_data<=number[31:
28]+8'h30;
else
disp_data<=number[31:
28]+8'h37;
number<=number<<4;
shift_cntr<=shift_cntr+5'b1;
end
end
endcase//case(char)
end//always@(negedgeCLK_50MHZ)
endmodule
`timescale1ns/1ps
modulelcd_display
(inputclk,
inputrst,
outputlcd_e,
outputlcd_rw,
outputlcd_rs,
output[3:
0]lcd_d,
input[7:
0]if_data,
inputif_rs,
input[31:
0]if_delay,
inputif_write,
outputif_ready,
inputif_8bit);
reg[2:
0]state;
reglcdr_e;
reg[3:
0]lcdr_d;
reg[31:
0]wait_cntr;
regready;
reginit_done;
parameterIDLE=3'b000,
WAIT_PULSE_E_0=3'b001,
LOAD_LOWER_NIBBLE=3'b010,
WAIT_PULSE_E_1=3'b011,
WAIT_COMMAND=3'b100;
parameterPULSE_E_DLY=32'd12;
parameterINIT_TIME=32'd20000000;
assignlcd_d=lcdr_d;
assignlcd_rs=if_rs;
assignlcd_rw=1'b0;
assignlcd_e=lcdr_e;
assignif_ready=ready;
initialbegin
state<=IDLE;
ready<=1'b0;
lcdr_e<=1'b0;
init_done<=1'b0;
end
always@(posedgeclk)begin
if(rst)begin
state<=IDLE;
endelseif(!
init_done)begin
if(wait_cntrwait_cntr<=wait_cntr+1;
elsebegin
init_done<=1'b1;
ready<=1'b1;
end
endelsebegin
case(state)
IDLE:
begin
if(if_write)begin
lcdr_e<=1'b1;
lcdr_d<=if_data[7:
4];//uppernibblefirst
ready<=1'b0;
wait_cntr<=32'b0;
state<=WAIT_PULSE_E_0;
end
end
WAIT_PULSE_E_0:
if(wait_cntrwait_cntr<=wait_cntr+1;
endelsebegin
lcdr_e<=1'b0;
wait_cntr<=0;
if(if_8bit)
state<=LOAD_LOWER_NIBBLE;
else
state<=WAIT_COMMAND;
end
LOAD_LOWER_NIBBLE:
if(wait_cntrwait_cntr<=wait_cntr+1;
endelsebegin
wait_cntr<=0;
lcdr_e<=1'b1;
lcdr_d<=if_data[3:
0];//lowernibble
state<=WAIT_PULSE_E_1;
end
WAIT_PULSE_E_1:
if(wait_cntrwait_cntr<=wait_cntr+1;
endelsebegin
lcdr_e<=1'b0;
wait_cntr<=0;
state<=WAIT_COMMAND;
end
WAIT_COMMAND:
if(wait_cntrwait_cntr<=wait_cntr+32'b1;
endelsebegin
wait_cntr<=0;
if(!
if_write)begin
state<=IDLE;
ready<=1'b1;
end
end
endcase//case(state)
end
end
endmodule
共有三个module,它们的包含关系为lcd_write_number_test包含lcd_write_number,lcd_write_number包含lcd_display,下同。
实验现象:
如下图,刚烧录程序完时,LCD前8位依次显示十六进制数“ABBA0123”,然后每过0.5秒,该数值增一,满十六进位。
2)设计按键拨动时显示小时、分钟和秒,中间分别空一格。
UCF文件如下:
NET"CLK_50MHZ"LOC="C9";
NET"LCD_D<0>"LOC="R15";
NET"LCD_D<1>"LOC="R16";
NET"LCD_D<2>"LOC="P17";
NET"LCD_D<3>"LOC="M15";
NET"LCD_E"LOC="M18";
NET"LCD_RS"LOC="L18";
NET"LCD_RW"LOC="L17";
NET"SW1"LOC="L14";
源代码如下:
modulelcd_write_number_test
(
inputSW1,
inputCLK_50MHZ,
outputLCD_E,
outputLCD_RS,
outputLCD_RW,
output[3:
0]LCD_D
);
wireif_ready;
regif_write;
reg[31:
0]if_data;
reg[1:
0]state;
reg[31:
0]cntr;
parameterIDLE=2'b00,
IF_WRITE_1=2'b01,
SET_IF_WRITE_0=2'b10,
WAIT=2'b11;
//InstantiatetheUnitUnderTest(UUT)
lcd_write_numberuut
(
.SW1(SW1),
.CLK_50MHZ(CLK_50MHZ),
.LCD_E(LCD_E),
.LCD_RS(LCD_RS),
.LCD_RW(LCD_RW),
.LCD_D(LCD_D),
.if_data(if_data),
.if_write(if_write),
.if_ready(if_ready)
);
initial
begin
if_data<=32'h19044012;
state<=IDLE;
if_write<=1'b0;
cntr<=32'b0;
end
always@(posedgeCLK_50MHZ)
begin
case(state)
IDLE:
if(if_ready)
begin
if(if_data[31:
0]==32'h23059059)if_data<=32'h0;
elseif(if_data[27:
0]==28'h9059059)if_data<=if_data+32'h6fa6fa7;
elseif(if_data[19:
0]==20'h59059)if_data<=if_data+32'hfa6fa7;
elseif(if_data[15:
0]==16'h9059)if_data<=if_data+32'h6fa7;
elseif(if_data[7:
0]==8'h59)if_data<=if_data+32'hfa7;
elseif(if_data[3:
0]==4'h9)if_data<=if_data+32'h7;
elseif_data<=if_data+1'b1;
if_write<=1'b1;
state<=IF_WRITE_1;
cntr<=32'b0;
end
IF_WRITE_1:
//thisstatetokeepif_writeupfor2cycles
state<=SET_IF_WRITE_0;
SET_IF_WRITE_0:
//setif_write0andstartthecounter
begin
if_write<=1'b0;
state<=WAIT;
cntr<=32'b0;
end
WAIT:
if(cntr<50000000)//waitfor1seconds
cntr<=cntr+32'b1;
else
state<=IDLE;
endcase
end
endmodule
`timescale1ns/1ps
modulelcd_display
(inputclk,
inputrst,
outputlcd_e,
outputlcd_rw,
outputlcd_rs,
output[3:
0]lcd_d,
input[7:
0]if_data,
inputif_rs,
input[31:
0]if_delay,
inputif_write,
outputif_ready,
inputif_8bit);
reg[2:
0]state;
reglcdr_e;
reg[3:
0]lcdr_d;
reg[31:
0]wait_cntr;
regready;
reginit_done;
parameterIDLE=3'b000,
WAIT_PULSE_E_0=3'b001,
LOAD_LOWER_NIBBLE=3'b010,
WAIT_PULSE_E_1=3'b011,
WAIT_COMMAND=3'b100;
parameterPULSE_E_DLY=32'd12;
parameterINIT_TIME=32'd20000000;
assignlcd_d=lcdr_d;
assignlcd_rs=if_rs;
assignlcd_rw=1'b0;
assignlcd_e=lcdr_e;
assignif_ready=ready;
initialbegin
state<=IDLE;
ready<=1'b0;
lcdr_e<=1'b0;
init_done<=1'b0;
end
always@(posedgeclk)begin
if(rst)begin
state<=IDLE;
endelseif(!
init_done)begin
if(wait_cntr