FPGA驱动12864液晶

来源:互联网 发布:网络司法拍卖 变卖 编辑:程序博客网 时间:2024/05/01 12:02

 LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY lcd12864 IS
  PORT(
 CLK: IN STD_LOGIC;
 ROM_DATA: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
 RS,RW,CS1,CS2,E: OUT STD_LOGIC;
 ADDRESS: OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
 Q: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
 );
END;
ARCHITECTURE BEHAV OF lcd12864 IS
 TYPE STATES IS(ST0,ST1,ST2,ST3,ST4,ST5,ST6,ST7,
    ST8,ST9,ST10,ST11,ST12,ST13,ST14,ST15);                      --状态定意
 SIGNAL PRE_STATE,NEXT_STATE:STATES;
 SIGNAL DATALOCK,EN,RST1:STD_LOGIC;
 SIGNAL ADDR:INTEGER RANGE 0 TO 65:=0;
 SIGNAL XPAGE:STD_LOGIC_VECTOR(7 DOWNTO 0):="10111000";
 SIGNAL YADDR:STD_LOGIC_VECTOR(7 DOWNTO 0):="01000000";
BEGIN
  CLOCK:PROCESS(CLK)                                                      --将时钟进行分频
         VARIABLE CONT:INTEGER RANGE 0 TO 20;
           BEGIN
             IF CLK'EVENT AND CLK='1' THEN
                CONT:=CONT+1;
                IF CONT = 12 THEN DATALOCK<='0';CONT:=0;
                ELSIF CONT = 9 THEN
                      DATALOCK<='1';
                END IF;
             END IF;
  END PROCESS CLOCK;
  EN<= NOT DATALOCK;
  E<=EN;

  DATAK:PROCESS(EN,PRE_STATE)
     BEGIN
        IF EN'EVENT AND EN='1' THEN
    CASE PRE_STATE IS
     WHEN ST0=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="00111110";PRE_STATE<=ST1;   --显示开关设置       
     WHEN ST1=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="00111110";PRE_STATE<=ST2;  
     WHEN ST2=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="11000000";PRE_STATE<=ST3;  --起始行设置
 --左半清屏  
     WHEN ST3=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<=XPAGE;PRE_STATE<=ST4;  --页地址设置
     WHEN ST4=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<=YADDR;PRE_STATE<=ST5;  --列地址设置
     WHEN ST5=>RS<='1';RW<='0';CS1<='0';CS2<='1';                 
          IF XPAGE>"10111111" THEN
             XPAGE<="10111000";
       YADDR<="01000000";
             PRE_STATE<=ST6;                                   --左半清屏完毕,进入下一状态
          ELSIF YADDR>"01111111" THEN
             YADDR<="01000000";
             XPAGE<=XPAGE+1;                                  --清完一页,开始下一页
       PRE_STATE<=ST3;                                 --返回重新设置页地址                     
        ELSE
          Q<="00000000";YADDR<=YADDR+1;PRE_STATE<=ST5;                  --清完一列,开始下一列      
       END IF;
 --右半清屏
     WHEN ST6=>RS<='0';RW<='0';CS1<='1';CS2<='0';Q<=XPAGE;PRE_STATE<=ST7;  --页地址设置
     WHEN ST7=>RS<='0';RW<='0';CS1<='1';CS2<='0';Q<=YADDR;PRE_STATE<=ST8;  --列地址设置
     WHEN ST8=>RS<='1';RW<='0';CS1<='1';CS2<='0';                  
          IF XPAGE>"10111111" THEN
             XPAGE<="10111000";
       YADDR<="01000000";
             PRE_STATE<=ST9;                                    ----右半清屏完毕,进入下一状态
          ELSIF YADDR>"01111111" THEN
             YADDR<="01000000";
             XPAGE<=XPAGE+1;                                  --清完一页,开始下一页
       PRE_STATE<=ST6;                                  --返回重新设置页地址
          ELSE
          Q<="00000000";YADDR<=YADDR+1;PRE_STATE<=ST8;            --清完一列,开始下一列    
       END IF;
 --清屏完毕,开始显示数据
       --显示上半边
              WHEN ST9=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="00111111";PRE_STATE<=ST10;   --显示开关设置
     WHEN ST10=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="10111011";PRE_STATE<=ST11;  --页地址设置 第三页
     WHEN ST11=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="01000001";PRE_STATE<=ST12;  --列地址设置 第1列
     WHEN ST12=>RS<='1';RW<='0';CS1<='0';CS2<='1';
          IF ADDR>15  THEN
             YADDR<="01000000";
             PRE_STATE<=ST13;                             --显示完上半边后显示下半边
          ELSE
       Q<=ROM_DATA;
       ADDR<=ADDR+1;
       YADDR<=YADDR+1;
             PRE_STATE<=ST12;
          END IF;
  --显示下半边  
     WHEN ST13=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="10111100";PRE_STATE<=ST14;  --页地址设置 第四页
     WHEN ST14=>RS<='0';RW<='0';CS1<='0';CS2<='1';Q<="01000001";PRE_STATE<=ST15;  --列地址设置 第1列
     WHEN ST15=>RS<='1';RW<='0';CS1<='0';CS2<='1';
          IF ADDR>31  THEN
       ADDR<=0;
       YADDR<="01000000";
             PRE_STATE<=ST10;                              --显示完毕后又重新显示
          ELSE
             Q<=ROM_DATA;
       ADDR<=ADDR+1;
       YADDR<=YADDR+1;
             PRE_STATE<=ST15;
          END IF;
     WHEN OTHERS=>PRE_STATE<=ST0;    
    END CASE;
   END IF;
  ADDRESS<=CONV_STD_LOGIC_VECTOR(ADDR,5);    
   END PROCESS DATAK;
END BEHAV;