yyh1910 发表于 2010-11-8 13:02:05

求助各位高手,这是我写的Verilog 1602液晶驱动,显示时有问题??

module disp1602(clk,en,rs,rw,lcd_data,rst);
input clk,rst;       //20MHz输入时钟
output en,rs,rw;    //使能信号,数据/指令选择端(H/L),读写选择端
output lcd_data;

reg lcd_clk;      //1602时钟信号 500Hz
reg c0;    //将 clk(20MHz) 分频到 500Hz: 2ms
reg state;//定义 状态

reg lcd_data;
reg data_first_buf,data_second_buf;   //液晶显示的数据缓存
regrs,lcd_en_sel;
reg disp_count;

/******* 定义各状态名及编码******/
parameter   Clear_Lcd         = 4'b0000,         //清屏和光标恢复
            Set_Disp_Mode   = 4'b0001,       //设置显示模式:8位2行5x7点阵   
            Disp_On         = 4'b0010,             //显示器开、光标不显示、光标不允许闪烁
            Auto_ad_address   = 4'b0011,
            Write_Addr      = 4'b0100,          //写入显示起始地址
            Write_Data_First= 4'b0101,    //写入第一行显示的数据
            Write_Data_Second = 4'b0110,    //写入第二行显示的数据
            SJMP= 4'B0111; //原地跳转

parameter   Data_First =" good good study ",//液晶显示的第一行的数据
            Data_Second = "day   dayup"; //液晶显示的第二行的数据
/***********************************/


assign rw=1'b0;   //选择 写 选通
assign en=lcd_en_sel?lcd_clk:1'b0;//通过lcd_en_sel来控制 en 的选通



/***********状态机变化部分   ********/
/*    1602液晶功能设置,数据写入      */
/**************************************/
always @(posedge lcd_clk or negedge rst)
begin   
    if(!rst)   
       begin
         state<=Clear_Lcd;
         lcd_data<=8'b0000_0000;
         rs <=1'b0;
         lcd_en_sel<=1;
         disp_count<=4'b0000;   
       end
   else
      case(state)
      Clear_Lcd:
         begin
             state<=Set_Disp_Mode;
             lcd_data=8'b0000_0001; //清屏指令
         end
      Set_Disp_Mode:
         begin
             state<=Disp_On;
             lcd_data=8'b0011_1000;//1602显示设置
         end
      Disp_On:
         begin
             state<=Auto_ad_address;
             lcd_data=8'b0000_1110;//开 显示和光标
         end
      Auto_ad_address:
         begin
             state<=Write_Addr;
             lcd_data=8'b0000_0110;//写1个字符,地址指针和光标都加 1
         end
      Write_Addr:
         begin
             state<=Write_Data_First;
             lcd_data=8'b1000_0000;//设置数据指针的首地址
             data_first_buf<=Data_First;//将第一行14个字符(112位)赋给 data_first_buf
            // data_second_buf=Data_Second;//将第二行14个字符(112位)赋给 data_second_buf
         end
      Write_Data_First:
         begin
             if(disp_count==16)
               begin
               rs=0;
               lcd_data=8'b1100_0000;
               disp_count=0;
               data_second_buf<=Data_Second;//将第二行14个字符(112位)赋给 data_second_buf
               state<=Write_Data_Second;
               end            
             else      
               begin
               rs=1;
               lcd_data=data_first_buf;
               data_first_buf=(data_first_buf<<8);
               disp_count=disp_count+1;
               state<=Write_Data_First;
               end         
             end         
         Write_Data_Second:
         begin
             if(disp_count<16)
               begin
               rs=1;
               lcd_data=data_second_buf;
               data_second_buf=(data_second_buf<<8);
               disp_count=disp_count+1;
               state<=Write_Data_Second;
               end
             else state=SJMP;
         end
         SJMP:
            state<=SJMP;
         default:state<=SJMP;      
       endcase
end   

/****clk分频为 500Hz****/
always @(posedge clk)
if(c0<25000)
    c0=c0+1;
else
    begin
      c0=0;lcd_clk=~lcd_clk;
    end
endmodule

yyh1910 发表于 2010-11-8 13:02:33

显示时只是闪一下就没了,复位按一下,字符再闪一下,这是什么原因??

weibode01 发表于 2010-11-8 13:06:15

没有板子在手上,想用你的程序调一下也不行。。

yyh1910 发表于 2010-11-8 15:16:08

回复 3# weibode01


    谢谢

yyh1910 发表于 2010-11-8 17:00:03

/***********状态机变化部分   ********/
/*    1602液晶功能设置,数据写入      */
/**************************************/
always @(posedge lcd_clk or negedge rst)
begin   
    if(!rst)   
       begin
         state<=Clear_Lcd;
         lcd_data<=8'b0000_0000;
         rs <=1'b0;
         lcd_en_sel<=1;
         disp_count<=4'b0000;   
       end
    else
      case(state)
      Clear_Lcd:
         begin
             state<=Set_Disp_Mode;
             lcd_data=8'b0000_0001; //清屏指令
         end
      Set_Disp_Mode:
         begin
             state<=Disp_On;
             lcd_data=8'b0011_1000;//1602显示设置
         end
      Disp_On:
         begin
             state<=Auto_ad_address;
             lcd_data=8'b0000_1110;//开 显示和光标
         end
      Auto_ad_address:
         begin
             state<=Write_Addr;
             lcd_data=8'b0000_0110;//写1个字符,地址指针和光标都加 1
         end
      Write_Addr:
         begin
             state<=Write_Data_First;
             lcd_data=8'b1000_0000;//设置数据指针的首地址
             data_first_buf<=Data_First;//将第一行14个字符(112位)赋给 data_first_buf
            // data_second_buf=Data_Second;//将第二行14个字符(112位)赋给 data_second_buf
         end
      Write_Data_First:
         begin
             if(disp_count==16)
               begin
               rs=0;
               lcd_data=8'b1100_0000;
               disp_count=0;
               data_second_buf<=Data_Second;//将第二行14个字符(112位)赋给 data_second_buf
               state<=Write_Data_Second;
               end            
             else      
               begin
               rs=1;
               lcd_data=data_first_buf;
               data_first_buf=(data_first_buf<<8);
               disp_count=disp_count+1;
               state<=Write_Data_First;
               end         
             end         
         Write_Data_Second:
         begin
             if(disp_count<16)
               begin
               rs=1;
               lcd_data=data_second_buf;
               data_second_buf=(data_second_buf<<8);
               disp_count=disp_count+1;
               state<=Write_Data_Second;
               end
             else begin disp_count=0;state=Write_Data_First;end
         end
      //   SJMP:
      //      state<=SJMP;
   //    default:state<=SJMP;      
       endcase
end   



我在写字符这里改了一下,不让他原地跳转,而是让他不断地写入字符,这样显示就正常了。
但我还是很想知道,为什么原来的代码不行,问题出在哪?

weibode01 发表于 2010-11-14 09:31:46

哈哈,我也想用板子去控制1602,可是都没钱买。。。穷孩子啊

驾神马看浮云 发表于 2011-2-4 20:45:21

加油!!!

FPGA_aihaozhe 发表于 2011-2-5 02:28:42

学习!!!!!!!!!!!

fsouth 发表于 2014-3-26 13:07:39

为什么我把你的程序下到我板子上   用你改过的程序还是屏幕闪一下呢???
页: [1]
查看完整版本: 求助各位高手,这是我写的Verilog 1602液晶驱动,显示时有问题??