题目一:数字频率计设计(平台实现)★
- 能对输入的方波信号频率进行采样;
- 采样频率范围为0~5999999Hz,以1Hz为单位进行显示;
- 采用七个七段数码管显示当前采样的频率值,如采样频率值为500HZ,则只显示500,而不显示0000500(即前面4个0不显示);
- 本电路系统板输入时钟为6MHz。
重要的事情:
可以参考,但是请不要伤害那些认真做的同学!
可以参考,但是请不要伤害那些认真做的同学!
可以参考,但是请不要伤害那些认真做的同学!
操作界面:
VHDL代码:
------------------This is Main Code,Please set it to Top level Entity-------------
--%%%%%%%%%%%%%%%%%%%%%
--%%|YZM-- (^@^)/ hi|%%
--%%|21******** |%%
--%%|2023.4.5 |%%
--%%%%%%%%%%%%%%%%%%%%%
library ieee;
use ieee.std_logic_1164.all;
entity Main is
generic (Num:integer :=4); --4 is Digital frequency num;
---------------------------------------------------------------------------------
port(
frequency_in: in std_logic_vector(0 to Num-1); --待测频率(选择frequency_in(0)为基准频率)
Choose_Frequency_in: in std_logic_vector(0 to Num-1); --频率选择
seg_sel: out std_logic_vector(6 downto 0); --数码管信息
bit_sel: out std_logic_vector(7 downto 0) --数码管选择
);
end Main;
---------------------------------------------------------------------------------
architecture Digital_frequency_meter_design_main of Main is
---------------------------------------------------------------------------------
type showIndex is array (0 to 7) of natural; --数组存储数码管信息
signal showers: showIndex; --数码管
type Temp_Num is array (0 to 7) of integer; --数组存储数码管信息(暂存)
signal Temp_Nixie_Num: Temp_Num; --数码管(暂存)
signal Nixie_tube_NOW :integer:= 0; --数码管显示位置状态
signal INPUT_FRE:integer := 0; --频率选择状态
signal NowClk: std_logic; --目前的频率
signal Set_Begin:std_logic:='0'; --重置计算标志
---------------------------------------------------------------------------------
begin
--###############################频率选择状态进程###############################
SCAN_FRE: process(frequency_in(0))
begin
if Choose_Frequency_in(0)='1' then INPUT_FRE<=0;
else if Choose_Frequency_in(1)='1' then INPUT_FRE<=1;
else if Choose_Frequency_in(2)='1' then INPUT_FRE<=2;
else if Choose_Frequency_in(3)='1' then INPUT_FRE<=3;
end if; end if; end if; end if;
case INPUT_FRE is
when 0 => NowClk<=frequency_in(0);
when 1 => NowClk<=frequency_in(1);
when 2 => NowClk<=frequency_in(2);
when 3 => NowClk<=frequency_in(3);
when others => Null;
end case;
end process SCAN_FRE;
----------------------------------------------------------------------------
--###############################待测频率计数进程###########################
Frequency_Generation: process(NowClk)
type Index_Num is array (0 to 7) of integer range 11 downto 0;
variable Nixie_Num: Index_Num;
begin
---------------------------------------------
if NowClk'event and NowClk= '1' then --
Nixie_Num(0):=Nixie_Num(0)+1; --
for m in 0 to 6 loop --
if Nixie_Num(m)=10 then --
Nixie_Num(m+1):=Nixie_Num(m+1)+1; --(计数信息存储在Nixie_Num内)
Nixie_Num(m):=0; --
end if; --
end loop; --
end if; --
---------------------------------------------
--(一秒钟时间到计数设置为0)
if Set_Begin='1' then for n in 0 to 7 loop Nixie_Num(n):=0 ; end loop; end if;
for n in 0 to 7 loop Temp_Nixie_Num(n)<=Nixie_Num(n);end loop;
end process Frequency_Generation;
-----------------------------------------------------------------------------
--###############################基础频率产生进程############################
Create_1Hz_Clk: process(frequency_in(0))
variable clk_count: integer := 0;
variable clk_count_show: integer := 0;
begin
if frequency_in(0)'event and frequency_in(0) = '1' then
if clk_count = 6000000 then
clk_count := 0;
Set_Begin<='1';
--(一秒钟只显示一次)
for n in 0 to 7 loop showers(n)<=Temp_Nixie_Num(n);end loop;
else clk_count := clk_count + 1;
Set_Begin <='0';
end if;
-----------------------------------------------
if clk_count_show = 60 then --
clk_count_show := 0; --为什么这么做呢?
Nixie_tube_NOW <=( Nixie_tube_NOW + 1)mod 8; --因为6Mhz频率太快显示会出现问题,出现毛刺输出不对齐(可以仿真出来)
else clk_count_show := clk_count_show + 1; --mos管导通速度太慢低于信号速度,数码管不该显示的地方有弱信号
end if; --
-----------------------------------------------
end if;
end process Create_1Hz_Clk;
------------------------------------------------------------------------------
--###############################数码管显示进程###############################
SHOW_NIXIE:process(Nixie_tube_NOW)
variable led:integer:=0;
begin
-----------------------------------------
for n in 7 downto 0 loop --
if showers(n)/=0 then --
led:=n; exit; --
end if; --(屏蔽数码管高位)
end loop; --
if led<Nixie_tube_NOW then led:=10; --
else led:=showers(Nixie_tube_NOW); --
end if; --
-----------------------------------------
case led is
when 0 => seg_sel <= "1111110" ;--数字0
when 1 => seg_sel <= "0110000" ;--数字1
when 2 => seg_sel <= "1101101" ;--数字2
when 3 => seg_sel <= "1111001" ;--数字3
when 4 => seg_sel <= "0110011" ;--数字4
when 5 => seg_sel <= "1011011" ;--数字5
when 6 => seg_sel <= "1011111" ;--数字6
when 7 => seg_sel <= "1110000" ;--数字7
when 8 => seg_sel <= "1111111" ;--数字8
when 9 => seg_sel <= "1111011" ;--数字9
when 10=> seg_sel <= "0000000" ;--10是不显示数字
when others => Null;
end case;
case Nixie_tube_NOW is
when 8 => bit_sel <= "11111111";--数码管不显示
when 7 => bit_sel <= "01111111";--数码管7
when 6 => bit_sel <= "10111111";--数码管6
when 5 => bit_sel <= "11011111";--数码管5
when 4 => bit_sel <= "11101111";--数码管4
when 3 => bit_sel <= "11110111";--数码管3
when 2 => bit_sel <= "11111011";--数码管2
when 1 => bit_sel <= "11111101";--数码管1
when 0 => bit_sel <= "11111110";--数码管0
when others => null;
end case;
end process SHOW_NIXIE;
end Digital_frequency_meter_design_main;
----------------------------------------------------------------------------------------