1602液晶的问题

[复制链接]
2156|1
 楼主| wang27177199 发表于 2011-12-6 22:13 | 显示全部楼层 |阅读模式
小弟最近学习开发板上的1602液晶,
写了代码,下载后液晶没显示,只有背光是亮的。

相信很多人都用过1602噻,程序也很普遍,

我贴出代码来大家帮我在你们的开发板上运行下

看看能实现不?

最好能找下问题所在,谢谢各位指点

  1. /*************************************************
  2. //Module:       lcd1602
  3. //File Name:    lcd1602.v
  4. //Version:      1.0
  5. //Date:         2011.12.5
  6. //Author:       wang li
  7. //Code Type:    RTL
  8. //Description:  LCD1602液晶显示
  9. //              clk——时钟输入(1位)
  10. //              rst——复位信号输入(1位)
  11. //       输入看模块
  12. **************************************************/
  13. module lcd1602(clk,rst,LCD_E,LCD_RW,LCD_RS,LCD_DATA);
  14. input clk;    //时钟信号,50Mhz
  15. input rst;    //复位信号,低电平进行复位
  16. output LCD_E;   //1602使能引脚,1时读取信息,1->0(下降沿)执行命令
  17. output LCD_RS;   //1602数据——H/命令——L  选择端
  18. output LCD_RW;   //1602写——L/读——H  选择端
  19. output [7:0] LCD_DATA; //1602数据传输端口
  20. wire LCD_E;
  21. reg [8:0] count;
  22. reg clk_div1; //500个clk的周期,20ns*500=10us
  23. reg clk_div2; //1000个,20us
  24. reg [8:0] count1; //500个clk_div2的周期,10us*200=2000u=5ms
  25. reg clk_buf;
  26. //******************
  27. //-----分频模块-----
  28. //******************
  29. always @(posedge clk or negedge rst)
  30. begin
  31. if(!rst) //rst=0
  32.   count<=0;
  33. else
  34.   begin
  35.    if(count<250)  //2500
  36.     begin
  37.      clk_div1<=0;
  38.      count<=count+1'b1;
  39.     end
  40.    else if(count>=500-1)  //5000
  41.     count<=0;
  42.    else
  43.     begin
  44.      clk_div1<=1;
  45.      count<=count+1'b1;
  46.     end   
  47.   end
  48. end
  49. always @(posedge clk_div1 or negedge rst)
  50. begin
  51. if(!rst)
  52.   clk_div2<=0;
  53. else
  54.   clk_div2<=~clk_div2;
  55. end
  56. always @(posedge clk_div2 or negedge rst)
  57. begin
  58. if(!rst) //rst=0
  59.   count1<=0;
  60. else
  61.   begin
  62.    if(count1<250)  //2500
  63.     begin
  64.      clk_buf<=0;
  65.      count1<=count1+1'b1;
  66.     end
  67.    else if(count1>=500-1)  //5000
  68.     count1<=0;
  69.    else
  70.     begin
  71.      clk_buf<=1;
  72.      count1<=count1+1'b1;
  73.     end   
  74.   end
  75. end
  76. assign LCD_E=clk_buf;


  77. //**********************
  78. //-----显示控制模块-----
  79. //**********************
  80. reg [3:0] state;     //当前状态寄存器  ,10个状态
  81. reg [4:0] address;  //地址的位置,0~31
  82. reg [7:0] LCD_DATA;
  83. reg LCD_RW,LCD_RS;
  84. parameter   
  85.   IDLE      = 4'd0,  //空闲
  86.   SET_FUNCTION  = 4'd2,  //工作方式设置指令  
  87.   SWITCH_MODE   = 4'd3,  //开关控制指令  
  88.   SET_MODE   = 4'd4,  //输入方式设置  
  89.   CLEAR    = 4'd5,
  90.   SET_DDRAM1    = 4'd6,  //设定第一行DDRAM地址指令  
  91.   WRITE_RAM1    = 4'd7,  //向第一行写入的数码  
  92.   WRITE_RAM2    = 4'd8,   //向第2行写入的数码  
  93.   SHIFT      = 4'd9, //设定显示屏或光标移动方向指令
  94.   SET_DDRAM2    = 4'd10,  //设定第2行DDRAM地址指令  
  95.   STOP    = 4'd11;
  96. reg [127:0] Data_First = "www.endchina.com"; //液晶显示的第一行的数据  
  97. reg [127:0] Data_Second = " chick_kid "; //液晶显示的第二行的数据  
  98. reg [127:0] Data_First_Buf,
  99.    Data_Second_Buf; //液晶显示的数据缓存
  100. //-----状态控制-----
  101. always @(posedge clk_buf or negedge rst)
  102. begin
  103. if(!rst)
  104.   begin
  105.    state<=IDLE;
  106.    address<=5'd0;
  107.    LCD_DATA<=8'b0000_0000;
  108.    LCD_RS<=0;
  109.    LCD_RW<=0;
  110.   end
  111. else
  112.   begin
  113.    case(state)
  114.     IDLE:  //空闲状态
  115.            begin
  116.             LCD_DATA<=8'b00000000;  //8'bzzzz_zzzz
  117.             state<=SET_FUNCTION;
  118.            end
  119.     SET_FUNCTION:  //工作方式设置
  120.         begin
  121.          LCD_RS<=0;
  122.          LCD_RW<=0;
  123.          LCD_DATA<=8'b0011_1000;  //38h
  124.          //第4位DL:0=数据总线为4位;1=数据总线为8位★★★
  125.          //第3位N:0=显示1行;1=显示2行★★★  
  126.          //第2位F:0=5×7点阵/每字符★★★;1=5×10点阵/每字符
  127.          state<=SWITCH_MODE;  
  128.         end
  129.     SWITCH_MODE:  //显示开关控制指令
  130.         begin
  131.          LCD_RS<=0;
  132.          LCD_RW<=0;
  133.          LCD_DATA<=8'b0000_1111;  //0Fh
  134.          //第2位D:0=显示功能关;1=显示功能开★★★
  135.          //第1位C:0=无光标;1=有光标★★★  
  136.          //第0位B:0=光标闪烁; 1=光标不闪烁★★★
  137.          state<=SET_MODE;
  138.         end
  139.     SET_MODE:  //设定显示屏或光标移动方向指令  
  140.         begin
  141.          LCD_RS<=0;
  142.          LCD_RW<=0;
  143.          LCD_DATA<=8'b0000_0110;  //06h
  144.          //第1位N:0=读或者写一个字符后,地址指针-1,光标-1
  145.          //       1=读或者写一个字符后,地址指针+1,光标+1★★★
  146.          //第0位S:0=当写一个字符,整屏显示不移动★★★
  147.          //    1=当写一个字符,整屏显示左移(N=1)或者右移(N=0),以得到光标不移动而屏幕移动的效果
  148.          state<=CLEAR;
  149.         end
  150.     CLEAR:  //清屏指令
  151.         begin
  152.          LCD_RS<=0;
  153.          LCD_RW<=0;
  154.          LCD_DATA<=8'b0000_0001; //指令
  155.          state<=SHIFT;      
  156.         end
  157.    
  158.     SHIFT:  //设定显示屏或光标移动方向指令  
  159.         begin
  160.          LCD_RS<=0;
  161.          LCD_RW<=0;
  162.          LCD_DATA<=8'b0001_0100;  
  163.               //第3位S/C;第2位R/L
  164.          //    S/C   R/L     设定情况  
  165.          //    0      0      光标左移1格,且AC值减1  
  166.          //    0      1      光标右移1格,且AC值加1  ★★★
  167.          //   1      0      显示器上字符全部左移一格,但光标不动  
  168.          //    1      1      显示器上字符全部右移一格,但光标不动
  169.          state<=SET_DDRAM1;
  170.         end
  171.     SET_DDRAM1:  //设定第一行DDRAM地址指令
  172.         begin  
  173.          LCD_RS<=0;
  174.          LCD_RW<=0;
  175.             
  176.     //-----写入第一行显示起始地址:-----
  177.     //  1   2  3  4   5   6   7  8  9  10  11  12  13  14  15  16
  178.     // 00  01 02  03  04  05 06 07 08  09  0A  0B  0C  0D  0E  0F   第一行
  179.          LCD_DATA<=8'h80+8'd0; //第一行第1个位置  
  180.             
  181.          state<=WRITE_RAM1;
  182.          Data_First_Buf<=Data_First;  
  183.         end
  184.     WRITE_RAM1:  //向第一行写入的数码
  185.         begin
  186.          if(address<=15)   //表示写第一行
  187.           begin
  188.            LCD_RS<=1;
  189.            LCD_RW<=0;
  190.            LCD_DATA<=Data_First_Buf[127:120];
  191.            Data_First_Buf<=(Data_First_Buf<<8);   //左移
  192.            address<=address+1'b1;
  193.            state<=WRITE_RAM1;
  194.           end
  195.          else
  196.           begin
  197.            LCD_RS<=0;
  198.            LCD_RW<=0;
  199.            state<=SET_DDRAM2;
  200.           end
  201.         end
  202.     SET_DDRAM2:  //设定第2行DDRAM地址指令
  203.         begin  
  204.          LCD_RS<=0;
  205.          LCD_RW<=0;
  206.             
  207.     //-----写入第2行显示起始地址:-----
  208.     //  1   2  3  4   5   6   7  8  9  10  11  12  13  14  15  16
  209.     // 40  41 42  43  44  45 46 47 48  49  4A  4B  4C  4D  4E  4F   第二行
  210.          LCD_DATA<=8'hC0+8'd0; //第2行第1个位置  
  211.             
  212.          state<=WRITE_RAM2;
  213.          Data_Second_Buf<=Data_Second;  
  214.         end
  215.     WRITE_RAM2:  //向第2行写入的数码
  216.            begin
  217.             if(address<=31)   //表示写第一行
  218.           begin
  219.            LCD_RS<=1;
  220.            LCD_RW<=0;
  221.            LCD_DATA<=Data_First_Buf[127:120];
  222.            Data_Second_Buf<=(Data_Second_Buf<<8);
  223.            address<=address+1'b1;
  224.            state<=WRITE_RAM2;
  225.           end
  226.          else
  227.           begin
  228.            LCD_RS<=0;
  229.            LCD_RW<=0;
  230.            address<=5'd0;
  231.            state<=STOP;
  232.           end
  233.            end
  234.     STOP:  //设定第一行DDRAM地址指令
  235.         begin  
  236.          state<=STOP;
  237.         end
  238.     default:
  239.            state<=CLEAR;
  240.    endcase        
  241.   end
  242. end

  243. endmodule



 楼主| wang27177199 发表于 2011-12-7 09:56 | 显示全部楼层
有耐心的解释下吧,谢谢啦。真的很感谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

9

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部