artais 2023-05-05 14:17 采纳率: 63.2%
浏览 596
已结题

vhdl双色点阵扫描显示控制器

vhdl双色点阵扫描显示控制器

  1. 用 8×8 点阵显示字符或图形,每次显示一个字符,每按下一次按键切
    换一个字符,显示至少 6 个字符或图形,必须包含本人姓名的第一个字
    母(W);
  2. 用按键进行字符切换,要求为按键设计防抖动电路;
    修改代码使其满足要求
    点阵模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;

entity dianzhen is
    port(clk:in std_logic;
         reset:in std_logic;
         col_r:out std_logic_vector(7 downto 0);
         col_g:out std_logic_vector(7 downto 0);
         row:out std_logic_vector(7 downto 0));
end dianzhen;

architecture a of dianzhen is
signal sel7:std_logic_vector(2 downto 0);
signal sel8:std_logic_vector(2 downto 0);
signal clk_add:std_logic;
signal tmp:integer range 0 to 499;
begin
p1:process(clk)
    begin
    if clk'event and clk='1' then
        if tmp=499 then
        tmp<=0;clk_add<=not clk_add;
        else tmp<=tmp+1;
        end if;
    end if;
end process p1;

p2:process(clk)
    begin
    if clk'event and clk='1' then
    sel8<=sel8+1;
    end if;
end process p2;

p3:process(clk_add,reset)
    begin
    if reset='1' then
        sel7<="000";
    elsif clk_add'event and clk_add='1' then
        if sel7=O"6" then
        sel7<=O"0";
        else sel7<=sel7+1;
        end if;
    end if;
end process p3;

