搜索
bottom↓
回复: 4

暂时放下FPGA的学习,临别放上自己的文档,以作纪念

[复制链接]

出0入0汤圆

发表于 2009-8-6 15:45:29 | 显示全部楼层 |阅读模式
这份文档是基于周立功公司的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周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2009-8-6 16:50:21 | 显示全部楼层
呵呵,为什么要放下FPGA呢

出0入0汤圆

发表于 2009-8-6 17:06:44 | 显示全部楼层
是呀,好东西的啊,不要放掉!

出0入0汤圆

 楼主| 发表于 2009-8-6 18:51:41 | 显示全部楼层
【1楼】 bad_fpga
【2楼】 leafing 叶子

之所以打算放下FPGA的学习是因为感觉到自己目前的水平还只是把它当单片机来用,不能发挥FPGA的强大功能。
而且,目前我的专业基础还不够扎实,打算先学好基础再考虑是否重回这条道路

出0入0汤圆

发表于 2009-8-17 16:25:29 | 显示全部楼层
这不是DE2板子的实例嘛!呵呵 怎么还成周立功的了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-1 07:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表