zxj123

zxj123

0个粉丝

92

问答

0

专栏

0

资料

zxj123  发布于  2012-12-24 14:54:59
采纳率 0%
92个问答
3621

用VHDL制作可变频可加减可复位计数器

 
用VHDL制作可变频可加减可复位计数器

1.  系统功能及要求:

该计数器应能实现加减计数,还应该有异步复位功能;与一般计数器不同的是该计数器

应可以变频;如果你想用不同频率实现计数,只要通过EDA实验板上按键进行切换即

可。如果你想实现加减计数,也只要预设一下方向状态即可.如果你想用某一频率进行

某一方向计数,只要预设方向和频率即可。

2.制作思路:

该系统核心是加减计数器,计数方向受方向按键控制,计数器采用串行进位。



要想实现不同频率计数,需做一系列方波信号,然后将这些不同频率的脉冲通过数据选

择器选择一个作为计数脉冲。



复位信号与方向控制信号需做成单脉冲行式,故需制作单脉冲发生器。



计数频率应适当,人眼必须能明显分辨出计数频率的变化,在这里共作了6档频率,最低

的约为0.5hz,然后每档以二倍向上增长。



要将单脉冲通过触发器,触发器输出用于判断该切换频率还是该切换计数方向。



数码管用于显示计数情况,LED指使灯最右边三个用于指示现在处于哪个计数频率,

最左边一个用于指示现在是加法计数还是减法计数。

LED右三个指使灯为000时处于0号计数频率;为001时处于1号计数频率;为010时处于2号计数频率;为011时处于3号计数频率;为100时处于4号计数频率;为101时处于5号计数频率。

LED最左边一个为0(不亮)时实行加法计数,为1(亮)时实行减法计数。

注意:LED灯亮表示1,但此时给LED送的电平为低。

3. 源程序注释:

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

entity muli_fre_light is

    port (

        change: in STD_LOGIC;   -------频率切换按键

        reset: in STD_LOGIC;     -------复位与开始计数按键

        direct:in std_logic;        -------方向切换按键

        dig: out std_logic_vector(3 downto 0);  ------数码管位选

        led: out STD_LOGIC_VECTOR (6 downto 0); ------数码管位选   

        dp:out std_logic;                        -------小数点点亮

        dire:out std_logic;                       -------计数方向指使灯

        light: out STD_LOGIC_VECTOR (2 downto 0)  -------频率状态指使灯

    );

end muli_fre_light;



architecture muli_fre_light_arch of muli_fre_light is



component clk_25hz        ---------元件clk_25用来产生6种计数频率和LED扫描

       port(clks,clks1,clks2,clks3,clks4,clks5,wer:inout STD_LOGIC);     频率

end component;                                                            

signal refresh:std_logic_vector(1 downto 0);      

signal zzm:std_logic_vector(2 downto 0);   

signal bcd1,bcd2,bcd3,bcd4,bcd:std_logic_vector(3 downto 0);     

signal carry1,carry2,carry3,clock,clks,clks1,clks2,clks3,clks4,clks5,wer,sel:std_logic;

signal chan1,chan0,direct0,direct1,dir,a_s:std_logic;

begin

