?? cymometer.vhd
字號:
--文件名:cymometer.vhd
--功 能:頻率計。具有4位顯示,能自動根據7位十進制計數的結果,自動選擇有效數據的
--說 明:高4位進行動態顯示。所顯示的結果是數碼管顯示的數據乘以十的N次方;N對應發光二極
-- 管的右邊點亮的第幾位就是幾,如果如果最右邊的一個被點亮的話,頻率就等于顯示的
-- 數值乘以10的一次方。頻率的測量范圍是0~9,999,999HZ。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cymometer is
port ( reset:in std_logic; --復位信號,高電平有效
clk :in std_logic; --系統時鐘
select_sw:in std_logic_vector(1 downto 0 );--選擇被測頻率是外部輸入還是內部輸入
check_clk:in std_logic; --外部輸入被測信號
cs:out std_logic_vector(1 downto 0); --74HC573的選通信號
data_led:out std_logic_vector(7 downto 0); --八段碼
shift:out std_logic_vector(3 downto 0)); --數碼管位選信號
end cymometer;
architecture behav of cymometer is
signal cnt1,cnt2,cnt3,cnt4,cnt5,cnt6,cnt7:std_logic_vector(3 downto 0); --十進制計數器
signal bcd:std_logic_vector(3 downto 0); --BCD碼寄存器
signal k_1hz :integer range 0 to 50000000; --秒分頻系數
signal en,bclk,clk_shift,check_clk1,check_clk2,check_clk3:std_logic; --使能信號,有效被測信號 ,動態掃描分頻
signal point : std_logic_vector(3 downto 0); --小數點
signal pointout : std_logic_vector(7 downto 0);
signal bcd0,bcd1,bcd2,bcd3 : std_logic_vector(3 downto 0); --寄存7位十進制計數器中有效的高4位數據
--signal led:std_logic_vector(7 downto 0);
signal ledfa:std_logic;
begin
process(clk) --分頻器;
variable cnt11,cnt22,cnt33 : integer range 0 to 25000000;
begin
if reset='1' then
cnt11:=0;cnt22:=0;cnt33:=0;check_clk1<='0'; check_clk2<='0';check_clk3<='0';
elsif clk'event and clk='1' then
if cnt11=249 then check_clk1<=not check_clk1;cnt11:=0;
else cnt11:=cnt11+1;
end if;
if cnt22=24999 then check_clk2<=not check_clk2; cnt22:=0;
else cnt22:=cnt22+1;
end if;
if cnt33=99999 then check_clk3<=not check_clk3; cnt33:=0;
else cnt33:=cnt33+1;
end if;
end if;
end process;
second:process(clk,reset) --此進程產生一個持續時間為一秒的的閘門信號
begin
if reset='1' then k_1hz<=0;
elsif clk'event and clk='1' then
if k_1hz<49999999 then k_1hz<=k_1hz+1;
else k_1hz<=50000000;
end if;
end if;
if k_1hz<49999999 and reset='0' then en<='1';
else en<='0';
end if;
end process;
and2:process(en,select_sw,check_clk1,check_clk2,check_clk3,check_clk) --此進程得到7位十進制計數器的計數脈沖
begin
if select_sw="00" then
bclk<=check_clk and en;
elsif select_sw="01" then
bclk<=check_clk1 and en;
elsif select_sw="10" then
bclk<=check_clk2 and en;
else
bclk<=check_clk3 and en;
end if;
end process;
com:process(en,reset,bclk) --此進程完成對被測信號計脈沖數
begin
if reset='1' then --復位
cnt1<="0000";cnt2<="0000";cnt3<="0000";cnt4<="0000";cnt5<="0000";cnt6<="0000";cnt7<="0000";
elsif bclk'event and bclk='1' then
if cnt1="1001" then cnt1<="0000"; --此IF語句完成個位十進制計數
if cnt2="1001" then cnt2<="0000"; --此IF語句完成百位十進制計數
if cnt3="1001" then cnt3<="0000"; --此IF語句完成千位十進制計數
if cnt4="1001" then cnt4<="0000"; --此IF語句完成萬位十進制計數
if cnt5="1001" THEN cnt5<="0000"; --此IF語句完成十萬位十進制計數
if cnt6="1001" then cnt6<="0000"; --此IF語句完成百萬位十進制計數
if cnt7="1001" then cnt7<="0000"; --此IF語句完成千萬位十進制計數
else cnt7<=cnt7+1;
end if;
else cnt6<=cnt6+1;
end if;
else cnt5<=cnt5+1;
end if;
else cnt4<=cnt4+1;
end if;
else cnt3<=cnt3+1;
end if;
else cnt2<=cnt2+1;
end if;
else cnt1<=cnt1+1;
end if;
end if;
end process;
process(clk,en) --此進程把7位十進制計數器有效的高4位數據送如bcd0~3;并得到小數點信息
begin
if rising_edge(clk) then
if en='0' then
if cnt7>"0000" then bcd3<=cnt7; bcd2<=cnt6; bcd1<=cnt5; bcd0<=cnt4; point<="0111";
elsif cnt6>"0000" then bcd3<=cnt6; bcd2<=cnt5; bcd1<=cnt4; bcd0<=cnt3; point<="1011";
elsif cnt5>"0000" then bcd3<=cnt5; bcd2<=cnt4; bcd1<=cnt3; bcd0<=cnt2; point<="1101";
else bcd3<=cnt4; bcd2<=cnt3; bcd1<=cnt2; bcd0<=cnt1; point<="1111";
end if;
end if;
end if;
end process;
process(clk) --分頻器;
variable cnt : integer range 0 to 50000;
begin
if clk'event and clk='1' then cnt:=cnt+1;
if cnt<2500 then clk_shift<='1';
elsif cnt<50000 then clk_shift<='0';
else cnt:=0;clk_shift<='0';
end if;
end if;
end process;
process(clk_shift,reset) --此進程完成數據的動態顯示 ,數據的賦植提前了一個時鐘,原因是譯碼模塊使得數據傳輸延遲了一個時鐘;
variable cnt : std_logic_vector(2 downto 0);
begin
if reset='1' then
cnt:="000";cs<="00";shift<="1111";
elsif clk_shift'event and clk_shift='1' then
cnt:=cnt+1;
if cnt="001" then
ledfa<='0';
cs<="11";
shift<="1111";
bcd<="1111"; --發光二極管、數碼管全滅;
elsif cnt="010" then
cs<="00";
shift<="1111";
bcd<=bcd3;
elsif cnt="011" then
cs<="01";
shift<="0111";
bcd<=bcd2;
elsif cnt="100" then
cs<="01";
shift<="1011";
bcd<=bcd1;
elsif cnt="101" then
cs<="01";
shift<="1101";
bcd<=bcd0;
elsif cnt="110" then
cs<="01";
shift<="1110";
ledfa<='1';
pointout<='1'&'1'&'1'&'1'&point;
elsif cnt="111" then
cs<="10";
bcd<="1111";
shift<="1111";
end if;
end if;
end process;
process (clk_shift,bcd) --譯碼
begin
if clk_shift'event and clk_shift='1' then
if ledfa='1' then
data_led<=pointout;
else
case bcd is
when"0000"=>data_led<="11000000";--0
when"0001"=>data_led<="11111001";--1
when"0010"=>data_led<="10100100";--2
when"0011"=>data_led<="10110000";--3
when"0100"=>data_led<="10011001";--4
when"0101"=>data_led<="10010010";--5
when"0110"=>data_led<="10000010";--6
when"0111"=>data_led<="11111000";--7
when"1000"=>data_led<="10000000";--8
when"1001"=>data_led<="10010000";--9
when others=>data_led<="11111111";--No signal;
end case;
end if;
end if;
end process;
end behav;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -