博客首页 | 排行榜 |

openhw_llh的博客

个人档案
博文分类
五种状态LCD  2008-08-24 17:54

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity lcdxianshi is
          port(  CLK : in std_logic;
       Reset : in std_logic;
                enter: in std_logic;
            key_encri: in std_logic_vector(3 downto 0);
            key_decri: in std_logic_vector(3 downto 0);    
              LCD_RS : out std_logic;
    outxianshi:out std_logic;
              LCD_RW : out std_logic;
              LCD_EN : out std_logic;
                data : out std_logic_vector(3 downto 0));
end lcdxianshi;
architecture Behavioral of lcdxianshi is
  type iState is ( 
                        Write_instr,      --写命令字
                    Write_DataUP4_1,      --写LCD一线高4位
                  Write_DataDown4_1,      --写LCD一线低4位
                     Set_DDRamAddUp,      --设置DDRam地址高4位   
                   Set_DDRamAddDown,      --设置DDRam地址低4位
                    Write_DataUP4_2,      --写LCD二线高4位
                   Write_DataDown4_2      --写LCD二线低4位
      );

  signal State:iState; 
  type ram is array(0 to 15) of std_logic_vector(7 downto 0);
  constant   myram0_up:ram:=(x"50",x"4c",x"45",x"41",--PLEASE
                            x"53",x"45",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20");                      
  constant   myram0_down:ram:=(x"49",x"4e",x"50",x"55",x"54",x"20",x"50",x"41",-- INPUT PASSWORD! 
                              x"53",x"53",x"57",x"4f",x"52",x"44",x"21",x"20");
  constant   myram1_up:ram:=(x"57",x"45",x"4c",  --WELCOME!
                             x"43",x"4f",x"4d",x"45",x"21",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20");
  constant   myram1_down:ram:=(x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20" 
                              ,x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20");
  constant   myram2_up:ram:=(x"45",x"52",x"52",  --ERROR!
                             x"4F",x"52",x"21",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20");
  constant   myram2_down:ram:=(x"54",x"57",x"4f",x"20",x"54",  --TWO TIMES!
                               x"49",x"4d",x"45",x"53",x"21",x"20",x"20",x"20",x"20",x"20",x"20");
  constant   myram3_up:ram:=(x"57",x"4f",x"52",x"4e",x"49",  -- WORNING! 
                             x"4e",x"47",x"21",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20");
  constant   myram3_down:ram:=(x"4f",x"4e",x"4c",x"59",x"20",x"4f",x"4e",  --ONLY ONE TIME! 
                             x"45",x"20",x"54",x"49",x"4d",x"45",x"21",x"20",x"20");
  constant   myram4_up:ram:=(x"46",  --  FAILED! 
                             x"41",x"49",x"4c",x"45",x"44",x"21",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20",x"20");
  constant   myram4_down:ram:=(x"54",x"48",x"45",x"20",x"4b",x"45",x"59",  --THE KEY LOCKED! 
                             x"20",x"4c",x"4f",x"43",x"4b",x"45",x"44",x"21",x"20");
 signal  LCD_Clk : std_logic :='0';
 signal  datacnt : integer range 0 to 23:=0;--作为地址指针计数
 signal  cnt     : integer range 0 to 100:=0;--统计密码输入次数
-- signal  addr_cnt: integer range 0 to 15:=0;--显示字符地址指?
begin
  LCD_RW <= '0';
  LCD_EN <= LCD_Clk;
process(CLK)                                         --20000分频,满足时序要求
  variable n1:integer range 0 to 899999;
begin 
  if rising_edge(CLK) then
   if n1<899999 then 
       n1:=n1+1;
    else
      n1:=0;
      LCD_Clk<=not LCD_Clk;
    end if;
 end if;
end process;

process(reset, enter)--统计密码输入次数
begin
 if Reset='0' then
     cnt<=0;
 --  outxianshi<='0';
 elsif rising_edge(enter) then
     cnt<=cnt+1;
 end if;
 
end process;
process(LCD_Clk,state,reset,cnt,key_decri,key_encri,enter)
begin
  if Reset='0' then
      state<=Write_instr;
     LCD_RS <= '0';
   outxianshi<='0';
 elsif rising_edge(LCD_Clk) then
   case cnt is
 when 0 =>--显示 please input password!
 case state is
   when Write_instr=>              --写命令字到LCD控制器
       LCD_RS<='0'; 
   if(datacnt=0)then
        data<="0000";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=1)then
        data<="0001";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=2)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=3)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=4)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=5)then
        data<="0010";             --0010
        datacnt<=datacnt+1; 
  elsif(datacnt=6)then            --0x28  :    0010 1000 =>功能设置 8位总线双行显示
        data<="0010";
        datacnt<=datacnt+1;
  elsif(datacnt=7)then
        data<="1000";
        datacnt<=datacnt+1;
  elsif(datacnt=8)then             --0x06  :   0000 0110 =>模式设定   光标右移,字符不动
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=9)then
        data<="0110";
        datacnt<=datacnt+1;
  elsif(datacnt=10)then            --0x0c  :    0000 1100 =>显示设定  整体显示开 无光标
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=11)then
        data<="1100";
        datacnt<=datacnt+1;  
  elsif(datacnt=12)then          --0x10  : 1000 0000 =>00H 设定列吹刂肺?       data<="1000";
       datacnt<=datacnt+1;
  else
       data<="0000";
       datacnt<=0;
       state<=Write_DataUP4_1;
  end if;
  
  when Write_DataUP4_1=>
       LCD_RS<='1';  
       data <= myram0_up(datacnt)(7 downto 4);
       state <= Write_DataDown4_1;
  when Write_DataDown4_1=>
      if datacnt=23 then
        data <= myram0_up(datacnt)(3 downto 0);
        datacnt<=0;
        state <=Set_DDRamAddUp;
       else
        data <= myram0_up(datacnt)(3 downto 0);
        datacnt<=datacnt+1;
        state <=Write_DataUP4_1;
       end if;
  when Set_DDRamAddUp=> --0xc0  :  1100 0000=>40H  设定读写地址位
        LCD_RS<='0';
        data<="1100";
        state<=Set_DDRamAddDown;
  when Set_DDRamAddDown=>
        data<="0000";
        state<=Write_DataUP4_2;
  when Write_DataUP4_2=>
       LCD_RS<='1';    
       data <= myram0_down(datacnt)(7 downto 4);
       state <= Write_DataDown4_2;
  when Write_DataDown4_2=>
        if datacnt=23 then
         data <= myram0_down(datacnt)(3 downto 0);
         datacnt<=0;
         state <=Write_DataUP4_1;
        else
         data <= myram0_down(datacnt)(3 downto 0);
         datacnt<=datacnt+1;
         state <=Write_DataUP4_2;
        end if;
  when others=>
      state<=Write_instr;
    end case;-- state machine  PLEASE INPUT PASSWORD!
 when 1 =>