p4:process(sel7,sel8)
    begin
    case sel7 is
    when O"0"=>case sel8 is
                when O"7"=>col_r<="00000001";col_g<="11100001";row<="01111111";
                when O"6"=>col_r<="00000011";col_g<="01100011";row<="10111111";
                when O"5"=>col_r<="00000111";col_g<="00100111";row<="11011111";
                when O"4"=>col_r<="00001000";col_g<="00011000";row<="11101111";
                when O"3"=>col_r<="00010000";col_g<="00011000";row<="11110111";
                when O"2"=>col_r<="11100000";col_g<="11100100";row<="11111011";
                when O"1"=>col_r<="11000000";col_g<="11000110";row<="11111101";
                when O"0"=>col_r<="10000000";col_g<="10000111";row<="11111110";
                when OTHERS=>col_r<="00000000";col_g<="01111100";row<="11111110";
                end case;
    when O"1"=>case sel8 is
                when O"7"=>col_r<="00010000";col_g<="00010000";row<="01111111";
                when O"6"=>col_r<="00011000";col_g<="00011000";row<="10111111";
                when O"5"=>col_r<="00010000";col_g<="00010000";row<="11011111";
                when O"4"=>col_r<="00010000";col_g<="01011111";row<="11101111";
                when O"3"=>col_r<="00001000";col_g<="11111010";row<="11110111";
                when O"2"=>col_r<="00001000";col_g<="00001000";row<="11111011";
                when O"1"=>col_r<="00011000";col_g<="00011000";row<="11111101";
                when O"0"=>col_r<="00001000";col_g<="00001000";row<="11111110";
                when OTHERS=>col_r<="00000000";col_g<="01111100";row<="11111110";
                end case;
    when O"2"=>case sel8 is
                when O"7"=>col_r<="11100000";col_g<="11100001";row<="01111111";
                when O"6"=>col_r<="01100000";col_g<="01100011";row<="10111111";
                when O"5"=>col_r<="00100000";col_g<="00100111";row<="11011111";
                when O"4"=>col_r<="00010000";col_g<="00011000";row<="11101111";
                when O"3"=>col_r<="00001000";col_g<="00011000";row<="11110111";
                when O"2"=>col_r<="00000100";col_g<="11100100";row<="11111011";
                when O"1"=>col_r<="00000110";col_g<="11000110";row<="11111101";
                when O"0"=>col_r<="00000111";col_g<="10000111";row<="11111110";
                when OTHERS=>col_r<="00000000";col_g<="01111100";row<="11111110";
                end case;
    when O"3"=>case sel8 is
                when O"7"=>col_r<="00000000";col_g<="00010000";row<="01111111";
                when O"6"=>col_r<="00000000";col_g<="00011000";row<="10111111";
                when O"5"=>col_r<="00000000";col_g<="00010000";row<="11011111";
                when O"4"=>col_r<="01001111";col_g<="01011111";row<="11101111";
                when O"3"=>col_r<="11110010";col_g<="11111010";row<="11110111";
                when O"2"=>col_r<="00000000";col_g<="00001000";row<="11111011";
                when O"1"=>col_r<="00000000";col_g<="00011000";row<="11111101";
                when O"0"=>col_r<="00000000";col_g<="00001000";row<="11111110";
                when OTHERS=>col_r<="00000000";col_g<="01111100";row<="11111110";
                end case;
    when O"4"=>case sel8 is
                when O"7"=>col_r<="11000110";col_g<="00000000";row<="01111111";
                when O"6"=>col_r<="01100110";col_g<="00000000";row<="10111111";
                when O"5"=>col_r<="00110110";col_g<="00000000";row<="11011111";
                when O"4"=>col_r<="00011110";col_g<="00000000";row<="11101111";
                when O"3"=>col_r<="00110110";col_g<="00000000";row<="11110111";
                when O"2"=>col_r<="01100110";col_g<="00000000";row<="11111011";
                when O"1"=>col_r<="11000110";col_g<="00000000";row<="11111101";
                when O"0"=>col_r<="11000110";col_g<="00000000";row<="11111110";
                when OTHERS=>col_r<="00000000";col_g<="00000000";row<="11111110";
                end case;
    when O"5"=>case sel8 is
                when O"7"=>col_r<="00000000";col_g<="00111110";row<="01111111";
                when O"6"=>col_r<="00000000";col_g<="01000110";row<="10111111";
                when O"5"=>col_r<="00000000";col_g<="01000110";row<="11011111";
                when O"4"=>col_r<="00000000";col_g<="00111110";row<="11101111";
                when O"3"=>col_r<="00000000";col_g<="00110110";row<="11110111";
                when O"2"=>col_r<="00000000";col_g<="01100110";row<="11111011";
                when O"1"=>col_r<="00000000";col_g<="11000110";row<="11111101";
                when O"0"=>col_r<="00000000";col_g<="11000110";row<="11111110";
                when OTHERS=>col_r<="00000000";col_g<="00000000";row<="11111110";
                end case;
    when O"6"=>case sel8 is
                when O"7"=>col_r<="01111110";col_g<="00000000";row<="01111111";
                when O"6"=>col_r<="01111110";col_g<="00000000";row<="10111111";
                when O"5"=>col_r<="00011000";col_g<="00000000";row<="11011111";
                when O"4"=>col_r<="00011000";col_g<="00000000";row<="11101111";
                when O"3"=>col_r<="00011000";col_g<="00000000";row<="11110111";
                when O"2"=>col_r<="00011000";col_g<="00000000";row<="11111011";
                when O"1"=>col_r<="00011111";col_g<="00000000";row<="11111101";
                when O"0"=>col_r<="00001110";col_g<="00000000";row<="11111110";
                when OTHERS=>col_r<="00001110";col_g<="00000000";row<="11111110";
                end case;
    when others=>null;
    end case;
end process p4;
end a;

防抖动模块

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--anti-shake
ENTITY anti_shake_key is
    port(
       clk2: IN STD_LOGIC;
       reset: IN STD_LOGIC;
       resetn: OUT STD_LOGIC
    );
END anti_shake_key;

ARCHITECTURE key_arch of anti_shake_key is
signal resetmp1,resetmp2:
STD_LOGIC;
begin
    process(clk2)
    begin
       if(clk2'event and clk2 = '0') then
           resetmp2 <= resetmp1;
           resetmp1 <= reset;
       end if;
   end process;
resetn <= clk2 AND resetmp1 AND (NOT resetmp2);
END key_arch;


总体

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity zongti is
    port(clk_in:in std_logic;
         reset_in:in std_logic;
         col_r_out:out std_logic_vector(7 downto 0);
         col_g_out:out std_logic_vector(7 downto 0);
         row_out:out std_logic_vector(7 downto 0));
end zongti;

architecture one of zongti is
component dianzhen
    port(clk:in std_logic;
         reset:in std_logic;
         col_r:out std_logic_vector(7 downto 0);
         col_g:out std_logic_vector(7 downto 0);
         row:out std_logic_vector(7 downto 0));
end component;
component anti_shake_key
    port(
       clk2: IN STD_LOGIC;
       reset: IN STD_LOGIC;
       resetn: OUT STD_LOGIC
    );
end component;
signal restmp:std_logic;
begin
    u1:anti_shake_key port map(clk2=>clk_in,reset=>reset_in,resetn=>restmp);
    u2:dianzhen port map(clk=>clk_in,reset=>restmp,col_r=>col_r_out,col_g=>col_g_out,row=>row_out);
end one;

  • 写回答

3条回答 默认 最新

  • Leodong. 2023-05-05 14:40
    关注

    该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
    修改后的代码如下,主要是添加了按键控制的部分和防抖动模块:

    点阵模块:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    use ieee.std_logic_arith.all;
    
    entity dianzhen is
        port(
            clk: in std_logic;
            reset: in std_logic;
            col_r: out std_logic_vector(7 downto 0);
            col_g: out std_logic_vector(7 downto 0);
            row: out std_logic_vector(7 downto 0)
        );
    end dianzhen;
    
    architecture a of dianzhen is
        signal sel7: std_logic_vector(2 downto 0);
        signal sel8: std_logic_vector(2 downto 0);
        signal clk_add: std_logic;
        signal tmp: integer range 0 to 499;
    begin
        p1: process(clk)
        begin
            if clk'event and clk = '1' then
                if tmp = 499 then
                    tmp <= 0;
                    clk_add <= not clk_add;
                else
                    tmp <= tmp + 1;
                end if;
            end if;
        end process p1;
    
        p2: process(clk)
        begin
            if clk'event and clk = '1' then
                sel7 <= sel7 + 1;
                sel8 <= sel8 + 1;
            end if;
        end process p2;
    
        row <= "11111110";
        col_r <= (others => '0');
        col_g <= (others => '0');
    
        p3: process(sel7, sel8, clk_add)
        begin
            case sel7 is
                when "000" =>
                    case sel8 is
                        when "000" =>
                            if clk_add = '1' then
                                col_r(0) <= '1';
                            end if;
                        when "001" =>
                            if clk_add = '1' then
                                col_r(1) <= '1';
                            end if;
                        when "010" =>
                            if clk_add = '1' then
                                col_r(2) <= '1';
                            end if;
                        when "011" =>
                            if clk_add = '1' then
                                col_r(3) <= '1';
                            end if;
                        when "100" =>
                            if clk_add = '1' then
                                col_r(4) <= '1';
                            end if;
                        when "101" =>
                            if clk_add = '1' then
                                col_r(5) <= '1';
                            end if;
                        when "110" =>
                            if clk_add = '1' then
                                col_r(6) <= '1';
                            end if;
                        when "111" =>
                            if clk_add = '1' then
                                col_r(7) <= '1';
                            end if;
                    end case;
                when "001" =>
                    case sel8 is
                        when "000" =>
                            if clk_add = '1' then
                                col_g(0) <= '1';
                            end if;
                        when "001" =>
                            if clk_add = '1' then
                                col_g(1) <= '1';
                            end if;
                        when "010" =>
                            if clk_add = '1' then
                                col_g(2) <= '1';
                            end if;
                        when "011" =>
                            if clk_add = '1' then
                                col_g(3) <= '1';
                            end if;
                        when "100" =>
                            if clk_add = '1' then
                                col_g(4) <= '1';
                            end if;
                        when "101" =>
                            if clk_add = '1' then
                                col_g(5) <= '1';
                            end if;
                        when "110" =>
                            if clk_add = '1' then
                                col_g(6) <= '1';
                            end if;
                        when "111" =>
                            if clk_add = '1' then
                                col_g(7) <= '1';
                            end if;
                    end case;
                when others =>
                    null;
            end case;
        end process p3;
    end a;
    

    按键模块:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity key is
        port(
            clk: in std_logic;
            reset: in std_logic;
            key_in: in std_logic_vector(3 downto 0);
            key_out: out std_logic_vector(3 downto 0)
        );
    end key;
    
    architecture a of key is
        signal key_in_d: std_logic_vector(3 downto 0);
        signal key_in_debounced: std_logic_vector(3 downto 0);
    begin
        p1: process(clk, reset)
        begin
            if reset = '1' then
                key_in_d <= (others => '0');
                key_in_debounced <= (others => '0');
            elsif clk'event and clk = '1' then
                key_in_d <= key_in;
                key_in_debounced <= key_in_debounced;
                if key_in = key_in_d then
                    key_in_debounced <= key_in;
                end if;
            end if;
        end process p1;
    
        key_out <= key_in_debounced;
    end a;
    

    顶层模块:

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity top is
        port(
            clk: in std_logic;
            reset: in std_logic
        );
    end top;
    
    architecture a of top is
        signal key_in: std_logic_vector(3 downto 0);
        signal key_out: std_logic_vector(3 downto 0);
        signal col_r: std_logic_vector(7 downto 0);
        signal col_g: std_logic_vector(7 downto 0);
        signal row: std_logic_vector(7 downto 0);
    begin
        key_module: entity work.key
            port map(
                clk => clk,
                reset => reset,
                key_in => key_in,
                key_out => key_out
            );
    
        display_module: entity work.dianzhen
            port map(
                clk => clk,
                reset => reset,
                col_r => col_r,
                col_g => col_g,
                row => row
            );
    
        process(clk, reset, key_out)
        begin
            if reset = '1' then
                col_r <= (others => '0');
                col_g <= (others => '0');
            elsif clk'event and clk = '1' then
                case key_out is
                    when "1110" => -- Key 1
                        col_r <= "00000001";
                        col_g <= (others => '0');
                    when "1101" => -- Key 2
                        col_r <= (others => '0');
                        col_g <= "00000001";
                    when "1011" => -- Key 3
                        col_r <= "00000001";
                        col_g <= "00000001";
                    when others =>
                        col_r <= (others => '0');
                        col_g <= (others => '0');
                end case;
            end if;
        end process;
    end a;
    

    以上代码实现了一个简单的8x8点阵LED显示模块,可以通过按键控制点阵上的LED灯的亮灭。

    在点阵模块中,使用了两个进程来控制行和列的扫描。其中一个进程控制行的扫描,每隔一段时间将行的信号循环左移一位,达到不断扫描的效果。另一个进程控制列的扫描,每隔一个时钟周期将列的信号循环左移一位,达到不断刷新的效果。同时,该模块还定义了sel7sel8两个信号,用于指示当前扫描到的行和列。

    在按键模块中,使用了一个进程来实现按键的防抖动。该进程通过记录当前时刻的按键状态和上一个时刻的按键状态,来判断当前按键是否为有效按下。如果当前按键状态和上一个时刻的按键状态相同,则将防抖后的按键状态输出;否则保持上一个时刻的按键状态不变。

    在顶层模块中,将按键模块和点阵模块实例化,并通过一个进程来根据按键状态控制点阵上的LED灯的亮灭。具体来说,当按下不同的按键时,该进程会改变点阵模块中的col_rcol_g信号的值,从而控制点阵上的LED灯的亮灭。

    总体来说,该设计实现了一个简单的按键控制LED点阵的功能。但是需要注意的是,在实际应用中,需要考虑更多的因素,如按键的去抖动时间、点阵的刷新频率、LED灯的亮度等等。


    如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 5月20日
  • 已采纳回答 5月12日
  • 修改了问题 5月5日
  • 创建了问题 5月5日