暂时放下FPGA的学习,临别放上自己的文档,以作纪念
这份文档是基于周立功公司的EasyFPGA030开发板的。研究FPGA也有一段时间了,由于自己资质愚笨,目前只能做到这样的水平,请各位兄弟不要见笑啦。
我所做的工作就是在这块简单的开发板上扩展LCD1602A,并用Verilog代码实现字符显示的功能。
对于高手来说这些是微不足道的,但是我希望自己的工作能帮入门的初学者。
放上文档预览一下吧:
http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_468006.jpg
(原文件名: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 iDATA;
input iRS,iStart;
input iCLK,iRST_N;
output reg oDone;
// LCD Interface
output LCD_DATA;
output reg LCD_EN;
output LCD_RW;
output LCD_RS;
// Internal Register
reg Cont;
reg 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 LCD_DATA;
output LCD_RW,LCD_EN,LCD_RS;
// Internal Wires/Registers
reg LUT_INDEX;
reg LUT_DATA;
reg mLCD_ST;
reg mDLY;
reg mLCD_Start;
reg 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;
mLCD_RS <= LUT_DATA;
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 呵呵,为什么要放下FPGA呢 是呀,好东西的啊,不要放掉! 【1楼】 bad_fpga
【2楼】 leafing 叶子
之所以打算放下FPGA的学习是因为感觉到自己目前的水平还只是把它当单片机来用,不能发挥FPGA的强大功能。
而且,目前我的专业基础还不够扎实,打算先学好基础再考虑是否重回这条道路 这不是DE2板子的实例嘛!呵呵 怎么还成周立功的了
页:
[1]