搜索
bottom↓
回复: 24

发一个Verilog写的LCD12864驱动实验代码

[复制链接]

出0入0汤圆

发表于 2010-7-22 11:43:07 | 显示全部楼层 |阅读模式
坛子里有很多单片机驱动LCD12864的代码,但用FPGA来驱动的比较少。
今天做了FPGA驱动LCD12864的实验,把代码发上来,与大家分享。

PS:仿佛这样的任务不适合用FPGA来做。

代码如下:

module LCD12864(
    input CLK,                        //系统时钟输入
    input RST_N,                //系统复位输入
    output reg LCD_RS,                //LCD的寄存器选择输出信号
    output LCD_RW,                //LCD的读、写操作选择输出信号
    output LCD_E,                //LCD使能信号
    output reg [7:0]LCD_D,        //LCD的数据总线(不进行读操作,故为输出)
    output PSB,
    output RST_LCD       
);

reg CLK_LCD;                        //LCD时钟信号
reg [23:0]cnt;

assign PSB = 1;
assign RST_LCD = 1;
// CLK频率为50MHz, 产生LCD时钟信号, 10Hz
always @(posedge CLK or negedge RST_N)
begin
    if (!RST_N)
    begin
        cnt <= 24'b0;
        CLK_LCD <= 0;
    end
    else if(cnt == 2499999)
    begin
        cnt <= 0;
        CLK_LCD <= ~CLK_LCD;
    end
    else
        cnt <= cnt +1'b1;
end

reg        [8:0] state;                                //State Machine code
parameter IDLE                 = 9'b00000000;                //初始状态,下一个状态为CLEAR
parameter SETFUNCTION        = 9'b00000001;                //功能设置:8位数据接口
parameter SETFUNCTION2        = 9'b00000010;               
parameter SWITCHMODE        = 9'b00000100;                //显示开关控制:开显示,光标和闪烁关闭
parameter CLEAR                = 9'b00001000;                //清屏
parameter SETMODE             = 9'b00010000;                //输入方式设置:数据读写操作后,地址自动加一/画面不动
parameter SETDDRAM            = 9'b00100000;                //设置DDRAM的地址:第一行起始为0x80/第二行为0x90
parameter WRITERAM            = 9'b01000000;                //数据写入DDRAM相应的地址
parameter STOP                = 9'b10000000;                //LCD操作完毕,释放其控制

reg flag;                //标志位,LCD操作完毕为0
reg [4:0]char_cnt;               
reg [7:0]data_disp;

assign LCD_RW = 1'b0;                                //没有读操作,R/W信号始终为低电平
assign LCD_E  = (flag == 1)?CLK_LCD:1'b0;        //E信号出现高电平以及下降沿的时刻与LCD时钟相同

always @(posedge CLK_LCD or negedge RST_N)        //只有在写数据操作时,RS信号才为高电平,其余为低电平
begin
    if(!RST_N)
        LCD_RS <= 1'b0;
    else if(state == WRITERAM)
        LCD_RS <= 1'b1;
    else
        LCD_RS <= 1'b0;
end

// State Machine
always @(posedge CLK_LCD or negedge RST_N)
begin
    if(!RST_N)
    begin
        state <= IDLE;
        LCD_D <= 8'bzzzzzzzz;
        char_cnt <= 5'b0;
        flag <= 1'b1;
    end
    else begin
        case(state)
            IDLE:
            begin
            state <= SETFUNCTION;
            LCD_D <= 8'bzzzzzzzz;
        end
        SETFUNCTION:
        begin
            state <= SETFUNCTION2;
            LCD_D <= 8'h30;                // 8-bit 控制界面,基本指令集动作
        end
        SETFUNCTION2:
        begin
            state <= SWITCHMODE;
            LCD_D <= 8'h30;                // 清屏               
        end
        SWITCHMODE:
        begin
            state <= CLEAR;
            LCD_D <= 8'h0c;                // 显示开关:开显示,光标和闪烁关闭
        end
        CLEAR:
        begin
            state <= SETMODE;
            LCD_D <= 8'h01;
        end
        SETMODE:
        begin
            state <= SETDDRAM;
            LCD_D <= 8'h06;                // 输入方式设置: 数据读写后,地址自动加1,画面不动
        end
        SETDDRAM:
        begin
            state <= WRITERAM;
            if(char_cnt == 0)                //如果显示的是第一个字符,则设置第一行的首字符地址
            begin
                LCD_D <= 8'h80;                //Line1
            end
            else                        //第二次设置时,是设置第二行的首字符地址
            begin
                LCD_D <= 8'h90;                //Line2
            end
        end
        WRITERAM:
        begin
            if(char_cnt <= 11)
            begin
                char_cnt <= char_cnt + 1'b1;
                LCD_D <= data_disp;
                if( char_cnt == 11 )
                    state <= SETDDRAM;
                else
                    state <= WRITERAM;
            end
            else if( char_cnt >= 12 && char_cnt <= 25)
            begin
                LCD_D <= data_disp;
                if(char_cnt == 25)
                begin
                    state <= STOP;
                    char_cnt <= 5'b0;
                    flag <= 1'b0;
                end
                else
                begin
                    state <= WRITERAM;
                    char_cnt <= char_cnt + 1'b1;
                end
            end
        end
        STOP: state <= STOP;
        default: state <= IDLE;
    endcase
