wudi123baobei 发表于 2014-11-12 19:46:14

FPGA串行控制LCD12864


library ieee;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.lcdchar.all;

entity display12864 is      --LCD12864 display
generic( fclk : integer :=50000000);
      port(
                n_rst                : in std_logic;
                clk_in                : in std_logic;
                en                        : in std_logic;
                SID                        : out std_logic;
                SCLK                : out std_logic
                );
end display12864;

architecture rtl of display12864 is

constant div_num : integer :=fclk/500000;

--attention : '\' and '"' can't be displayed.
constant line1_str : string:="   test1      ";
constant line2_str : string:="       2      ";
constant line3_str : string:="      3       ";
constant line4_str : string:="       4      ";

signal clk_500KHz         : std_logic;
signal LCD_cnt                : integer range 0 to 71;
signal LCD_Data                : std_logic_vector(7 downto 0);
signal rs,LCD_cnt_en: std_logic;

signal clr                        : std_logic;
signal bit_cnt                : integer range 0 to 25;
signal delay_over      : std_logic;
constant delay_10ms      : integer := 500000/100;--delay 10 ms
constant delay_1ms      : integer := 500000/1000;--delay 1 ms
begin

--frequency division
      process(clk_in,n_rst)               
      variable div_cnt : integer range 0 to div_num-1 ;
      begin
      if(n_rst='0')then
                div_cnt:=0;
      elsif(clk_in'event and clk_in='1') then
                if(en='1')then
                        if(div_cnt>=div_num-1) then
                              div_cnt:=0;
                        else
                              if (div_cnt < div_num/2) then      
                                        clk_500KHz<='1';
                              else
                                        clk_500KHz<='0';
                              end if;
                              div_cnt:=div_cnt + 1;
                        end if;
                end if;
      end if;
      end process;

      process(clk_500KHz,n_rst)
      begin
      if(n_rst='0')then
                LCD_cnt<=0;
                rs<='0';
                LCD_Data<=x"00";
      elsif(clk_500KHz'event and clk_500KHz='1')then
                if(en='1')then
                        if(LCD_cnt>=71)then
                              LCD_cnt<=4;
                        elsif(delay_over='1')then
                              LCD_cnt<=LCD_cnt+1;
                        else
                              LCD_cnt<=LCD_cnt;
                        end if;
                        case LCD_cnt is
                              when 0                =>      rs<='0';LCD_Data<=x"30";
                              when 1                =>      rs<='0';LCD_Data<=x"01";
                              when 2                =>      rs<='0';LCD_Data<=x"06";
                              when 3                =>      rs<='0';LCD_Data<=x"0c";
                              
                              when 4                =>      rs<='0';LCD_Data<=x"80";                --first line
                              when 5                =>      rs<='1';LCD_Data<=str2vector(line1_str,1);
                              when 6                =>      rs<='1';LCD_Data<=str2vector(line1_str,2);
                              when 7                =>      rs<='1';LCD_Data<=str2vector(line1_str,3);
                              when 8                =>      rs<='1';LCD_Data<=str2vector(line1_str,4);
                              when 9                =>      rs<='1';LCD_Data<=str2vector(line1_str,5);
                              when 10                =>      rs<='1';LCD_Data<=str2vector(line1_str,6);
                              when 11                =>      rs<='1';LCD_Data<=str2vector(line1_str,7);
                              when 12                =>      rs<='1';LCD_Data<=str2vector(line1_str,8);
                              when 13                =>      rs<='1';LCD_Data<=str2vector(line1_str,9);
                              when 14                =>      rs<='1';LCD_Data<=str2vector(line1_str,10);
                              when 15                =>      rs<='1';LCD_Data<=str2vector(line1_str,11);
                              when 16                =>      rs<='1';LCD_Data<=str2vector(line1_str,12);
                              when 17                =>      rs<='1';LCD_Data<=str2vector(line1_str,13);
                              when 18                =>      rs<='1';LCD_Data<=str2vector(line1_str,14);
                              when 19                =>      rs<='1';LCD_Data<=str2vector(line1_str,15);
                              when 20                =>      rs<='1';LCD_Data<=str2vector(line1_str,16);
                              
                              when 21                =>      rs<='0';LCD_Data<=(x"90");      --second line
                              when 22                =>      rs<='1';LCD_Data<=str2vector(line2_str,1);
                              when 23                =>      rs<='1';LCD_Data<=str2vector(line2_str,2);
                              when 24                =>      rs<='1';LCD_Data<=str2vector(line2_str,3);
                              when 25                =>      rs<='1';LCD_Data<=str2vector(line2_str,4);
                              when 26                =>      rs<='1';LCD_Data<=str2vector(line2_str,5);
                              when 27                =>      rs<='1';LCD_Data<=str2vector(line2_str,6);
                              when 28                =>      rs<='1';LCD_Data<=str2vector(line2_str,7);
                              when 29                =>      rs<='1';LCD_Data<=str2vector(line2_str,8);
                              when 30                =>      rs<='1';LCD_Data<=str2vector(line2_str,9);
                              when 31                =>      rs<='1';LCD_Data<=str2vector(line2_str,10);
                              when 32                =>      rs<='1';LCD_Data<=str2vector(line2_str,11);
                              when 33                =>      rs<='1';LCD_Data<=str2vector(line2_str,12);
                              when 34                =>      rs<='1';LCD_Data<=str2vector(line2_str,13);
                              when 35                =>      rs<='1';LCD_Data<=str2vector(line2_str,14);
                              when 36                =>      rs<='1';LCD_Data<=str2vector(line2_str,15);
                              when 37                =>      rs<='1';LCD_Data<=str2vector(line2_str,16);
                              
                              when 38                =>      rs<='0';LCD_Data<=(x"88");      --third line
                              when 39                =>      rs<='1';LCD_Data<=str2vector(line3_str,1);
                              when 40                =>      rs<='1';LCD_Data<=str2vector(line3_str,2);
                              when 41                =>      rs<='1';LCD_Data<=str2vector(line3_str,3);
                              when 42                =>      rs<='1';LCD_Data<=str2vector(line3_str,4);
                              when 43                =>      rs<='1';LCD_Data<=str2vector(line3_str,5);
                              when 44                =>      rs<='1';LCD_Data<=str2vector(line3_str,6);
                              when 45                =>      rs<='1';LCD_Data<=str2vector(line3_str,7);
                              when 46                =>      rs<='1';LCD_Data<=str2vector(line3_str,8);
                              when 47                =>      rs<='1';LCD_Data<=str2vector(line3_str,9);
                              when 48                =>      rs<='1';LCD_Data<=str2vector(line3_str,10);
                              when 49                =>      rs<='1';LCD_Data<=str2vector(line3_str,11);
                              when 50                =>      rs<='1';LCD_Data<=str2vector(line3_str,12);
                              when 51                =>      rs<='1';LCD_Data<=str2vector(line3_str,13);
                              when 52                =>      rs<='1';LCD_Data<=str2vector(line3_str,14);
                              when 53                =>      rs<='1';LCD_Data<=str2vector(line3_str,15);
                              when 54                =>      rs<='1';LCD_Data<=str2vector(line3_str,16);
                              
                              when 55                =>      rs<='0';LCD_Data<=(x"98");      --forth line
                              when 56                =>      rs<='1';LCD_Data<=str2vector(line4_str,1);
                              when 57                =>      rs<='1';LCD_Data<=str2vector(line4_str,2);
                              when 58                =>      rs<='1';LCD_Data<=str2vector(line4_str,3);
                              when 59                =>      rs<='1';LCD_Data<=str2vector(line4_str,4);
                              when 60                =>      rs<='1';LCD_Data<=str2vector(line4_str,5);
                              when 61                =>      rs<='1';LCD_Data<=str2vector(line4_str,6);
                              when 62                =>      rs<='1';LCD_Data<=str2vector(line4_str,7);
                              when 63                =>      rs<='1';LCD_Data<=str2vector(line4_str,8);
                              when 64                =>      rs<='1';LCD_Data<=str2vector(line4_str,9);
                              when 65                =>      rs<='1';LCD_Data<=str2vector(line4_str,10);
                              when 66                =>      rs<='1';LCD_Data<=str2vector(line4_str,11);
                              when 67                =>      rs<='1';LCD_Data<=str2vector(line4_str,12);
                              when 68                =>      rs<='1';LCD_Data<=str2vector(line4_str,13);
                              when 69                =>      rs<='1';LCD_Data<=str2vector(line4_str,14);
                              when 70                =>      rs<='1';LCD_Data<=str2vector(line4_str,15);
                              when 71                =>      rs<='1';LCD_Data<=str2vector(line4_str,16);
                              
                              when others      =>      rs<='1';LCD_Data<=x"00";      
                        end case;
                end if;
      end if;
      end process;

--delay 10 ms counter
      process(clk_500KHz,n_rst)               
      variable cnt : integer range 0 to delay_10ms-1 ;
      begin
      if(n_rst='0')then
                cnt:=0;
                delay_over<='0';
                clr<='1';
      elsif(clk_500KHz'event and clk_500KHz='1') then
                if(LCD_cnt<=4)then
                        if(cnt=delay_10ms-1)then
                              delay_over<='1';
                              clr<='1';
                              cnt:=0;
                        else
                              delay_over<='0';
                              clr<='0';
                              if(bit_cnt=25)then
                                        cnt:=cnt+1;
                              end if;
                        end if;
                else
                        if(cnt=delay_1ms-1)then
                              delay_over<='1';
                              clr<='1';
                              cnt:=0;
                        else
                              delay_over<='0';
                              clr<='0';
                              if(bit_cnt=25)then
                                        cnt:=cnt+1;
                              end if;
                        end if;
                end if;
      end if;
      end process;
      
--output SCLK
      process(clk_in,n_rst)
      begin
      if(n_rst='0')then
                SCLK<='0';
      elsif(clk_in'event and clk_in='1') then
                if(en='1')then
                        if(bit_cnt>0 and bit_cnt<25)then
                              SCLK <= not clk_500KHz;
                        else
                              SCLK <= '0';
                        end if;
                end if;
      end if;
      end process;

--output SID
      process(clk_500KHz,n_rst)
      begin
      if(n_rst='0')then
                SID<='0';
                bit_cnt<=0;
      elsif(clk_500KHz'event and clk_500KHz='1')then
                if(clr='1')then
                        SID<='0';
                        bit_cnt<=0;
                else
                        case bit_cnt is
                              when 0                =>      SID<='1';bit_cnt<=bit_cnt+1;
                              when 1                =>      SID<='1';bit_cnt<=bit_cnt+1;
                              when 2                =>      SID<='1';bit_cnt<=bit_cnt+1;
                              when 3                =>      SID<='1';bit_cnt<=bit_cnt+1;
                              when 4                =>      SID<='1';bit_cnt<=bit_cnt+1;
                              when 5                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 6                =>      SID<=rs ;bit_cnt<=bit_cnt+1;
                              when 7                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 8                =>      SID<=LCD_Data(7);bit_cnt<=bit_cnt+1;
                              when 9                =>      SID<=LCD_Data(6);bit_cnt<=bit_cnt+1;
                              when 10                =>      SID<=LCD_Data(5);bit_cnt<=bit_cnt+1;
                              when 11                =>      SID<=LCD_Data(4);bit_cnt<=bit_cnt+1;
                              when 12                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 13                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 14                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 15                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 16                =>      SID<=LCD_Data(3);bit_cnt<=bit_cnt+1;
                              when 17                =>      SID<=LCD_Data(2);bit_cnt<=bit_cnt+1;
                              when 18                =>      SID<=LCD_Data(1);bit_cnt<=bit_cnt+1;
                              when 19                =>      SID<=LCD_Data(0);bit_cnt<=bit_cnt+1;
                              when 20                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 21                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 22                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 23                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 24                =>      SID<='0';bit_cnt<=bit_cnt+1;
                              when 25                =>      SID<='0';bit_cnt<=bit_cnt;
                              when others      =>      SID<='0';bit_cnt<=0;
                        end case;
                end if;
      end if;
      end process;
      
end rtl;

--str2vector函数
library ieee;
use ieee.std_logic_1164.all;
package lcdchar is
      function char2vector (char:in character)
      return std_logic_vector;
      function str2vector (str:in string;i:in integer)
      return std_logic_vector;
end lcdchar;
package body lcdchar is
      function char2vector (char:in character)
      return std_logic_vector is
      begin
                case char is
                when ' ' => return x"20";
                when '!' => return x"21";
                when '"' => return x"22";
                when '#' => return x"23";
                when '$' => return x"24";
                when '%' => return x"25";
                when '&' => return x"26";
                when ''' => return x"27";
                when '(' => return x"28";
                when ')' => return x"29";
                when '*' => return x"2a";
                when '+' => return x"2b";
                when ',' => return x"2c";
                when '-' => return x"2d";
                when '.' => return x"2e";
                when '/' => return x"2f";
                when '0' => return x"30";
                when '1' => return x"31";
                when '2' => return x"32";
                when '3' => return x"33";
                when '4' => return x"34";
                when '5' => return x"35";
                when '6' => return x"36";
                when '7' => return x"37";
                when '8' => return x"38";
                when '9' => return x"39";
                when ':' => return x"3a";
                when ';' => return x"3b";
                when '<' => return x"3c";
                when '=' => return x"3d";
                when '>' => return x"3e";
                when '?' => return x"3f";
                when '@' => return x"40";
                when 'A' => return x"41";
                when 'B' => return x"42";
                when 'C' => return x"43";
                when 'D' => return x"44";
                when 'E' => return x"45";
                when 'F' => return x"46";
                when 'G' => return x"47";
                when 'H' => return x"48";
                when 'I' => return x"49";
                when 'J' => return x"4a";
                when 'K' => return x"4b";
                when 'L' => return x"4c";
                when 'M' => return x"4d";
                when 'N' => return x"4e";
                when 'O' => return x"4f";
                when 'P' => return x"50";
                when 'Q' => return x"51";
                when 'R' => return x"52";
                when 'S' => return x"53";
                when 'T' => return x"54";
                when 'U' => return x"55";
                when 'V' => return x"56";
                when 'W' => return x"57";
                when 'X' => return x"58";
                when 'Y' => return x"59";
                when 'Z' => return x"5a";
                when '[' => return x"5b";
                when '\' => return x"5c";
                when ']' => return x"5d";
                when '^' => return x"5e";
                when '_' => return x"5f";
                when '`' => return x"60";
                when 'a' => return x"61";
                when 'b' => return x"62";
                when 'c' => return x"63";
                when 'd' => return x"64";
                when 'e' => return x"65";
                when 'f' => return x"66";
                when 'g' => return x"67";
                when 'h' => return x"68";
                when 'i' => return x"69";
                when 'j' => return x"6a";
                when 'k' => return x"6b";
                when 'l' => return x"6c";
                when 'm' => return x"6d";
                when 'n' => return x"6e";
                when 'o' => return x"6f";
                when 'p' => return x"70";
                when 'q' => return x"71";
                when 'r' => return x"72";
                when 's' => return x"73";
                when 't' => return x"74";
                when 'u' => return x"75";
                when 'v' => return x"76";
                when 'w' => return x"77";
                when 'x' => return x"78";
                when 'y' => return x"79";
                when 'z' => return x"7a";
                when '{' => return x"7b";
                when '|' => return x"7c";
                when '}' => return x"7d";
                when '~' => return x"7e";
                when others =>null;
                end case;
      end function char2vector;
      
      function str2vector (str:in string;i:in integer)
      return std_logic_vector is
      begin
                return char2vector(str(i));
      end function str2vector;
end package body;

--代码已验证过,相当好用
页: [1]
查看完整版本: FPGA串行控制LCD12864