0

これは、LCD のサブプログラムです。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity VideoTest is
    port( LCD_E, LCD_RS, LCD_RW : OUT std_logic;
            LCD_DB : OUT std_logic_vector(7 downto 0);
            counter: IN integer;
            clk: IN std_logic);

end VideoTest;

architecture Behavioral of VideoTest is
    signal InitDone: std_logic :='0';
begin

InitAndSet: process (InitDone, counter, clk) is
    variable tencounter: integer :=0;
    variable tempcounter: integer :=0;
begin
    if (clk'event and clk='1') then
        if (InitDone = '0') then
        -- Enabling
            LCD_E <='1';

        -- Clear Screen
            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 1) <= "0000000";
            LCD_DB(0) <= '1';

        -- Return Cursor Home

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 2) <= "000000";
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '0';

        -- Setting incrementation and moving cursor;

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 3) <= "00000";
            LCD_DB(2) <= '1';
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '0';

        -- Display On, show cursor, blink cursor

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 4) <= "0000";
            LCD_DB(3) <= '1';
            LCD_DB(2) <= '1';
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '1';

        -- Function set

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 6) <= "00";
            LCD_DB(5) <= '1';
            LCD_DB(4) <= '0';
            LCD_DB(3) <= '1';
            LCD_DB(2) <= '0';
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '1';

        -- Set DD Adress to 0

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7)<='1';
            LCD_DB(6 downto 0) <= "0000000";

            InitDone <= '0';
        end if;

        -- Setting the value (0 to 9 is equal to 00110000 to 00111001)
        if (InitDone = '1') then
            if (counter < 10) then
                LCD_RS<='1';
                LCD_RW<='0';
                case counter is
                    when 0 =>
                            LCD_DB <="00110000";
                    when 1 =>
                            LCD_DB <="00110001";
                    when 2 =>
                            LCD_DB <="00110010";
                    when 3 =>
                            LCD_DB <="00110011";
                    when 4 =>
                            LCD_DB <="00110100";
                    when 5 =>
                            LCD_DB <="00110101";
                    when 6 =>
                            LCD_DB <="00110110";
                    when 7 =>
                            LCD_DB <="00110111";
                    when 8 =>
                            LCD_DB <="00111000";
                    when 9 =>
                            LCD_DB <="00111001";
                    when others =>
                            LCD_DB <="00000000";
                end case;
            -- if counter is greater than 10, then put the number in two addresses.
            elsif (counter > 9) then

                LCD_DB <="00000000";
                tempcounter :=counter;
                for i in 0 to 8 loop
                    if tempcounter > 9 then
                        tempcounter := tempcounter - 10;
                    end if;
                end loop;
                tencounter := counter - tempcounter;

                case tencounter is
                    when 0 =>
                            LCD_DB <="00110000";
                    when 1 =>
                            LCD_DB <="00110001";
                    when 2 =>
                            LCD_DB <="00110010";
                    when 3 =>
                            LCD_DB <="00110011";
                    when 4 =>
                            LCD_DB <="00110100";
                    when 5 =>
                            LCD_DB <="00110101";
                    when 6 =>
                            LCD_DB <="00110110";
                    when 7 =>
                            LCD_DB <="00110111";
                    when 8 =>
                            LCD_DB <="00111000";
                    when 9 =>
                            LCD_DB <="00111001";
                    when others =>
                            LCD_DB <="00000000";
                end case;

                LCD_RS<='0';
                LCD_RW<='0';
                LCD_DB(7)<='1';
                LCD_DB(6 downto 1) <= "000000";
                LCD_DB(0) <='1';

                case tempcounter is
                    when 0 =>
                            LCD_DB <="00110000";
                    when 1 =>
                            LCD_DB <="00110001";
                    when 2 =>
                            LCD_DB <="00110010";
                    when 3 =>
                            LCD_DB <="00110011";
                    when 4 =>
                            LCD_DB <="00110100";
                    when 5 =>
                            LCD_DB <="00110101";
                    when 6 =>
                            LCD_DB <="00110110";
                    when 7 =>
                            LCD_DB <="00110111";
                    when 8 =>
                            LCD_DB <="00111000";
                    when 9 =>
                            LCD_DB <="00111001";
                    when others =>
                            LCD_DB <="00000000";
                end case;

            end if;
        end if;
    end if;

end process InitAndSet;


end Behavioral;

ユーザー制約は次のとおりです。

-- Constraints
NET "LCD_E" LOC = "AB4" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_RS" LOC = "Y14" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_RW" LOC = "W13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<7>" LOC = "Y15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<6>" LOC = "AB16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<5>" LOC = "Y16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<4>" LOC = "AA12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<3>" LOC = "AB12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<2>" LOC = "AB17" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<1>" LOC = "AB18" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<0>" LOC = "Y13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

私が見たように、メモリに保存された古いものをすべてクリアしたので、このプログラムは LCD ディスプレイをアクティブにする必要があります。画面上の番号を示します。制約とエンコーディングは、Spartan 3AN - ビギナー キットのユーザー マニュアルから直接取得しました。

何か不足していますか?電源が入っていないかのように動作します。

前もって感謝します、ボーヤン・マトフスキー

4

1 に答える 1

1
if (clk'event and clk='1') then
    if (InitDone = '0') then
    -- Enabling
        LCD_E <='1';

    -- Clear Screen
        LCD_RS<='0';
        LCD_RW<='0';
        LCD_DB(7 downto 1) <= "0000000";
        LCD_DB(0) <= '1';
        etc etc etc.....

1 つの問題: この最初の部分でステート マシンが欠落しています。Case ステートメントと、それらがステート マシンでどのように機能するかを確認してください。あなたが書いたコードで何が起こるかというと、LCD_RD、LCD_RW などは、その if ステートメントにあるコードの最後の行に置き換えられるだけです。それ以前のものはすべて未使用になります。

別の問題: InitDone が '1' に設定されない。これまで。

さらに別の問題:

for i in 0 to 8 loop
    if tempcounter > 9 then
         tempcounter := tempcounter - 10;
    end if;
end loop;

この for ループは、あなたが思っているようには動作しません。合成可能なコードの for ループについて読む必要があります。C の for ループのようには動作しません。

于 2013-09-24T14:14:21.923 に答える