end
end

always @(char_cnt)                        //输出的字符
begin
    case (char_cnt)
        6'd0: data_disp = "H";        //        第
        6'd1: data_disp = "e";        //        一
        6'd2: data_disp = "l";        //        行
        6'd3: data_disp = "l";        //        的
        6'd4: data_disp = "o";        //        显
        6'd5: data_disp = ",";        //        示
        6'd6: data_disp = "w";        //        内
        6'd7: data_disp = "o";        //        容
        6'd8: data_disp = "r";        //
        6'd9: data_disp = "l";        //        字符串变量形式
        6'd10: data_disp = "d";        //
        6'd11: data_disp ="!";        //               

        6'd12: data_disp = "w";        //        第二行的显示内容
        6'd13: data_disp = "w";        //
        6'd14: data_disp = "w";
        6'd15: data_disp = ".";       
        6'd16: data_disp = "o";
        6'd17: data_disp = "u";
        6'd18: data_disp = "r";
        6'd19: data_disp = "d";
        6'd20: data_disp = "e";
        6'd21: data_disp = "v";
        6'd22: data_disp = ".";
        6'd23: data_disp = "c";
        6'd24: data_disp = "n";
        default :   data_disp =  8'd32;
    endcase
end

endmodule

阿莫论坛20周年了!感谢大家的支持与爱护!!

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

出0入0汤圆

发表于 2010-7-22 11:54:29 | 显示全部楼层
mark

出0入90汤圆

发表于 2010-7-22 11:56:35 | 显示全部楼层
学习了!!!

出0入0汤圆

发表于 2010-7-22 19:10:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-25 21:10:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-25 21:10:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-25 21:20:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-26 12:53:02 | 显示全部楼层
好   借鉴一下

出0入0汤圆

发表于 2010-7-26 13:06:15 | 显示全部楼层
好像是VHDL语言吧,之前看过一下,但是不会用呢

出0入0汤圆

发表于 2010-7-26 14:53:24 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-3-5 20:29:49 | 显示全部楼层
请问 我想改成用矩阵按键实现的,按键一次显示一个数字,但是按照上面的程序更改,只可以输进去一个数字,假如输入下一个字符状态应如何转换啊? 12864液晶显示只可以用状态机吗 ?

出675入8汤圆

发表于 2011-3-6 00:43:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-6 08:23:29 | 显示全部楼层
正好需要一个FPGA驱动1602的代码,拿走参考一下喽,3q lz

出0入0汤圆

发表于 2011-3-9 21:07:57 | 显示全部楼层
Mark 拿来欣赏

出0入0汤圆

发表于 2011-11-29 09:51:10 | 显示全部楼层
回复【楼主位】ifree64
-----------------------------------------------------------------------

好像是有问题的,显示有时候不正常!

出0入0汤圆

发表于 2011-12-18 22:42:09 | 显示全部楼层
有时间测试一下

出0入0汤圆

发表于 2011-12-18 22:45:49 | 显示全部楼层
mark 12864 fpga

出0入24汤圆

发表于 2011-12-18 22:46:49 | 显示全部楼层
Mark!

出0入0汤圆

发表于 2011-12-20 09:20:26 | 显示全部楼层
好东西,收藏了

出0入0汤圆

发表于 2012-4-9 15:01:32 | 显示全部楼层
标记 学习

出0入0汤圆

发表于 2013-6-4 16:06:34 | 显示全部楼层
有显示图片的verilog例程吗?

出0入0汤圆

发表于 2013-8-1 22:00:47 | 显示全部楼层
支持,mark

出0入0汤圆

发表于 2013-8-2 09:24:26 | 显示全部楼层
刚听一个同学吹说网上没有verilog写的12864.。。他也在这论坛上。。。默默鄙视一番

出0入0汤圆

发表于 2013-8-2 13:20:21 | 显示全部楼层
mark,学习中

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-8-27 03:27

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

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