📄 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 + -