kramann.info
© Guido Kramann

Login: Passwort:










22 Übung

22 (EN google-translate)

22 (PL google-translate)


Bitte verbinden Sie die Taster in der Schaltung genau so wie in der hier unten zu sehenden aktuellen Version, um Schäden an der Hardware zu vermeiden!


Entwickeln Sie mit Hilfe des FPGA-Boards eine Uhr mit 24-Stunden-Anzeige und Minutenanzeige oder eine Stoppuhr mit Sekunden (0..99) und Hundertstelsekunden.

Als Anzeigeelement wird ein LTC-2723WC Element benutzt.

Datenblatt zu LTC-2723WC.

Verwenden Sie als Vorwiderstand an den Anoden 2200 Ohm. An den Katoden wird kein Widerstand vorgeschaltet.

Die Uhr / Stoppuhr soll mit entsprechenden Buttons ausgerüstet sein: Stunden+/- Minuten+/- bzw. Start Stop Reset

Teilaufgaben
  1. Machen Sie sich mit dem Anzeigemodul vertraut und steuern es testweise auf einfache Weise an.
  2. Überlegen Sie sich ein Konzept, wie die vier 7-Segmentanzeigen angesteuert werden können.
  3. Entwerfen Sie die Pin-Zuordnungen / den Gesamtschaltplan
  4. ACHTUNG: Es wird nun ein gemeinsames für alle verbindliches Konzept für die Pinzuordnung festgelegt!
  5. Schreiben Sie ein Programm, das den Doppelpunkt mit 1Hz blinken läßt.
  6. Schreiben Sie ein Programm, das nacheinander in jedem Digit und dem Doppelpunkt A,B,C,D,E,F,G anspricht. Wechsel mit 4Hz, also DIGIT1: A,B,C,D,E,F,G; DIGIT2 A,B,C,D,E,F,G; ... und dann wieder von vorne.
  7. Schreiben Sie ein Programm, mit dem Sie alle Taster einzeln testen können. ACHTUNG: Unbedingt alle Leitungen als digitale Eingänge. Jeweils untere Leitung eines Tasters auf Masse legen. Siehe Bild unten.
  8. Vollenden Sie die Uhr / Stoppuhr.
Pinzuordnungen / Überblick.

Bild 22-1: Pinzuordnungen / Überblick.

uhr003.zip - Musterlösung.

Hinweise zur Musterlösung

  • Die Uhr läuft 120mal schneller als eine normale Uhr (damit man schneller sieht, dass sie funktioniert)
  • Der Doppelpunkt wird nicht angesprochen.
  • Statt dessen gibt es ein Wechselblinken der roten und der grünen LED.
  • Obere Taste: Minute dekrementieren, mittlere Taste: Minute inkrementieren, untere Taste: Stunde inkrementieren.

Quelltexte zur Musterlösung

1. uhr.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;


entity uhr is
    Port ( MEINECLOCK : in  STD_LOGIC;
           LEDROT : out  STD_LOGIC;
           LEDGRUEN : out  STD_LOGIC;
           DIGIT12P34 : out  STD_LOGIC_VECTOR (4 downto 0);
           ABCDEFG : out  STD_LOGIC_VECTOR (6 downto 0);
           GROUND123 : out  STD_LOGIC_VECTOR (2 downto 0);
           TASTE123 : in  STD_LOGIC_VECTOR (2 downto 0));
end uhr;

architecture Behavioral of uhr is