if(enter='1') then
    if(key_decri=key_encri) then --显示 WELCOME!
   case state is
   when Write_instr=>              --写命令字到LCD控制器
       LCD_RS<='0'; 
   if(datacnt=0)then
        data<="0000";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=1)then
        data<="0001";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=2)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=3)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=4)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=5)then
        data<="0010";             --0010
        datacnt<=datacnt+1; 
  elsif(datacnt=6)then            --0x28  :    0010 1000 =>功能设置 8位总线双行显示
        data<="0010";
        datacnt<=datacnt+1;
  elsif(datacnt=7)then
        data<="1000";
        datacnt<=datacnt+1;
  elsif(datacnt=8)then             --0x06  :   0000 0110 =>模式设定   光标右移,字符不动
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=9)then
        data<="0110";
        datacnt<=datacnt+1;
  elsif(datacnt=10)then            --0x0c  :    0000 1100 =>显示设定  整体显示开 无光标
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=11)then
        data<="1100";
        datacnt<=datacnt+1;  
  elsif(datacnt=12)then          --0x10  : 1000 0000 =>00H 设定读写地址位
       data<="1000";
       datacnt<=datacnt+1;
  else
       data<="0000";
       datacnt<=0;
       state<=Write_DataUP4_1;
  end if;
  when Write_DataUP4_1=>
       LCD_RS<='1';  
       data <= myram1_up(datacnt)(7 downto 4);
       state <= Write_DataDown4_1;
  when Write_DataDown4_1=>
      if datacnt=23 then
        data <= myram1_up(datacnt)(3 downto 0);
        datacnt<=0;
        state <=Set_DDRamAddUp;
       else
        data <= myram1_up(datacnt)(3 downto 0);
        datacnt<=datacnt+1;
        state <=Write_DataUP4_1;
       end if;
  when Set_DDRamAddUp=> --0xc0  :  1100 0000=>40H  设定读写地址位
        LCD_RS<='0';
        data<="1100";
        state<=Set_DDRamAddDown;
  when Set_DDRamAddDown=>
        data<="0000";
        state<=Write_DataUP4_2;
  when Write_DataUP4_2=>
       LCD_RS<='1';    
       data <= myram1_down(datacnt)(7 downto 4);
       state <= Write_DataDown4_2;
  when Write_DataDown4_2=>
        if datacnt=23 then
         data <= myram1_down(datacnt)(3 downto 0);
         datacnt<=0;
         state <=Write_DataUP4_1;
        else
         data <= myram1_down(datacnt)(3 downto 0);
         datacnt<=datacnt+1;
         state <=Write_DataUP4_2;
        end if;
  when others=>
      state<=Write_instr;  
  end case;-- end state machine2
 else                  --显示 ERROR! TWO TIMES!
   case state is
   when Write_instr=>              --写命令字到LCD控制器
       LCD_RS<='0'; 
   if(datacnt=0)then
        data<="0000";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=1)then
        data<="0001";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=2)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=3)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=4)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=5)then
        data<="0010";             --0010
        datacnt<=datacnt+1; 
  elsif(datacnt=6)then            --0x28  :    0010 1000 =>功能设置 8位总线双行显示
        data<="0010";
        datacnt<=datacnt+1;
  elsif(datacnt=7)then
        data<="1000";
        datacnt<=datacnt+1;
  elsif(datacnt=8)then             --0x06  :   0000 0110 =>模式设定   光标右移,字符不动
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=9)then
        data<="0110";
        datacnt<=datacnt+1;
  elsif(datacnt=10)then            --0x0c  :    0000 1100 =>显示设定  整体显示开 无光标
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=11)then
        data<="1100";
        datacnt<=datacnt+1;  
  elsif(datacnt=12)then          --0x10  : 1000 0000 =>00H 设定读写地址位
       data<="1000";
       datacnt<=datacnt+1;
  else
       data<="0000";
       datacnt<=0;
       state<=Write_DataUP4_1;
  end if;
 when Write_DataUP4_1=>
       LCD_RS<='1';  
       data <= myram2_up(datacnt)(7 downto 4);
       state <= Write_DataDown4_1;
 when Write_DataDown4_1=>
      if datacnt=23 then
        data <= myram2_up(datacnt)(3 downto 0);
        datacnt<=0;
        state <=Set_DDRamAddUp;
       else
        data <= myram2_up(datacnt)(3 downto 0);
        datacnt<=datacnt+1;
        state <=Write_DataUP4_1;
       end if;
 when Set_DDRamAddUp=> --0xc0  :  1100 0000=>40H  设定读写地址位
        LCD_RS<='0';
        data<="1100";
        state<=Set_DDRamAddDown;
 when Set_DDRamAddDown=>
        data<="0000";
        state<=Write_DataUP4_2;
 when Write_DataUP4_2=>
       LCD_RS<='1';    
       data <= myram2_down(datacnt)(7 downto 4);
       state <= Write_DataDown4_2;
 when Write_DataDown4_2=>
        if datacnt=23 then
         data <= myram2_down(datacnt)(3 downto 0);
         datacnt<=0;
         state <=Write_DataUP4_1;
        else
         data <= myram2_down(datacnt)(3 downto 0);
         datacnt<=datacnt+1;
         state <=Write_DataUP4_2;
        end if;
  when others=>
      state<=Write_instr;
    end case; --end state machine3
    end if;
  else--显示 please input password !
 case state is
   when Write_instr=>              --写命令字到LCD控制器
       LCD_RS<='0'; 
   if(datacnt=0)then
        data<="0000";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=1)then
        data<="0001";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=2)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=3)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=4)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=5)then
        data<="0010";             --0010
        datacnt<=datacnt+1; 
  elsif(datacnt=6)then            --0x28  :    0010 1000 =>功能设置 8位总线双行显示
        data<="0010";
        datacnt<=datacnt+1;
  elsif(datacnt=7)then
        data<="1000";
        datacnt<=datacnt+1;
  elsif(datacnt=8)then             --0x06  :   0000 0110 =>模式设定   光标右移,字符不动
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=9)then
        data<="0110";
        datacnt<=datacnt+1;
  elsif(datacnt=10)then            --0x0c  :    0000 1100 =>显示设定  整体显示开 无光标
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=11)then
        data<="1100";
        datacnt<=datacnt+1;  
  elsif(datacnt=12)then          --0x10  : 1000 0000 =>00H 设定读写地址位
       data<="1000";
       datacnt<=datacnt+1;
  else
       data<="0000";
       datacnt<=0;
       state<=Write_DataUP4_1;
  end if;
 when Write_DataUP4_1=>
       LCD_RS<='1';  
       data <= myram0_up(datacnt)(7 downto 4);
       state <= Write_DataDown4_1;
 when Write_DataDown4_1=>
      if datacnt=23 then
        data <= myram0_up(datacnt)(3 downto 0);
        datacnt<=0;
        state <=Set_DDRamAddUp;
       else
        data <= myram0_up(datacnt)(3 downto 0);
        datacnt<=datacnt+1;
        state <=Write_DataUP4_1;
       end if;
 when Set_DDRamAddUp=> --0xc0  :  1100 0000=>40H  设定读写地址位
        LCD_RS<='0';
        data<="1100";
        state<=Set_DDRamAddDown;
 when Set_DDRamAddDown=>
        data<="0000";
        state<=Write_DataUP4_2;
 when Write_DataUP4_2=>
       LCD_RS<='1';    
       data <= myram0_down(datacnt)(7 downto 4);
       state <= Write_DataDown4_2;
 when Write_DataDown4_2=>
        if datacnt=23 then
         data <= myram0_down(datacnt)(3 downto 0);
         datacnt<=0;
         state <=Write_DataUP4_1;
        else
         data <= myram0_down(datacnt)(3 downto 0);
         datacnt<=datacnt+1;
         state <=Write_DataUP4_2;
        end if;
 when others=>
      state<=Write_instr;
     end case;
   end if;
 when 2 =>  --第二次输入密钥
   if(enter='1') then
         if(key_decri=key_encri) then
         --显示 welocme!
   case state is
   when Write_instr=>              --写命令字到LCD控制器
       LCD_RS<='0'; 
   if(datacnt=0)then
        data<="0000";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=1)then
        data<="0001";             --0011
        datacnt<=datacnt+1;
   elsif(datacnt=2)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=3)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=4)then
        data<="0011";             --0011
        datacnt<=datacnt+1;
  elsif(datacnt=5)then
        data<="0010";             --0010
        datacnt<=datacnt+1; 
  elsif(datacnt=6)then            --0x28  :    0010 1000 =>功能设置 8位总线双行显示
        data<="0010";
        datacnt<=datacnt+1;
  elsif(datacnt=7)then
        data<="1000";
        datacnt<=datacnt+1;
  elsif(datacnt=8)then             --0x06  :   0000 0110 =>模式设定   光标右移,字符不动
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=9)then
        data<="0110";
        datacnt<=datacnt+1;
  elsif(datacnt=10)then            --0x0c  :    0000 1100 =>显示设定  整体显示开 无光标
        data<="0000";
        datacnt<=datacnt+1;
  elsif(datacnt=11)then
        data<="1100";
        datacnt<=datacnt+1;  
  elsif(datacnt=12)then          --0x10  : 1000 0000 =>00H 设定读写地址位
       data<="1000";
       datacnt<=datacnt+1;
  else
       data<="0000";
       datacnt<=0;
       state<=Write_DataUP4_1;
  end if;
 when Write_DataUP4_1=>
       LCD_RS<='1';  
       data <= myram1_up(datacnt)(7 downto 4);
       state <= Write_DataDown4_1;
 when Write_DataDown4_1=>
      if datacnt=23 then
        data <= myram1_up(datacnt)(3 downto 0);
        datacnt<=0;
        state <=Set_DDRamAddUp;
       else
        data <= myram1_up(datacnt)(3 downto 0);
        datacnt<=datacnt+1;
        state <=Write_DataUP4_1;
       end if;
 when Set_DDRamAddUp=> --0xc0  :  1100 0000=>40H  设定读写地址位
        LCD_RS<='0';
        data<="1100";
        state<=Set_DDRamAddDown;
 when Set_DDRamAddDown=>
        data<="0000";
        state<=Write_DataUP4_2;
 when Write_DataUP4_2=>
       LCD_RS<='1';    
       data <= myram1_down(datacnt)(7 downto 4);
       state <= Write_DataDown4_2;
 when Write_DataDown4_2=>
        if datacnt=23 then
         data <= myram1_down(datacnt)(3 downto 0);
         datacnt<=0;
         state <=Write_DataUP4_1;
        else
         data <= myram1_down(datacnt)(3 downto 0);
         datacnt<=datacnt+1;
         state <=Write_DataUP4_2;
        end if;
 when others=>
      state<=Write_instr;
     end case;
    else
         --显示 warning  one time!
   case state is
   when Write_instr=>              --写命令字到LCD控制器
       LCD_RS<='0'; 
   if(datacnt=0)then
     &

|
上一篇:uart控制器 | 下一篇:串口通信加密
以下网友评论只代表其个人观点,不代表本网站的观点或立场