morse'a i podawac na wyswietlacze ich numery alfabetu. Zczytane litery sa
przechowywane w 4-bitowym wektorze logicznym. Rozpoznawanie kropki badz
kreski odbywa sie poprzez porownanie czasu przytrzymania KEY3. Gdy uplynie
odpowiednia ilosc wolnych taktow, wektor logiczny jest zamieniany na liczbe
calkowita i wyswietlany powinien zostac odpowiedni numer litery.
Oryginalan treśc mojego zadania:
Dekodowanie alfabetu Morsa. Należy napisać program który zdekoduje litery podawane za pomocą sygnału morsa (podawanie sygnałów będzie polegało na wciskaniu przycisków odpowiednio długo z odpowiednimi przerwami) i wyświetli na wyświetlaczu co za litera została nadana. Ze względu na fakt że na wyświetlaczu 7-segmentowym trudno reprezentować w sposób rozróżnialny wszystkie litery alfabetu wystarczy że zostanie podany numer litery lub inna reprezentacja pozwalająca odróżnić poszczególne znaki.
Mój kod wygląda następująco:
Kod: Zaznacz cały
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;
entity morse_code is
port (
CLOCK_50 : IN STD_LOGIC;
KEY3: IN STD_LOGIC; -- klawisz glowny
KEY2: IN STD_LOGIC; -- klawisz do kasowania
HEX5: OUT STD_LOGIC_VECTOR(0 TO 6); -- wyswietlacz dziesiatek
HEX4: OUT STD_LOGIC_VECTOR(0 TO 6) -- wyswietlacz jednosci
);
end morse_code;
architecture Behavioral of morse_code is
signal licznik_wolnych_taktow: integer; -- licznik taktow gdy button jest zwolniony, w celu rozpoznania konca litery
signal licznik_taktow: integer; -- licznik biezacych taktow pomiedzy akcjami na buttonie (przycisnieciem a zwolnieniem)
signal zmierzone_wolne_takty: integer; -- licznik do porownan
signal zmierzone_takty: integer; -- licznik do porownan
signal litera : STD_LOGIC_VECTOR(0 TO 3); -- wcisnieta litera
signal litera_int: integer; -- litera po konwersji
signal litera_alf: integer; -- numer litery po konwersji w alfabecie
signal indeks: integer; -- indeks aktualnej pozycji w wektorze bitowym dla litery
signal liczba_gotowa: integer;
-- OGOLNE ZALOZENIA:
-- Kropka (sygnal trwajacy 0 sek - 1 sek) jest interpretowana jako 1
-- Kreska (sygnal trwajacy 1 sek - 2 sek) jest interpretowana jako 0
-- Sygnal dluzszy od 2 sek oznacza przerwe miedzy literami
-- Gdy wciskamy przycisk zostaje mierzony czas do jego zwolnienia.
-- Nastepnie na odpowiednim miejscu (indeks) wektora bitowego zostaje dopisane 0 lub 1
-- Jesli przez odpowiednio dlugi okres czasu (licznik_wolnych_taktow przekroczy wartosc 100 000) button nie zostanie wcisniety, liczba zostaje uznana za skonczona
-- moze wystarczy rozbic proces glowny na 2 procesy???
--process (clock_50) is
--begin
--end process;
--process (KEY3) is
--begin
--end process;
begin
-- PROCES LICZACY TAKTY
process (clock_50) is
begin
-- ZLICZANIE TAKTOW ZEGARA
if clock_50'event and clock_50 = '1' then
licznik_taktow <= licznik_taktow + 1;
licznik_wolnych_taktow <= licznik_wolnych_taktow + 1;
end if;
end process;
-- ###############################################################################
-- PROCES DLA PRZYCISKU
process (KEY3) is
begin
--licznik_wolnych_taktow <= 0;
-- SPRAWDZANIE STANU PRZYCISKU - wciskanie
if KEY3'event and KEY3 = '1' then
licznik_taktow <= 0;
-- SPRAWDZANIE STANU PRZYCISKU - zwalnianie
elsif KEY3'event and KEY3 = '0' then
zmierzone_takty <= licznik_taktow;
-- SYNTEZA LICZBY - dopisywanie kropek - 1
if zmierzone_takty>1 and zmierzone_takty<50000 then
if indeks = 0 then litera <= litera or "1000"; end if;
if indeks = 1 then litera <= litera or "0100"; end if;
if indeks = 2 then litera <= litera or "0010"; end if;
if indeks = 3 then litera <= litera or "0001"; end if;
end if;
-- SYNTEZA LICZBY - dopisywanie kresek - 0
-- elsif zmierzone_takty>50000 and zmierzone_takty<100000 then
-- nic sie nie dzieje, po prostu zwiekszony bedzie indeks a na miejscu kreski zostanie 0
indeks <= indeks + 1;
-- INTERPRETOWANIE LITERY (jej nr) I WYSWIETLANIE JEJ - gdy uplyna minimum 2 sekundy
if licznik_wolnych_taktow>100000 OR indeks = 4 then
liczba_gotowa <= 1;
else
liczba_gotowa <= 0;
end if;
end if;
end process;
-- ###############################################################################
-- PROCES WYSWIETLAJACY LICZBE
process (liczba_gotowa) is
begin
if liczba_gotowa = 1 then -- tylko dla pojawienia sie nowej gotowej liczby
-- konwersja wektora bitowego opisujacego liczbe na wartosc calkowita do porownan
litera_int <= CONV_INTEGER(litera);
-- konwersja z powyzszej wartosci na wartosc odpowiadajaca numerze litery w alfabecie
-- w zasadzie ten etap moglby zostac wyeliminowany poprzez modyfikacje nastepnego case'a, ale w ten sposob zachowujemy wieksza czytelnosc
if litera_int = 8 and indeks = 2 then litera_alf <= 1; end if;
if litera_int = 15 and indeks = 4 then litera_alf <= 2; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 3; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 4; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 5; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 6; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 7; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 8; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 9; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 10; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 11; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 12; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 13; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 14; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 15; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 16; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 17; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 18; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 19; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 20; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 21; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 22; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 23; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 24; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 25; end if;
if litera_int = 1 and indeks = 1 then litera_alf <= 26; end if;
-- wypisywanie na wyswietlacze
case litera_alf is
when 1 => HEX4 <= "1001111"; -- A
when 2 => HEX4 <= "0010010"; -- B
when 3 => HEX4 <= "0000110"; -- C
when 4 => HEX4 <= "1001100"; -- D
when 5 => HEX4 <= "0100100"; -- E
when 6 => HEX4 <= "0100000"; -- F
when 7 => HEX4 <= "0001111"; -- G
when 8 => HEX4 <= "0000000"; -- H
when 9 => HEX4 <= "0000100"; -- I
when 10 =>HEX4 <= "0000001"; -- J -- 1: "1001111"
when 11 => HEX4 <= "1001111"; -- K
when 12 => HEX4 <= "0010010"; -- L
when 13 => HEX4 <= "0000110"; -- M
when 14 => HEX4 <= "1001100"; -- N
when 15 => HEX4 <= "0100100"; -- O
when 16 => HEX4 <= "0100000"; -- P
when 17 => HEX4 <= "0001111"; -- Q
when 18 => HEX4 <= "0000000"; -- R
when 19 => HEX4 <= "0000100"; -- S
when 20 => HEX4 <= "0000001"; -- T -- 2: "0010010"
when 21 => HEX4 <= "1001111"; -- U
when 22 => HEX4 <= "0010010"; -- V
when 23 => HEX4 <= "0000110"; -- W
when 24 => HEX4 <= "1001100"; -- X
when 25 => HEX4 <= "0100100"; -- Y
when 26 => HEX4 <= "0100000"; -- Z
when others => HEX4 <= "0000001"; -- '0' gdy nie rozpoznano litery
end case;
--zerowanie aby mozna bylo dekodowac nastepna litere
indeks <= 0;
zmierzone_takty <= 0;
liczba_gotowa <= 0;
end if;
end process;
-- ###############################################################################
-- PROCES KASUJACY WSZYSTKO
process (KEY2) is
begin
if KEY2'event and KEY2 = '1' then
HEX4 <= "0000001";
HEX5 <= "0000001";
indeks <= 0;
litera <= "0000";
liczba_gotowa <= 0;
end if;
end process;
-- ###############################################################################
end Behavioral;
roznego typu (kompiluje w Quartus II). Bardzo prosze o pomoc