3132
- 收藏
- 点赞
- 分享
- 举报
用VHDL语言制作秒表
用VHDL语言制作秒表
1.功能和要求:
1/100S计时器常用于体育竟赛及各种要求有较精确订时的地方.其功能主要有
(1).精度应大于1/100S;
(2).计时器最长计时时间为1h,故需6位显示器,例如 36分12秒56(1/100);
(3).设置复位和启停开关, 复位开关用于使计时器清零,按一下启停开关计时器开始
计数,再按一下启停开关计时器停止计数; 复位开关可以在仍何情况下使用,即使
在计时过程中,只要一按复位开关,计时进程应立即停止,并对计时器清零.
2.制作思路:
秒表的核心部件是6位计数器,每个计数器由四位二进制数组成.计数器的时钟信号
为100hz.每按一次按键开关输入一个单脉冲用于复位和启停.由于EDA实验板上只
有4为数码管,故需借用LED指示灯资源.用数码管左边两位显示(分),用数码管右边
两位显示(秒),用LED左边四位直接显示(1/100)高位(二进制形式),用LED右边四位
显示(1/100)低位.
可以用6个串行进位计数器作为核心,计数器最低位时钟为100hz方波; 100hz方波可
由对光盘中os.xnf(相当于晶振)适当分频得到。
由于EDA实验板上的按键按一下会出现多个上升沿or下降沿,这种键抖动现象必须
消除,再单片机中可以用延时的方法,CPLD芯片不能直接实现很精确的延时,故需做一
单脉冲发生电路.(具体方法可参考西安电子科技大学出版的
与数字逻缉电路设计>page197图9-3)。
要想每按一次按键均改变原来状态,需用消抖后产生的单脉冲作为触发器的时钟,
每次按键均使触发器状态反转,在进程中通过判断触发器状态为0 or 为1来决定
是启停还是复位。
数码管显示采用动态扫描以节省I/O口,其实在EDA实验板上数码管段选端是接
在一起的,不可能采用静态扫描. 采用动态扫描就必须注意扫描频率,不能太高也
不能太低. 只要做到人眼观察无闪烁即可.
3.源程序注释:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity counter60 is
port (
reset:in std_logic; -------reset为清零信号
stop:in std_logic; -------stop为启停信号
led:out std_logic_vector(6 downto 0); -------led为数码管7段显示信号
dig:out std_logic_vector(3 downto 0); ------dig为数码管位选信号
bcd1: inout STD_LOGIC_VECTOR (3 downto 0); ----bcd1为1/100s低位
bcd10: inout STD_LOGIC_VECTOR (3 downto 0)---bcd10为 1/100 高位
);
end counter60;
architecture counter60_arch of counter60 is
signal qw1,qw10,bcd1_s,bcd10_s,bcd1_a_s,bcd10_a,bcd:STD_LOGIC_VECTOR (3 downto 0);
signal display:STD_LOGIC_VECTOR (1 downto 0);
signal start,st,carry1,carry2,carry3,carry4,carry5,clkin2,res1,res0:std_logic;
signal stop1,stop0,stop_s,stop_s1,sel:std_logic;
component clk_100hz ------元件clk_100hz用来产生计数脉冲
port (clks,wer:inout std_logic);
end component;
begin
bcd1<=not qw1; ----因为LED为低电平点亮,故要想将101显示
bcd10<=not qw10; 只要送010;
u1: clk_100hz port map(clkin2,sel); --clkin2=100hz sel for display
process(clkin2) ----产生启停复位信号
begin
if(clkin2'event and clkin2='0')then
res1<=res0;
res0<=reset;
stop1<=stop0;
stop0<=stop;
end if;
end process;
process(res0,res1) ----start stop_s 为单脉冲信号
begin
start<=clkin2 and res0 and (not res1);
stop_s<=clkin2 and stop0 and (not stop1);
end process;
process(stop_s) ----每次stop_s上升沿将stop_s1反转
begin 如stop_s1=1则表示开始计数
if(stop_s'event and stop_s='1')then 如stop_s1=0则表示停止计数
stop_s1<=not stop_s1; (启停信号)
end if;
end process;
process(start) ----每次start上升沿将st反转
begin 如st=1则复位,此时数码管和LED均为零
if(start'event and start='1')then 如st=0则重新允许计时
st<= not st; (复位信号)
end if;
end process;
--counter
process(st,clkin2) -----clkin2为100HZ计数脉冲输入
begin 这个进程描述了1/100s 低位计数情况
if(st='1')then 当st=1时复位,把计数器各位清零
qw1<="0000"; 当st=0时允许计时,如此时stop_s1=1,
else 则在clkin2 上升沿开始计时; 如此时
if(clkin2'event and clkin2='1')then stop_s1=0,则计时停止.
if(stop_s1='1')then
if(qw1="1001")then *********************************
qw1<="0000"; qw10和 qw1组成100进制计数器
else *********************************
qw1<=qw1+1;
end if ;
end if;
end if;
end if ;
end process;
carry1<=qw1(3); ----如果qw1(3)出现从1到0的下降沿
则给1/100s高位进位, carry1为进位
process(carry1,st) 标志
begin
if(st='1')then
qw10<="0000"; ----carry1的下降沿触发1/100s
else 计数器高位计数
if(carry1'event and carry1='0')then
if(stop_s1='1')then
if(qw10="1001")then
qw10<="0000";
else
qw10<=qw10+1;
end if;
end if;
end if;
end if;
end process;
carry2<=qw10(3); -----carry2给 s计数器低位计数
process(st,carry2) ************************************
begin bcd1_s和bcd10_s组成60进制计数器
if(st='1')then ************************************
bcd1_s<="0000";
else
if(carry2'event and carry2='0')then
if(stop_s1='1')then
if(bcd1_s="1001")then
bcd1_s<="0000";
else
bcd1_s<=bcd1_s+1;
end if;
end if;
end if;
end if;
end process;
carry3<=bcd1_s(3); ------carry3 给s高位计数
process(carry3,st)
begin
if(st='1')then
bcd10_s<="0000";
else
if(carry3'event and carry3='0')then
if(stop_s1='1')then
if(bcd10_s="0101")then
bcd10_s<="0000";
carry4<='1'; -----在这边设进位也可以
else 当 bcd10_s=5时,再来一个
bcd10_s<=bcd10_s+1; 脉冲则计数器清零同时设
carry4<='0'; 进位标志为1;bcd10_s不等于
end if; 5时,计时值加1同时设进位
end if; 标志为0
end if;
end if;
end process;
process(carry4,st) ------carry4的上升沿为m低位时钟脉冲
begin
if(st='1')then **************************************
bcd1_a_s<="0000"; bcd1_a_s和bcd10_a 组成60进制计数器
else **************************************
if(carry4'event and carry4='1')then
if(stop_s1='1')then
if(bcd1_a_s="1001")then
bcd1_a_s<="0000";
else
bcd1_a_s<=bcd1_a_s+1;
end if;
end if;
end if;
end if;
end process;
carry5<=bcd1_a_s(3); -----carry5下降沿为m高位计时脉冲
process(carry5,start)
begin
if(start='1')then
bcd10_a<="0000";
else
if(carry5'event and carry5='0')then
if(stop_s1='1')then
if(bcd10_a="0101")then
bcd10_a<="0000";
else
bcd10_a<=bcd10_a+1;
end if;
end if;
end if;
end if;
end process;
process(bcd) ------将四位二进制数转换成数码管段选码
begin
case bcd is
when "0000"=>led<= "0111111";
when "0001"=>led<= "0000110";
when "0010"=>led<= "1011011";
when "0011"=>led<= "1001111";
when "0100"=>led<= "1100110";
when "0101"=>led<= "1101101";
when "0110"=>led<= "1111101";
when "0111"=>led<= "0000111";
when "1000"=>led<= "1111111";
when "1001"=>led<= "1101111";
when others=>led<= "XXXXXXX";
end case;
END PROCESS;
process(sel) -----sel为动态扫描频率
begin display为一四进制计数器,根据display的
if(sel'event and sel='1')then 四种状态00 01 10 11来点亮不同的
if(display="11")then 数码管.
display<="00";
else
display<=display+1;
end if;
end if;
end process;
bcd<=bcd1_s when display="00" else -----display=00时显示s低位
bcd10_s when display="01" else display=01时显示s高位
bcd1_a_s when display="10" else display=10时显示m低位
bcd10_a; display=11时显示m高位
dig<="1110" when display="00" else -----dig为四个数码管的位选码,低电
"1101" when display="01" else 平选通. display=00时,点亮最
"1011" when display="10" else 右边数码管,01 10 11相应.
"0111";
end counter60_arch;
4. 管脚锁定文件及说明:
net bcd1<3> loc=p25; -----8个LED指示灯对应管脚
net bcd1<2> loc=p1;
net bcd1<1> loc=p40;
net bcd1<0> loc=p42;
net bcd10<3> loc=p29;
net bcd10<2> loc=p28;
net bcd10<1> loc=p27;
net bcd10<0> loc=p26;
net led<6> loc=p24; ------数码管段选端对应管脚
net led<5> loc=p22;
net led<4> loc=p20;
net led<3> loc=p19;
net led<2> loc=p18;
net led<1> loc=p14;
net led<0> loc=p13;
net dig<3> loc=p8; ------数码管位选端对应管脚
net dig<2> loc=p9;
net dig<1> loc=p11;
net dig<0> loc=p12;
net reset loc=p6; -----复位输入,在EDA板上对应s1
net stop loc=p7; -----启停输入, 在EDA板上对应s2
5.100HZ方波产生元件的VHDL程序:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity clk_100hz is
port (
clks,wer: inout STD_LOGIC --clks=100hz wer for display
);
end clk_100hz;
architecture clk_100hz_arch of clk_100hz is -----clks是os经适当分频得到的
signal clkin:std_logic; 大约100hz.
component os ----元件os说明
port (osout:out std_logic);
end component;
signal counter:std_logic_vector(12 downto 0);
signal fp:std_logic_vector(5 downto 0);
begin
u0:os port map(clkin);
wer<=fp(5);
-------首先对os 5分频产生wer用于动态扫描
process(clkin)
begin
if(clkin'event and clkin='1')then
fp<=fp+1;
end if;
end process;
process(wer) -----再对wer分频得到100HZ方波
begin clks
if wer='1' and wer'event then
if(counter="1111000000000")then
clks<=not clks;
counter<="0000000000000";
else
COUNTER<=COUNTER+1;
end if;
end if;
end process;
end clk_100hz_arch;
6.COUNTER60的具体实现方法:
#1.新建一目录,将COUNTER60.VHD OS.XNF CLK_100HZ COUNTER60.UCF
COPY到该目录下.
#2.进行逻缉综合和编程
#3.通过操作s1 s2按键观察计数情况.
1.功能和要求:
1/100S计时器常用于体育竟赛及各种要求有较精确订时的地方.其功能主要有
(1).精度应大于1/100S;
(2).计时器最长计时时间为1h,故需6位显示器,例如 36分12秒56(1/100);
(3).设置复位和启停开关, 复位开关用于使计时器清零,按一下启停开关计时器开始
计数,再按一下启停开关计时器停止计数; 复位开关可以在仍何情况下使用,即使
在计时过程中,只要一按复位开关,计时进程应立即停止,并对计时器清零.
2.制作思路:
秒表的核心部件是6位计数器,每个计数器由四位二进制数组成.计数器的时钟信号
为100hz.每按一次按键开关输入一个单脉冲用于复位和启停.由于EDA实验板上只
有4为数码管,故需借用LED指示灯资源.用数码管左边两位显示(分),用数码管右边
两位显示(秒),用LED左边四位直接显示(1/100)高位(二进制形式),用LED右边四位
显示(1/100)低位.
可以用6个串行进位计数器作为核心,计数器最低位时钟为100hz方波; 100hz方波可
由对光盘中os.xnf(相当于晶振)适当分频得到。
由于EDA实验板上的按键按一下会出现多个上升沿or下降沿,这种键抖动现象必须
消除,再单片机中可以用延时的方法,CPLD芯片不能直接实现很精确的延时,故需做一
单脉冲发生电路.(具体方法可参考西安电子科技大学出版的
与数字逻缉电路设计>page197图9-3)。
要想每按一次按键均改变原来状态,需用消抖后产生的单脉冲作为触发器的时钟,
每次按键均使触发器状态反转,在进程中通过判断触发器状态为0 or 为1来决定
是启停还是复位。
数码管显示采用动态扫描以节省I/O口,其实在EDA实验板上数码管段选端是接
在一起的,不可能采用静态扫描. 采用动态扫描就必须注意扫描频率,不能太高也
不能太低. 只要做到人眼观察无闪烁即可.
3.源程序注释:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity counter60 is
port (
reset:in std_logic; -------reset为清零信号
stop:in std_logic; -------stop为启停信号
led:out std_logic_vector(6 downto 0); -------led为数码管7段显示信号
dig:out std_logic_vector(3 downto 0); ------dig为数码管位选信号
bcd1: inout STD_LOGIC_VECTOR (3 downto 0); ----bcd1为1/100s低位
bcd10: inout STD_LOGIC_VECTOR (3 downto 0)---bcd10为 1/100 高位
);
end counter60;
architecture counter60_arch of counter60 is
signal qw1,qw10,bcd1_s,bcd10_s,bcd1_a_s,bcd10_a,bcd:STD_LOGIC_VECTOR (3 downto 0);
signal display:STD_LOGIC_VECTOR (1 downto 0);
signal start,st,carry1,carry2,carry3,carry4,carry5,clkin2,res1,res0:std_logic;
signal stop1,stop0,stop_s,stop_s1,sel:std_logic;
component clk_100hz ------元件clk_100hz用来产生计数脉冲
port (clks,wer:inout std_logic);
end component;
begin
bcd1<=not qw1; ----因为LED为低电平点亮,故要想将101显示
bcd10<=not qw10; 只要送010;
u1: clk_100hz port map(clkin2,sel); --clkin2=100hz sel for display
process(clkin2) ----产生启停复位信号
begin
if(clkin2'event and clkin2='0')then
res1<=res0;
res0<=reset;
stop1<=stop0;
stop0<=stop;
end if;
end process;
process(res0,res1) ----start stop_s 为单脉冲信号
begin
start<=clkin2 and res0 and (not res1);
stop_s<=clkin2 and stop0 and (not stop1);
end process;
process(stop_s) ----每次stop_s上升沿将stop_s1反转
begin 如stop_s1=1则表示开始计数
if(stop_s'event and stop_s='1')then 如stop_s1=0则表示停止计数
stop_s1<=not stop_s1; (启停信号)
end if;
end process;
process(start) ----每次start上升沿将st反转
begin 如st=1则复位,此时数码管和LED均为零
if(start'event and start='1')then 如st=0则重新允许计时
st<= not st; (复位信号)
end if;
end process;
--counter
process(st,clkin2) -----clkin2为100HZ计数脉冲输入
begin 这个进程描述了1/100s 低位计数情况
if(st='1')then 当st=1时复位,把计数器各位清零
qw1<="0000"; 当st=0时允许计时,如此时stop_s1=1,
else 则在clkin2 上升沿开始计时; 如此时
if(clkin2'event and clkin2='1')then stop_s1=0,则计时停止.
if(stop_s1='1')then
if(qw1="1001")then *********************************
qw1<="0000"; qw10和 qw1组成100进制计数器
else *********************************
qw1<=qw1+1;
end if ;
end if;
end if;
end if ;
end process;
carry1<=qw1(3); ----如果qw1(3)出现从1到0的下降沿
则给1/100s高位进位, carry1为进位
process(carry1,st) 标志
begin
if(st='1')then
qw10<="0000"; ----carry1的下降沿触发1/100s
else 计数器高位计数
if(carry1'event and carry1='0')then
if(stop_s1='1')then
if(qw10="1001")then
qw10<="0000";
else
qw10<=qw10+1;
end if;
end if;
end if;
end if;
end process;
carry2<=qw10(3); -----carry2给 s计数器低位计数
process(st,carry2) ************************************
begin bcd1_s和bcd10_s组成60进制计数器
if(st='1')then ************************************
bcd1_s<="0000";
else
if(carry2'event and carry2='0')then
if(stop_s1='1')then
if(bcd1_s="1001")then
bcd1_s<="0000";
else
bcd1_s<=bcd1_s+1;
end if;
end if;
end if;
end if;
end process;
carry3<=bcd1_s(3); ------carry3 给s高位计数
process(carry3,st)
begin
if(st='1')then
bcd10_s<="0000";
else
if(carry3'event and carry3='0')then
if(stop_s1='1')then
if(bcd10_s="0101")then
bcd10_s<="0000";
carry4<='1'; -----在这边设进位也可以
else 当 bcd10_s=5时,再来一个
bcd10_s<=bcd10_s+1; 脉冲则计数器清零同时设
carry4<='0'; 进位标志为1;bcd10_s不等于
end if; 5时,计时值加1同时设进位
end if; 标志为0
end if;
end if;
end process;
process(carry4,st) ------carry4的上升沿为m低位时钟脉冲
begin
if(st='1')then **************************************
bcd1_a_s<="0000"; bcd1_a_s和bcd10_a 组成60进制计数器
else **************************************
if(carry4'event and carry4='1')then
if(stop_s1='1')then
if(bcd1_a_s="1001")then
bcd1_a_s<="0000";
else
bcd1_a_s<=bcd1_a_s+1;
end if;
end if;
end if;
end if;
end process;
carry5<=bcd1_a_s(3); -----carry5下降沿为m高位计时脉冲
process(carry5,start)
begin
if(start='1')then
bcd10_a<="0000";
else
if(carry5'event and carry5='0')then
if(stop_s1='1')then
if(bcd10_a="0101")then
bcd10_a<="0000";
else
bcd10_a<=bcd10_a+1;
end if;
end if;
end if;
end if;
end process;
process(bcd) ------将四位二进制数转换成数码管段选码
begin
case bcd is
when "0000"=>led<= "0111111";
when "0001"=>led<= "0000110";
when "0010"=>led<= "1011011";
when "0011"=>led<= "1001111";
when "0100"=>led<= "1100110";
when "0101"=>led<= "1101101";
when "0110"=>led<= "1111101";
when "0111"=>led<= "0000111";
when "1000"=>led<= "1111111";
when "1001"=>led<= "1101111";
when others=>led<= "XXXXXXX";
end case;
END PROCESS;
process(sel) -----sel为动态扫描频率
begin display为一四进制计数器,根据display的
if(sel'event and sel='1')then 四种状态00 01 10 11来点亮不同的
if(display="11")then 数码管.
display<="00";
else
display<=display+1;
end if;
end if;
end process;
bcd<=bcd1_s when display="00" else -----display=00时显示s低位
bcd10_s when display="01" else display=01时显示s高位
bcd1_a_s when display="10" else display=10时显示m低位
bcd10_a; display=11时显示m高位
dig<="1110" when display="00" else -----dig为四个数码管的位选码,低电
"1101" when display="01" else 平选通. display=00时,点亮最
"1011" when display="10" else 右边数码管,01 10 11相应.
"0111";
end counter60_arch;
4. 管脚锁定文件及说明:
net bcd1<3> loc=p25; -----8个LED指示灯对应管脚
net bcd1<2> loc=p1;
net bcd1<1> loc=p40;
net bcd1<0> loc=p42;
net bcd10<3> loc=p29;
net bcd10<2> loc=p28;
net bcd10<1> loc=p27;
net bcd10<0> loc=p26;
net led<6> loc=p24; ------数码管段选端对应管脚
net led<5> loc=p22;
net led<4> loc=p20;
net led<3> loc=p19;
net led<2> loc=p18;
net led<1> loc=p14;
net led<0> loc=p13;
net dig<3> loc=p8; ------数码管位选端对应管脚
net dig<2> loc=p9;
net dig<1> loc=p11;
net dig<0> loc=p12;
net reset loc=p6; -----复位输入,在EDA板上对应s1
net stop loc=p7; -----启停输入, 在EDA板上对应s2
5.100HZ方波产生元件的VHDL程序:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity clk_100hz is
port (
clks,wer: inout STD_LOGIC --clks=100hz wer for display
);
end clk_100hz;
architecture clk_100hz_arch of clk_100hz is -----clks是os经适当分频得到的
signal clkin:std_logic; 大约100hz.
component os ----元件os说明
port (osout:out std_logic);
end component;
signal counter:std_logic_vector(12 downto 0);
signal fp:std_logic_vector(5 downto 0);
begin
u0:os port map(clkin);
wer<=fp(5);
-------首先对os 5分频产生wer用于动态扫描
process(clkin)
begin
if(clkin'event and clkin='1')then
fp<=fp+1;
end if;
end process;
process(wer) -----再对wer分频得到100HZ方波
begin clks
if wer='1' and wer'event then
if(counter="1111000000000")then
clks<=not clks;
counter<="0000000000000";
else
COUNTER<=COUNTER+1;
end if;
end if;
end process;
end clk_100hz_arch;
6.COUNTER60的具体实现方法:
#1.新建一目录,将COUNTER60.VHD OS.XNF CLK_100HZ COUNTER60.UCF
COPY到该目录下.
#2.进行逻缉综合和编程
#3.通过操作s1 s2按键观察计数情况.
我来回答
回答0个
时间排序
认可量排序
暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2012-12-24 14:54:59
-
2013-11-22 22:07:50
-
2012-12-24 14:59:30
-
2008-10-02 20:40:04
-
2013-12-10 20:07:17
-
2012-12-24 15:00:31
-
2012-12-24 15:01:43
-
2020-11-21 17:10:04
-
2013-11-23 08:55:59
-
2013-11-25 21:08:31
-
2018-11-05 11:35:36
-
2016-03-21 14:50:22
-
2008-07-31 01:02:40
-
02012-12-24 15:02:48
-
2013-08-27 22:13:22
-
2018-12-24 10:38:40
-
2008-10-02 20:47:54
-
2020-11-11 18:25:23
-
2020-11-11 16:44:51
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认