--                                     ABCDEFG
constant ZIFFER0: STD_LOGIC_VECTOR := "1111110";
constant ZIFFER1: STD_LOGIC_VECTOR := "0110000";
constant ZIFFER2: STD_LOGIC_VECTOR := "1101101";
constant ZIFFER3: STD_LOGIC_VECTOR := "1111001";
constant ZIFFER4: STD_LOGIC_VECTOR := "0110011";
constant ZIFFER5: STD_LOGIC_VECTOR := "1011011";
constant ZIFFER6: STD_LOGIC_VECTOR := "1011111";
constant ZIFFER7: STD_LOGIC_VECTOR := "1110000";
constant ZIFFER8: STD_LOGIC_VECTOR := "1111111";
constant ZIFFER9: STD_LOGIC_VECTOR := "1111011";


    signal zaehler    : integer range 0 to 2999999 := 0;
    signal D1     : integer range 0 to 9 := 0; -- Stunden obere Stelle
    signal D2     : integer range 0 to 9 := 0; -- Stunden untere Stelle
    signal D3     : integer range 0 to 9 := 0; -- Minuten obere Stelle
    signal D4     : integer range 0 to 9 := 0; -- Minuten untere Stelle
    signal D1_anzeige : std_logic_vector (6 downto 0) := "0000000";
    signal D2_anzeige : std_logic_vector (6 downto 0) := "0000000";
    signal D3_anzeige : std_logic_vector (6 downto 0) := "0000000";
    signal D4_anzeige : std_logic_vector (6 downto 0) := "0000000";
	 	 
    signal logikpegel : std_logic := '0';
    signal auswahl    : std_logic_vector (4 downto 0) := "01111";
    signal tasten    : std_logic_vector (2 downto 0) := "111";
	 
	 signal blockiert : std_logic := '0';
	 
    begin
       process begin
            wait until rising_edge(MEINECLOCK);
				
				
            if (zaehler<2999999) then
                zaehler <= zaehler+1;
            else -- schalten im Halb-Sekundentakt
                blockiert <= '0';				
                zaehler <= 0;
                logikpegel <= not logikpegel;
                if(D4<9) then 
                    D4 <= D4+1;  -- Minuten untere Stelle
                else
                    D4 <= 0;
                    if(D3<5) then
                        D3 <= D3+1; -- Minuten obere Stelle
                    else
                        D3 <= 0; 
                        if( ((D2<9) and (D1<2)) or ((D2<3) and (D1=2)) ) then -- Stunden untere Stelle
                            D2 <= D2+1;
                        else
                            D2 <= 0;
                            if(D1<2) then -- Stunden obere Stelle
                                D1 <= D1+1;
                            else
                                D1 <= 0;
                            end if;										 
                        end if;									 
                    end if;						  
                 end if;
            end if;
				
            if ( (TASTE123(0) = '0') and (blockiert='0')) then 
                 blockiert <= '1';
                 if( ((D2<9) and (D1<2)) or ((D2<3) and (D1=2)) ) then -- Stunden untere Stelle
                     D2 <= D2+1;
                 else
                     D2 <= 0;
                     if(D1<2) then -- Stunden obere Stelle
                         D1 <= D1+1;
                     else
                         D1 <= 0;
                     end if;										 
                  end if;									 
             elsif ( (TASTE123(1) = '0') and (blockiert='0') ) then 
                  blockiert <= '1';
                  if(D4<9) then 
                      D4 <= D4+1;  -- Minuten untere Stelle
                  else
                      D4 <= 0;
                      if(D3<5) then
                          D3 <= D3+1; -- Minuten obere Stelle
                      else
                          D3 <= 0; 
                      end if;
                  end if;	  
             elsif ( (TASTE123(2) = '0') and (blockiert='0') ) then 
                  blockiert <= '1';				
                  if(D4>1) then 
                      D4 <= D4-2;  -- Minuten untere Stelle
                  else
                      D4 <= 9;
                      if(D3>0) then
                          D3 <= D3-1; -- Minuten obere Stelle
                      else
                          D3 <= 5; 
                      end if;
                  end if;	  
             end if;								
