集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1478|回复: 3

LCD12864驱动代码分享

[复制链接]
fpga_feixiang 发表于 2019-9-16 21:09:31 | 显示全部楼层 |阅读模式
module Lcd12864(//针对型号为RT12864-S
                                                input Sys_Clk,
                                                input Rst,
                                                output reg LCD_RS,
                                                output LCD_RW,
                                                output LCD_E,
                                                output reg [7:0]LCD_Data
                                //                output PSB//串并控制端口,H为并行,L为串行,直接接5v
                                //                output LCD_Rst,//液晶的复位端口,低电平有效
                                //由于端口不够,暂时让其悬空
                                                );
                                reg LCD_Clk;
                                reg[7:0] state;//状态机寄存器
                                reg [23:0] cnt;//计数器
                                reg flag;//显示完成标志
                                reg[5:0]char_cnt;
                                reg[7:0]data_disp;//一个字节是八位,一个英文字符是一个字节,中文是俩个字节
                                parameter T500KHZ=24'd49999;
                        //        parameter T500KHZ=24'd24_999_999;//测试低频现象
                        //        parameter T500KHZ=24'd24_9;//仿真专用
                                //首先先对系统频率分频,液晶所需频率不用这么高,但是是多少呢?由datasheet可得出该液晶的最大频率是590kHZ
                                //典型值为530KH,为了好算取个值500KHZ,50M/500KHZ=10HZ,计数5M/2变化一次方向
                                always@(posedge Sys_Clk or negedge Rst)
                                begin
                                                if(!Rst)
                                                        begin
                                                                        cnt<=24'd0;
                                                                        LCD_Clk<=1'b0;
                                                        end
                                                else  if(cnt==T500KHZ)
                                                                        begin
                                                                                cnt<=24'd0;
                                                                                LCD_Clk<=~LCD_Clk;
                                                                        end
                                                                else
                                                                        cnt<=cnt+1'b1;
                                end
                               
                               
                                //state machine description,8个状态 只要用把位二进制就可以全部表示
                                parameter IDLE=8'b00_000_000;//初始状态
                                parameter SETFUNCTION=8'b00_000_001;//功能设置,8-bit+基本指令集0x30
                        //        parameter SETFUNCTION2=8'b00_000_010;//同上
                                parameter SWITCHMODE=8'b00_000_100;//设置显示开和光标闪烁关闭
                                parameter CLEAR=8'b00_001_000;//清屏操作
                                parameter SETMODE=8'b00_010_000;//点设置
                                parameter SETDDRAM=8'b00_100_000;//起始行设置
                                parameter WRITERAM=8'b01_000_000;//写设置
                                parameter STOP=8'b10_000_000;//LCD操作停止,释放其控制
                       
                                initial
                                begin
                                        cnt=24'd0;
                                        state=IDLE;
                                        flag=1'b1;
                                        LCD_Clk=1'b10;
                                        char_cnt=6'd0;
                                        data_disp=8'd32;
                                end
                               
                                //设置好RS、RW、E
                                always@(posedge LCD_Clk or negedge Rst)
                                begin
                                                if(!Rst)
                                                        LCD_RS<=1'b0;
                                                else        if(state==WRITERAM)
                                                                        LCD_RS<=1'b1;
                                                                else
                                                                        LCD_RS<=1'b0;
                                end
                               
                                //如果定义了LCD_Rst俩个端口的话,可做如下设置
                                //assign LCD_Rst=1'b1;
                                //assign PSB=1'b1;
                                assign LCD_RW=1'b0;//只是写操作,不需要读操作
                                assign LCD_E=(flag==1)?LCD_Clk:1'b0;//使能信号与液晶时钟同步
                               
                                //descible the state machine
                                always@(posedge LCD_Clk or negedge Rst)
                                begin
                                                if(!Rst)
                                                        begin
                                                                        state<=IDLE;
                                                                        LCD_Data<=8'bzz_zzz_zzz;
                                                        end
                                                else
                                                                begin
                                                                                case(state)
                                                                                                IDLE:
                                                                                                                begin
                                                                                                                                state<=SETFUNCTION;
                                                                                                                                LCD_Data<=8'h30;
                                                                                                                end
                                                                                                SETFUNCTION:
                                                                                                                begin
                                                                                                                                state<=SWITCHMODE;
                                                                                                                        //        state<=SETFUNCTION2;
                                                                                                                                LCD_Data<=8'h30;
                                                                                                                end
                                                                                //                SETFUNCTION2:
                                                                                        //                        begin       
                                                                                        //                                        state<=SWITCHMODE;
                                                                                        //                                        LCD_Data<=8'h30;
                                                                                        //                        end
                                                                                                SWITCHMODE:
                                                                                                                begin
                                                                                                                                state<=CLEAR;
                                                                                                                                LCD_Data<=8'h0c;//显示设置,全显示开,光标和闪烁关
                                                                                                                end
                                                                                                CLEAR:
                                                                                                                begin
                                                                                                                                state<=SETMODE;
                                                                                                                                LCD_Data<=8'h01;//清屏、
                                                                                                                end
                                                                                                SETMODE:
                                                                                                                begin
                                                                                                                                state<=SETDDRAM;
                                                                                                                                LCD_Data<=8'h06;//点设置,光标右移,地址加一,整体不动
                                                                                                                end
                                                                                                SETDDRAM://设置起始位置
                                                                                                                begin
                                                                                                                                state<=WRITERAM;
                                                                                                                                if(char_cnt==6'd0)
                                                                                                                                        LCD_Data<=8'h80;//line1
                                                                                                                                else
                                                                                                                                        LCD_Data<=9'h90;//line2
                                                                                                                end
                                                                                                WRITERAM:
                                                                                                                begin
                                                                                                                                if(char_cnt<=6'd11)
                                                                                                                                        begin
                                                                                                                                                        char_cnt<=char_cnt+1'b1;
                                                                                                                                                        LCD_Data<=data_disp;
                                                                                                                                                        if(char_cnt==6'd11)
                                                                                                                                                                state<=SETDDRAM;//第一行写完后从新返回设置地址
                                                                                                                                                        else
                                                                                                                                                                state<=WRITERAM;
                                                                                                                                        end
                                                                                                                                else if(char_cnt>=6'd12&&char_cnt<=6'd25)
                                                                                                                                                        begin
                                                                                                                                                                if(char_cnt==6'd25)
                                                                                                                                                                        begin
                                                                                                                                                                                        state<=STOP;
                                                                                                                                                                                        char_cnt=6'd0;
                                                                                                                                                                                        flag<=1'b0;
                                                                                                                                                                        end
                                                                                                                                                                else
                                                                                                                                                                        begin       
                                                                                                                                                                                LCD_Data<=data_disp;//不管到没到第25个都要继续写数
                                                                                                                                                                                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="G";
                                                        6'd1:data_disp="U";
                                                        6'd2:data_disp="X";
                                                        6'd3:data_disp="I";
                                                        6'd4:data_disp="A";
                                                        6'd5:data_disp="N";
                                                        6'd6:data_disp="Y";
                                                        6'd7:data_disp="I";
                                                        6'd8:data_disp="L";
                                                        6'd9:data_disp="C";
                                                        6'd10:data_disp="D";
                                                        6'd11:data_disp="!";
                                                       
                                                        6'd12:data_disp="H";
                                                        6'd13:data_disp="E";
                                                        6'd14:data_disp="L";
                                                        6'd15:data_disp="L";
                                                        6'd16:data_disp="O";
                                                        6'd17:data_disp="E";
                                                        6'd18:data_disp="V";
                                                        6'd19:data_disp="E";
                                                        6'd20:data_disp="R";
                                                        6'd21:data_disp="Y";
                                                        6'd22:data_disp="O";
                                                        6'd23:data_disp="N";
                                                        6'd24:data_disp="E";
                                        //                default:data_disp=8'h32;
                                                endcase
                                               
                                end
                               
endmodule
zxopenljx 发表于 2019-9-17 10:00:11 | 显示全部楼层
感谢楼主分享
晓灰灰 发表于 2019-9-17 12:53:09 | 显示全部楼层
LCD12864驱动代码
durongze 发表于 2023-6-18 22:11:36 | 显示全部楼层
to,location
12864_res, pin_R1
12864_cs, pin_T3
12864_rs , pin_J1
12864_scl ,pin_P1
12864_sda , pin_K6

我这个管脚如何配置才能用你的程序呢? http://fpgaw.com/forum.php?mod=attachment&aid=NDU3NDV8NTllNzU4MGN8MTczMjY3NTQwOHwwfA%3D%3D

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-27 10:43 , Processed in 0.063779 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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