搜索
bottom↓
回复: 15

求助——Verilog 写的LCD12864 模块

[复制链接]

出0入0汤圆

发表于 2011-4-26 21:06:40 | 显示全部楼层 |阅读模式
这几天用Verilog写了一个LCD12864模块,调试几天,还是不工作,如有高手看到,请指教:
   
module LCD12864(
                                input clk,
                                input reset,
                                output reg rs,
                                output rw,
                                output en,
                                output reg[7:0] date,
                                output rst
                                );
reg clk_lcd;
reg[24:0] count;
reg flag;   //LCD操作完毕,释放其控制

always@(posedge clk or negedge reset)   //50Mhz TO 100khz
begin
        if(!reset)
                begin
                count<=25'b0;
                clk_lcd<=0;
                end
        else if(count==25'hf4240)     //
                        begin
                                count<=25'b0;
                                clk_lcd<=~clk_lcd;
                        end
                else  count<=count+25'b1;               
end

reg[8:0] state;                //state machine code
parameter idle=9'b00000_0000;   //initial,next is clear
parameter setfunction=9'b00000_0001;   //set function ,8-bits date
parameter setfunction2=9'b00000_0010;
parameter setfunction3=9'b00000_0100;
parameter switchmode=9'b00000_1000;    //显示开关控制:开显示,光标和闪烁关闭
parameter clear=9'b00001_0000;
parameter setmode=9'b00010_0000;   //输入方式设置:数据读写操作后,地址自动加一/画面不动
parameter setddram=9'b00100_0000;    //设置DDRAM的地址:第一行起始为0x80/第二行为0x90
parameter writeram=9'b01000_0000;   //数据写入DDRAM相应的地址
parameter stop=9'b10000_0000;      //LCD操作完毕,释放其控制


parameter message="项目名称: 声强仪功能介绍:      设计人:   第五组日期:2011.04.21 ";

reg[511:0] message1;


reg[4:0] char_cnt;
reg[7:0] date_disp;

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


always@(posedge clk_lcd or negedge rst)
begin
        if(!rst)
                begin
                rs<=1'b0;
                 end
        else if(state==writeram)
                        begin rs<=1'b1; end
                        else  rs<=1'b0;
end

// state machine
always @(posedge clk_lcd or negedge rst)
begin
        if(!rst)
        begin
                state<=idle;
                date<=8'bxxxxxxxx;
                char_cnt<=5'b0;
                flag<=1'b1;
                message1<=message;
        end
        else begin
                 case(state)
                 idle:  begin
                                state<=setfunction;
                                date<=8'h30;
                                end
                 setfunction: begin
                                          state<=setfunction2;
                                          date<=8'h08;     // 8-bit 控制界面,基本指令集动作
                                          end
                 setfunction2: begin
                                                state<= setfunction3;
                                                date<=8'h10;
                                           end
                 setfunction3: begin
                                                state<=clear;
                                                date<=8'h0c;  // 显示开关:开显示,光标和闪烁关闭
                                           end
                 clear:  begin
                                 state<=switchmode;
                                 date<=8'h01;  
                                 end
                 switchmode:  begin
                                 state<=setddram;
                                 date<=8'h06;  //输入方式设置: 数据读写后,地址自动加1,画面不动
                                 end

                 setddram:  begin
                                        state<=writeram;
                                        if(char_cnt==0)       //如果显示的是第一个字符,则设置第一行的首字符地址
                                            begin
                                                date<=8'h80;         //Line1
                                                end
                                        else if(char_cnt==16) begin
                                                        date<=8'h90;     //line2
                                                        end
                                                 else if(char_cnt==32) begin
                                                                                                date<=8'h88;
                                                                                                end
                                                          else if(char_cnt==48) begin
                                                                                                        date<=8'h98;
                                                                                                        end
                                        end
                 writeram:  begin
                                                if((char_cnt==16)|(char_cnt==32)|(char_cnt==48))
                                                         begin  state<=setddram;  end
                                                else if(char_cnt==64)
                                                                begin  char_cnt<=0; end
                                                         else
                                                                begin
                                                                    date_disp<=message1[511:504];
                                                                        message1<=(message1<<8);
                                                                        char_cnt<=char_cnt+1'b1;
                                                                        state<=writeram;
                                                                end
                                        end
                 stop:  begin
                                state<=stop;
                                flag<=0;
                                end
                 default: state<='bxxxxxxxxx;
                 endcase                       
                 end
end



endmodule

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2011-5-2 10:47:56 | 显示全部楼层
谁给个正确的模块也行啊

出0入0汤圆

发表于 2011-5-18 12:53:11 | 显示全部楼层
module LCD_12864(


                                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的数据总线(不进行读操作,故为输出)
                                input[7:0]  data_miao,
                                input[7:0]  data_fen,
                                input[7:0]  data_hour
                  
                );

                reg CLK_LCD; //LCD时钟信号
                reg [15:0]cnt;
                // CLK频率为50MHz, 产生LCD时钟信号, 10Hz
                always @(posedge CLK or negedge RST_N)
                begin
                  if (!RST_N)begin cnt <= 16'b0;CLK_LCD <= 0;end   
                  else if(cnt == 49999)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操作完毕,释放其控制
                  
          wire[7:0] disp_miao_L,disp_miao_H;//秒显示低位 * 秒显示高位
          wire[7:0] disp_fen_L,disp_fen_H;
          wire[7:0] disp_hour_L,disp_hour_H;
          
          //秒
          assign  disp_miao_H=data_miao/8'd10+8'h30;
          assign  disp_miao_L=data_miao%8'd10+8'h30;
          //分
          assign  disp_fen_H=data_fen/8'd10+8'h30;
          assign  disp_fen_L=data_fen%8'd10+8'h30;
          //时
      assign  disp_hour_H=data_hour/8'd10+8'h30;
          assign  disp_hour_L=data_hour%8'd10+8'h30;


        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'h90; //Line2
                                end
                                else //第二次设置时,是设置第二行的首字符地址
                                begin
                        LCD_D <= 8'h88; //Line3
                                end
                        end
                WRITERAM:
                begin
                        if(char_cnt <= 12)
                         begin
                                char_cnt <= char_cnt + 1'b1;
                                LCD_D <= data_disp;
                           if( char_cnt == 12 )
                                  state <= SETDDRAM;
                           else
                                state <= WRITERAM;
                         end
                        else if( char_cnt >= 13 && char_cnt <= 28)
                         begin
                                        LCD_D <= data_disp;
                                        state <= WRITERAM;
                                   char_cnt <= char_cnt + 1'b1;
                         end         
                        else if(char_cnt == 29)
                                        begin
                                                state <=SETDDRAM;
                                                char_cnt <= 5'b0;
                                           // flag <= 1'b0;
                                        end
                         
                 end
                       
                STOP: state <= STOP;
                 
         default: state <= IDLE;
                endcase
          end
end

                always @(char_cnt) //输出的字符
                begin
                        case (char_cnt)
                                5'd0:  data_disp <= 8'h20;
                                5'd1:  data_disp <= 8'h20;
                                5'd2:  data_disp <= 8'h20;
                                5'd3:  data_disp <= 8'h20;
                                5'd4:  data_disp <= 8'd181;
                                5'd5:  data_disp <= 8'd177;//当
                                5'd6:  data_disp <= 8'd199;
                                5'd7:  data_disp <= 8'd176;//前
                                5'd8:  data_disp <= 8'd186;
                                5'd9:  data_disp <= 8'd177;//时
                                5'd10:  data_disp <= 8'd188;
                                5'd11:  data_disp <= 8'd228;//间
                                5'd12:  data_disp <= ":";
                                       
                                5'd13:  data_disp <= 8'h20;
                            5'd14:  data_disp <= 8'h20;
                                5'd15:  data_disp <= 8'h20;
                                5'd16:  data_disp <= 8'h20;                                       
                                5'd17:  data_disp <= disp_hour_H;
                                5'd18:  data_disp <= disp_hour_L; //时
                                5'd19:  data_disp <= ":";  
                                5'd20:  data_disp <= disp_fen_H;  
                                5'd21:  data_disp <= disp_fen_L;  //分
                                5'd22:  data_disp <= ":";
                                5'd23:  data_disp <= disp_miao_H;
                                5'd24:  data_disp <= disp_miao_L; //秒
                                5'd25:  data_disp <= 8'h20;
                                5'd26:  data_disp <= 8'h20;
                                5'd27:  data_disp <= 8'h20;
                                5'd28:  data_disp <= 8'h20;
                                                                                                               
                     default :   data_disp <= 8'd20;
                        endcase
                end

endmodule


程序来自坛子的一位网友,我只是稍微改了些。代码一直在用,没问题。

出0入0汤圆

发表于 2011-5-18 14:17:01 | 显示全部楼层
mark下

出0入0汤圆

 楼主| 发表于 2011-5-24 13:52:20 | 显示全部楼层
谢了

出0入0汤圆

发表于 2011-8-14 16:16:11 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-9-26 14:52:58 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-9-26 14:57:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-26 14:58:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-29 08:53:35 | 显示全部楼层
回复【3楼】nison
-----------------------------------------------------------------------

试一下,使用时发现动态显示不成功!

出0入0汤圆

发表于 2011-11-29 08:56:05 | 显示全部楼层
回复【10楼】chenbo_ourdev  
-----------------------------------------------------------------------

我就是用这个代码写的一个秒表啊,

出0入0汤圆

发表于 2011-11-29 09:24:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-3-30 11:20:33 | 显示全部楼层
mark!!!

出0入0汤圆

发表于 2013-5-19 15:44:09 | 显示全部楼层
mark         

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-24 07:16

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

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