|
这份文档是基于周立功公司的EasyFPGA030开发板的。
研究FPGA也有一段时间了,由于自己资质愚笨,目前只能做到这样的水平,请各位兄弟不要见笑啦。
我所做的工作就是在这块简单的开发板上扩展LCD1602A,并用Verilog代码实现字符显示的功能。
对于高手来说这些是微不足道的,但是我希望自己的工作能帮入门的初学者。
放上文档预览一下吧:
(原文件名:EasyFPGA030 扩展 LCD应用文档1.jpg)
完整的文档下载:
点击此处下载 ourdev_468007.pdf(文件大小:166K) (原文件名:EasyFPGA030扩展LCD1602A应用文档.pdf)
Verilog源代码
源代码是在Altera公司的DE2开发板中的测试程序分离出来的,正因为它不是针对用户使用而编写的,所以当中很少注释说明。(一切版权归Altera公司所有。)
提示:要读懂下面的代码,建议大家首先了解一下1602的读写时序,时序的介绍在Datasheet中会有详细说明。这里由于篇幅有限,就不多赘述了。在关键的地方已经有注释说明了。
//把下面的代码保存为“LCD_Controller.v”文件
module LCD_Controller ( // Host Side
iDATA,iRS,
iStart,oDone,
iCLK,iRST_N,
// LCD Interface
LCD_DATA,
LCD_RW,
LCD_EN,
LCD_RS );
// CLK
parameter CLK_Divide = 16;
// Host Side
input [7:0] iDATA;
input iRS,iStart;
input iCLK,iRST_N;
output reg oDone;
// LCD Interface
output [7:0] LCD_DATA;
output reg LCD_EN;
output LCD_RW;
output LCD_RS;
// Internal Register
reg [4:0] Cont;
reg [1:0] ST;
reg preStart,mStart;
/////////////////////////////////////////////
// Only write to LCD, bypass iRS to LCD_RS
assign LCD_DATA = iDATA;
assign LCD_RW = 1'b0;//由于现在只写不读,所以LCD_RW直接置低电平
assign LCD_RS = iRS;
/////////////////////////////////////////////
always@(posedge iCLK or negedge iRST_N)
begin
if(!iRST_N)//?RST_N???????
begin//???????????????
oDone <= 1'b0;
LCD_EN <= 1'b0;
preStart<= 1'b0;
mStart <= 1'b0;
Cont <= 0;
ST <= 0;
end
else//???????
begin
////// Input Start Detect ///////
preStart<= iStart;
if({preStart,iStart}==2'b01)
begin
mStart <= 1'b1;
oDone <= 1'b0;
end
//////////////////////////////////
if(mStart)
begin
case(ST)
0: ST <= 1; // Wait Setup
1: begin
LCD_EN <= 1'b1;
ST <= 2;
end
2: begin
if(Cont<CLK_Divide)
Cont <= Cont+1;
else
ST <= 3;
end
3: begin
LCD_EN <= 1'b0;
mStart <= 1'b0;
oDone <= 1'b1;
Cont <= 0;
ST <= 0;
end
endcase
end
end
end
endmodule
//把下面的代码保存为“LCD_TEST.v”
module LCD_TEST ( // Host Side
iCLK,iRST_N,
// LCD Side
LCD_DATA,LCD_RW,LCD_EN,LCD_RS );
// Host Side
input iCLK,iRST_N;
// LCD Side
output [7:0] LCD_DATA;
output LCD_RW,LCD_EN,LCD_RS;
// Internal Wires/Registers
reg [5:0] LUT_INDEX;
reg [8:0] LUT_DATA;
reg [5:0] mLCD_ST;
reg [17:0] mDLY;
reg mLCD_Start;
reg [7:0] mLCD_DATA;
reg mLCD_RS;
wire mLCD_Done;
parameter LCD_INTIAL = 0;
parameter LCD_LINE1 = 5;
parameter LCD_CH_LINE = LCD_LINE1+16;
parameter LCD_LINE2 = LCD_LINE1+16+1;
parameter LUT_SIZE = LCD_LINE1+32+1;
always@(posedge iCLK or negedge iRST_N)
begin
if(!iRST_N)
begin
LUT_INDEX <= 0;
mLCD_ST <= 0;
mDLY <= 0;
mLCD_Start <= 0;
mLCD_DATA <= 0;
mLCD_RS <= 0;
end
else
begin
if(LUT_INDEX<LUT_SIZE)
begin
case(mLCD_ST)
0: begin
mLCD_DATA <= LUT_DATA[7:0];
mLCD_RS <= LUT_DATA[8];
mLCD_Start <= 1;
mLCD_ST <= 1;
end
1: begin
if(mLCD_Done)
begin
mLCD_Start <= 0;
mLCD_ST <= 2;
end
end
2: begin
if(mDLY<18'h3FFFE)
mDLY <= mDLY+1;
else
begin
mDLY <= 0;
mLCD_ST <= 3;
end
end
3: begin
LUT_INDEX <= LUT_INDEX+1;
mLCD_ST <= 0;
end
endcase
end
end
end
always
begin
case(LUT_INDEX)
// Initial
LCD_INTIAL+0: LUT_DATA <= 9'h038;//
LCD_INTIAL+1: LUT_DATA <= 9'h00C;
LCD_INTIAL+2: LUT_DATA <= 9'h001;
LCD_INTIAL+3: LUT_DATA <= 9'h006;//
LCD_INTIAL+4: LUT_DATA <= 9'h080;//
/*Line 1,下面开始的都是液晶显示部分的代码,想要更改显示的内容,只需要改动后两位即可,例如9’h120,前面的1表示写的是数据,后面的20表示的是数据内容,20表示为空格键,即为不显示内容,把它改为9’h165即可显示字符e,详细的对应可以看看Datasheet的字符表*/
LCD_LINE1+0: LUT_DATA <= 9'h120; // Welcome to the
LCD_LINE1+1: LUT_DATA <= 9'h157;
LCD_LINE1+2: LUT_DATA <= 9'h165;
LCD_LINE1+3: LUT_DATA <= 9'h16C;
LCD_LINE1+4: LUT_DATA <= 9'h163;
LCD_LINE1+5: LUT_DATA <= 9'h16F;
LCD_LINE1+6: LUT_DATA <= 9'h16D;
LCD_LINE1+7: LUT_DATA <= 9'h165;
LCD_LINE1+8: LUT_DATA <= 9'h120;
LCD_LINE1+9: LUT_DATA <= 9'h174;
LCD_LINE1+10: LUT_DATA <= 9'h16F;
LCD_LINE1+11: LUT_DATA <= 9'h120;
LCD_LINE1+12: LUT_DATA <= 9'h174;
LCD_LINE1+13: LUT_DATA <= 9'h168;
LCD_LINE1+14: LUT_DATA <= 9'h165;
LCD_LINE1+15: LUT_DATA <= 9'h120;
// Change Line
LCD_CH_LINE: LUT_DATA <= 9'h0C0;
// Line 2
LCD_LINE2+0: LUT_DATA <= 9'h141; // Altera DE2 Board
LCD_LINE2+1: LUT_DATA <= 9'h16C;
LCD_LINE2+2: LUT_DATA <= 9'h174;
LCD_LINE2+3: LUT_DATA <= 9'h165;
LCD_LINE2+4: LUT_DATA <= 9'h172;
LCD_LINE2+5: LUT_DATA <= 9'h161;
LCD_LINE2+6: LUT_DATA <= 9'h120;
LCD_LINE2+7: LUT_DATA <= 9'h144;
LCD_LINE2+8: LUT_DATA <= 9'h145;
LCD_LINE2+9: LUT_DATA <= 9'h132;
LCD_LINE2+10: LUT_DATA <= 9'h120;
LCD_LINE2+11: LUT_DATA <= 9'h142;
LCD_LINE2+12: LUT_DATA <= 9'h16F;
LCD_LINE2+13: LUT_DATA <= 9'h161;
LCD_LINE2+14: LUT_DATA <= 9'h172;
LCD_LINE2+15: LUT_DATA <= 9'h164;
default: LUT_DATA <= 9'hxxx;
endcase
end
LCD_Controller u0 ( // Host Side
.iDATA(mLCD_DATA),
.iRS(mLCD_RS),
.iStart(mLCD_Start),
.oDone(mLCD_Done),
.iCLK(iCLK),
.iRST_N(iRST_N),
// LCD Interface
.LCD_DATA(LCD_DATA),
.LCD_RW(LCD_RW),
.LCD_EN(LCD_EN),
.LCD_RS(LCD_RS) );
endmodule |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|