zxj123

zxj123

0个粉丝

92

问答

0

专栏

0

资料

zxj123  发布于  2012-12-24 14:56:39
采纳率 0%
92个问答
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按键观察计数情况.



   





                                                   




























我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区