-- Umwandlung Ziffer in Digit:				
				case D1 is
				    when 0 => 
					     D1_anzeige <= ZIFFER0;  
				    when 1 => 
					     D1_anzeige <= ZIFFER1;  
				    when 2 => 
					     D1_anzeige <= ZIFFER2;  
				    when 3 => 
					     D1_anzeige <= ZIFFER3;  
				    when 4 => 
					     D1_anzeige <= ZIFFER4;  
				    when 5 => 
					     D1_anzeige <= ZIFFER5;  
				    when 6 => 
					     D1_anzeige <= ZIFFER6;  
				    when 7 => 
					     D1_anzeige <= ZIFFER7;  
				    when 8 => 
					     D1_anzeige <= ZIFFER8;  
				    when 9 => 
					     D1_anzeige <= ZIFFER9;  
				end case;
				
				case D2 is
				    when 0 => 
					     D2_anzeige <= ZIFFER0;  
				    when 1 => 
					     D2_anzeige <= ZIFFER1;  
				    when 2 => 
					     D2_anzeige <= ZIFFER2;  
				    when 3 => 
					     D2_anzeige <= ZIFFER3;  
				    when 4 => 
					     D2_anzeige <= ZIFFER4;  
				    when 5 => 
					     D2_anzeige <= ZIFFER5;  
				    when 6 => 
					     D2_anzeige <= ZIFFER6;  
				    when 7 => 
					     D2_anzeige <= ZIFFER7;  
				    when 8 => 
					     D2_anzeige <= ZIFFER8;  
				    when 9 => 
					     D2_anzeige <= ZIFFER9;  
				end case;

				case D3 is
				    when 0 => 
					     D3_anzeige <= ZIFFER0;  
				    when 1 => 
					     D3_anzeige <= ZIFFER1;  
				    when 2 => 
					     D3_anzeige <= ZIFFER2;  
				    when 3 => 
					     D3_anzeige <= ZIFFER3;  
				    when 4 => 
					     D3_anzeige <= ZIFFER4;  
				    when 5 => 
					     D3_anzeige <= ZIFFER5;  
				    when 6 => 
					     D3_anzeige <= ZIFFER6;  
				    when 7 => 
					     D3_anzeige <= ZIFFER7;  
				    when 8 => 
					     D3_anzeige <= ZIFFER8;  
				    when 9 => 
					     D3_anzeige <= ZIFFER9;  
				end case;

				case D4 is
				    when 0 => 
					     D4_anzeige <= ZIFFER0;  
				    when 1 => 
					     D4_anzeige <= ZIFFER1;  
				    when 2 => 
					     D4_anzeige <= ZIFFER2;  
				    when 3 => 
					     D4_anzeige <= ZIFFER3;  
				    when 4 => 
					     D4_anzeige <= ZIFFER4;  
				    when 5 => 
					     D4_anzeige <= ZIFFER5;  
				    when 6 => 
					     D4_anzeige <= ZIFFER6;  
				    when 7 => 
					     D4_anzeige <= ZIFFER7;  
				    when 8 => 
					     D4_anzeige <= ZIFFER8;  
				    when 9 => 
					     D4_anzeige <= ZIFFER9;  
				end case;

            -- Digit waehlen und richtig setzen, das aufgefrischt werden soll:
            case (zaehler mod 4) is
				    when 0 =>
                    DIGIT12P34 <= "01111";
                    ABCDEFG    <= D1_anzeige;						  
				    when 1 =>
                    DIGIT12P34 <= "10111";
                    ABCDEFG    <= D2_anzeige;						  
				    when 2 =>
                    DIGIT12P34 <= "11101";
                    ABCDEFG    <= D3_anzeige;						  
				    when others =>
                    DIGIT12P34 <= "11110";
                    ABCDEFG    <= D4_anzeige;						  
				end case;
        end process;      
    --- LEDROT und GRUEN blinken lassen
    LEDROT <= logikpegel;
    LEDGRUEN <= not logikpegel;
    --- GROUND123 auf Masse setzen:
    GROUND123 <= "000";
end Behavioral;

Code 22-1: uhr.vhd

2. uhr.ucf
## GCLK6 ist auf FPGA-Chip Pin 56
NET "MEINECLOCK" LOC = "P56" | IOSTANDARD = LVCMOS25;

## LEDROT
NET "LEDROT"   LOC = "P126"  | IOSTANDARD = LVCMOS33;

## LEDGRUEN
NET "LEDGRUEN"   LOC = "P125"  | IOSTANDARD = LVCMOS33;

## DIGIT12P34
NET "DIGIT12P34<4>"   LOC = "P105"  | IOSTANDARD = LVCMOS33; ## 1
NET "DIGIT12P34<3>"   LOC = "P106"  | IOSTANDARD = LVCMOS33; ## 2
NET "DIGIT12P34<2>"   LOC = "P112"  | IOSTANDARD = LVCMOS33; ## P
NET "DIGIT12P34<1>"   LOC = "P113"  | IOSTANDARD = LVCMOS33; ## 3
NET "DIGIT12P34<0>"   LOC = "P116"  | IOSTANDARD = LVCMOS33; ## 4

## ABCDEFG
NET "ABCDEFG<6>"   LOC = "P130"  | IOSTANDARD = LVCMOS33; ## A 
NET "ABCDEFG<5>"   LOC = "P131"  | IOSTANDARD = LVCMOS33; ## B 
NET "ABCDEFG<4>"   LOC = "P132"  | IOSTANDARD = LVCMOS33; ## C 
NET "ABCDEFG<3>"   LOC = "P134"  | IOSTANDARD = LVCMOS33; ## D 
NET "ABCDEFG<2>"   LOC = "P135"  | IOSTANDARD = LVCMOS33; ## E 
NET "ABCDEFG<1>"   LOC = "P139"  | IOSTANDARD = LVCMOS33; ## F 
NET "ABCDEFG<0>"   LOC = "P140"  | IOSTANDARD = LVCMOS33; ## G 

## TASTEN123 IO0,2,5
NET "TASTE123<2>"  LOC = "P58" | PULLUP  | IOSTANDARD = LVCMOS33;
NET "TASTE123<1>"  LOC = "P93" | PULLUP  | IOSTANDARD = LVCMOS33;
NET "TASTE123<0>"  LOC = "P97" | PULLUP  | IOSTANDARD = LVCMOS33;

## GROUND123 IO1,4,7
NET "GROUND123<2>"   LOC = "P59"  | IOSTANDARD = LVCMOS33;
NET "GROUND123<1>"   LOC = "P96"  | IOSTANDARD = LVCMOS33;
NET "GROUND123<0>"   LOC = "P104" | IOSTANDARD = LVCMOS33;

Code 22-2: uhr.ucf