u2:clk_25hz   port map(clks,clks1,clks2,clks3,clks4,clks5,wer);-----调用clk_25产生

                                                        各种频率

     process(clks1)                                            

       begin                           

         if(clks1'event and clks1='0')then           -----单脉冲信号sel  dir产生

           chan1<=chan0;                 

           chan0<=change;                     

           direct1<=direct0;                        

           direct0<=direct;

         end if;

     end process;

     

     process(chan0,direct0)                         dir为切换方向按键按下后

        begin                                    产生的单脉冲

         sel<=clks1 and chan0 and (not chan1);        sel为切换频率按键按下后

         dir<=clks1 and direct0 and (not direct1);       产生的单脉冲

     end process;   



  process(sel)                              ------每次频率切换通过zzm记录所处

     begin                                    频率状态

      if(sel'event and sel='1')then

         if(zzm="101")then

           zzm<="000";

         else  

          zzm<=zzm+1;

         end if;

      end if;

  end process;     

  

  light<=not zzm;                        ------当前频率状态送LED右三位显示

                                          

  process(dir)                           -------每次方向切换通过a_s记录所处

     begin                                  方向状态

       if(dir'event and dir='1')then

         a_s<=not a_s;

       end if;

  end process;     



  dire<=not a_s;                       -----将方向状态送LED最左边显示



   clock<=clks  when zzm="000"  else    -----6选1 mux选择计数脉冲

          clks1 when zzm="001"  else

          clks2 when zzm="010"  else

          clks3 when zzm="011"  else

          clks4 when zzm="100"  else

          clks5 ;         

   

     

process(clock)                        ------clock为mux输出信号   

    begin

    if(reset='0')then                  ------如果reset=0则允许加减计数

      if(clock'event and clock='1')then         此时如a_s=0则做减法

          if(a_s='0')then   --add count        此时如a_s=1则做加法

              if(bcd1="1001")then

                 bcd1<="0000";

                 carry1<='1';                 个位计数

              else

                 bcd1<=bcd1+1;

                 carry1<='0';

              end if;   

          else              --sub count

               if(bcd1="0000")then  

                   bcd1<="1001";

                   carry1<='1';

               else

                   bcd1<=bcd1-1;

                   carry1<='0';

               end if;  

          end if;           

      end if;   

    else

           bcd1<="0000";  

    end if;  

end process;



process(carry1,clock)

begin

      if(carry2=’1’)then  *************这个if 很重要,如没有则会出现错误

           carry2<=’0’;**************

       else

    if(reset='0')then

      if(carry1'event and carry1='1')then                 十位计数

          if(a_s='0')then   --add count

              if(bcd2="1001")then

                 bcd2<="0000";

                 carry2<='1';

              else

                 bcd2<=bcd2+1;

                 carry2<='0';

              end if;   

          else              --sub count

               if(bcd2="0000")then

                   bcd2<="1001";

                   carry2<='1';

                else

                   bcd2<=bcd2-1;

                   carry2<='0';

               end if;  

          end if;           

      end if;   

   else

       bcd2<="0000";

   end if;   

end if;

end process;



process(carry2,clock)

begin

      if(carry3=’1’)then **********************************

         carry3<=’0’;

      else

    if(reset='0')then

      if(carry2'event and carry2='1')then

          if(a_s='0')then   --add count        百位计数

              if(bcd3="1001")then

                 bcd3<="0000";

                 carry3<='1';

              else

                 bcd3<=bcd3+1;

                 carry3<='0';

              end if;   

          else              --sub count

               if(bcd3="0000")then

                   bcd3<="1001";

                   carry3<='1';

                else

                   bcd3<=bcd3-1;

                   carry3<='0';

               end if;  

          end if;           

      end if;   

    else

       bcd3<="0000";  

end if;   

       end if;

end process;



process(carry3)

    begin

    if(reset='0')then

      if(carry3'event and carry3='1')then            千位计数

          if(a_s='0')then   --add count

              if(bcd4="1001")then

                 bcd4<="0000";

              else

                 bcd4<=bcd4+1;

              end if;   

          else              --sub count

               if(bcd4="0000")then

                   bcd4<="1001";

                else

                   bcd4<=bcd4-1;

               end if;  

          end if;

      end if;

    else  

          bcd4<="0000";              

    end if;   

end process;







--display                      ------使百位小数点一直点亮

  dp<='1' when refresh="10" else

  '0';



  LED<= "0111111" when(BCD="0000") else  -----数码管7段译码

        "0000110" when(BCD="0001") else

        "1011011" when(BCD="0010") else

        "1001111" when(BCD=" 0011") else

        "1100110" when(BCD="0100") else

        "1101101" when(BCD="0101") else

        "1111101" when(BCD="0110") else

        "0000111" when(BCD="0111") else

        "1111111" when(BCD="1000") else

        "1101111" when(BCD="1001") else

        "XXXXXXX";

        

         

--bcd for display

  BCD<=BCD1 when(refresh="00" ) else  ----refresh

       BCD2 when(refresh="01" ) else

       BCD3 when(refresh="10" ) else  

       BCD4 when(refresh="11" ) else

       "XXXX";



   process(wer)                    -----wer为扫描脉冲

     begin

       if(wer'event and wer='1')then

         refresh<=refresh+1;       -----通过refresh四种状态选择点亮

       end if;                        数码管

   end process;      

   

--dig signal generate

   with REFRESH select            -------数码管位选译码

      DIG <= "1110" when "00",

           "1101" when "01",

             "1011" when "10",

             "0111" when "11",

             "XXXX" when others;

end muli_fre_light_arch;



4.管脚锁定文件说明:                     

net   reset     loc=p33;      复位和启动管脚,在EDA板上为跳线最左端脚

                          使用时把P33接地则开始计数,把P33不接地则清零

    net   change    loc=p7;       频率选择按键,每按一下换一档频率

    net   direct      loc=p6;       方向选择按键,每按一下换一次方向

    net   dp        loc=p39;      百位小数点,常亮

    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      light<2> loc=p1;        频率状态指使灯

      net      light<1>  loc=p40;

      net      light<0> loc=p42;

      net      dire     loc=p29;        方向状态指使灯

5.元件clk_25说明:

      library IEEE;                        ——clk_25用来产生计数频率和

      use IEEE.std_logic_1164.all;                 扫描频率

      use IEEE.std_logic_unsigned.all;



   entity clk_25hz is

       port (

           clks,clks1,clks2,clks3,clks4,clks5,wer: inout STD_LOGIC);

   end clk_25hz;



   architecture clk_25hz_arch of clk_25hz is

   signal  clkin:std_logic;

   signal counter:std_logic_vector(12 downto 0);  

   signal aq:std_logic_vector(1 downto 0);        

   signal fp:std_logic_vector(4 downto 0);        



   component os                             -----只要熟悉分频,这边很简单

      port (osout:out std_logic);   

   end component;



   begin



   u1:os port map(clkin);



   wer<=fp(4);



    process(clkin)

     begin

       if(clkin'event and clkin='1')then

         fp<=fp+1;

       end if;

   end process;   



   process(wer)

   begin

     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;



   process(clks)

      begin

         if(clks'event and clks='1')then      

               aq<=aq+1;

         end if;

   end process;



   clks1<=aq(1);      



   process(clks1)

      begin

         if(clks1'event and clks1='1')then

           clks2<=not clks2;                  

         end if;

   end process;



   process(clks2)

      begin

         if(clks2'event and clks2='1')then

           clks3<=not clks3;                  

         end if;

   end process;



   process(clks3)

      begin

         if(clks3'event and clks3='1')then

           clks4<=not clks4;                  

         end if;

   end process;



   process(clks4)

      begin

         if(clks4'event and clks4='1')then

           clks5<=not clks5;                  

         end if;

   end process;

   end clk_25hz_arch;

6. muli_fre_light具体实现方法:

   #1.新建一个文件夹,将muli_fre_light.vhd, muli_hz_vhd, os.xnf, muli_fre_light.ucf

      copy 到该文件夹下。

   #2.运行xilinx软件,并将管脚锁定。

   #3.跳线用于启动和清零,S2用于切换频率,S1用于切换方向。












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

Markdown 语法

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

Markdown 语法

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

举报类型

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

详细说明

易百纳技术社区