zoukankan      html  css  js  c++  java
  • 数码管一些列功能的verilog实现

    将数码管各段发光元件的正极连在一起称为共阳数码管,且该共点击链接电路电源的正极,而各段的负极连接驱动电路。它适用于低电平有效的驱动电路,当某段的驱动电平为低电平时,该段发亮;将数码管各段发光元件的负极连在一起称为共阴数码管,且该电平连接电源的负极,而各段元件的正极驱动电路,它适用于高电平有效的驱动电路,当某段的驱动电平为高电平,该段发光。

    imageimage

    1.数码管的动态显示 驱动多位数码管需要动态扫描显示,假如是8位数码管显示,则需要先设计一个计数器,8位计数器,不断扫描。动态扫描显示时刷新频率最好大于50HZ,即显示一轮的时间不要超过20ms,每个数码管显示时间不能太长也不能太短,时间太长会影响刷新频率,导致整体出现闪烁的现象,时间太短发生二极管的电流导通时间也就短,会影响总体的显示亮度。一般控制在1ms左右。

    module seg(clk,wei,duan);//50MHZ时钟输入,duan:数码管位吗,wei:数码管段码,‘0’led亮
    input clk;
    output [7:0]wei;
    output [7:0]duan;
    reg [7:0]wei;
    reg [7:0]duan;
    integer count;//分频计数器,每计数到50000下clk_1k时钟翻转
    reg clk_1k;//数码管扫描时钟2ms
    reg [2:0]wei_count;//位码计数器
    
    
    always @(posedge clk)//分频进程
    begin
       if(count==500000)
         begin
         count=0;
         clk_1k=~clk_1k;
         end
       else
         count=count+1;
    end
    
    always @(posedge clk_1k)//数码管扫描进程    
       begin
            case(wei_count)  
                3'b000: begin wei=8'b11111110; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
                3'b001: begin wei=8'b11111101; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
                3'b010: begin wei=8'b11111011; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
                3'b011: begin wei=8'b11110111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
                3'b100: begin wei=8'b11101111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
                3'b101: begin wei=8'b11011111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
                3'b110: begin wei=8'b10111111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
                3'b111: begin wei=8'b01111111; duan=8'b0000_0000;wei_count=wei_count+1'b1;end
             endcase
       end
    endmodule

    2.秒表数码管显示 :秒表的设计原理:首先通过分频器产生一个频率为1HZ的时钟座位计数源,设置两个寄存器分别用来存储计数值,一个为寄存个位数,一个寄存十位数,同时同时产生一个数码管位选时钟,用来对数码管的位选进行扫描。(0到60,秒表)

    image

    module second(clk,duan,wei);//clk:50MHZ时钟输入,duan:数码管段码,wei:数码管位码
    input clk;
    output [7:0]duan;
    output [1:0]wei;
    reg [7:0]duan;
    reg [1:0]wei;
    
    integer count;//1HZ时钟计数器
    integer count2;//扫描时钟计数器
    reg clk_1hz;//1HZ时钟信号
    
    reg [3:0]ge;//数码管个位数BCD码
    reg [2:0]shi;//数码管十位BCD二进制码
    
    reg clk_scan;//数码管扫描时钟
    reg select; 
    
    
    always @(posedge clk)//1HZ时钟进程
      begin
        if(count==25000000)
          begin
             clk_1hz=~clk_1hz;
             count=0;
          end
        else
           count=count+1'b1;
      end
      
    always @(posedge clk_1hz)//秒表功能进程
      begin
        if(ge==4'b1001)
          begin
             ge=4'b0000;
             if(shi==3'b101)
               shi=3'b000;
             else
               shi=shi+1'b1;
          end
          
        else
          ge=ge+1'b1;
      end
          
    always @(posedge clk)//数码管扫描时钟产生进程
    begin
       if(count2==50000)
         begin
         count2=0;
         clk_scan=~clk_scan;
         end
       else
         count2=count2+1;
    end
       
    always @(posedge clk_scan)
     begin 
         select=select+1'b1;
     end
       
    always @(ge or shi or select)
     begin 
       if(select==1'b1)
       begin
       wei=2'b10;//秒表个位数显示
       case(ge)
           4'b0000:begin duan=8'b1100_0000;end
           4'b0001:begin duan=8'b1111_1001;end
           4'b0010:begin duan=8'b1010_0100;end
           4'b0011:begin duan=8'b1011_0000;end
           4'b0100:begin duan=8'b1001_1001;end
           4'b0101:begin duan=8'b1001_0010;end
           4'b0110:begin duan=8'b1000_0011;end
           4'b0111:begin duan=8'b1111_1000;end
           4'b1000:begin duan=8'b1000_0000;end
           4'b1001:begin duan=8'b1001_1000;end
           default duan=8'bx;
       endcase
       end
       else
       begin
     
       wei=2'b01;//秒表十位数显示
       case(shi)
           3'b000:duan=8'b1100_0000;
           3'b001:duan=8'b1111_1001;
           3'b010:duan=8'b1010_0100;
           3'b011:duan=8'b1011_0000;
           3'b100:duan=8'b1001_1001;
           3'b101:duan=8'b1001_0010;
           3'b110:duan=8'b1000_0011;
           default duan=8'bx;
       endcase
       end
    end
    endmodule

    IMG_8513

    3.时钟数码管显示:首先通过分频器产生一个频率为1HZ的时钟作为计数源,设置六个寄存器分别用来存储竖直,时分秒各用两个寄存器,一个为寄存个位数,另一个寄存十位数。当秒计数到达59时便向分进一,同时秒清零;当分计数达到59时,便向时进一,同时分清零;当时计数到达24时将时分秒计数寄存器同时清零。产生一个数码管位选时钟,用来对数码管的位选进行扫描。

    module time_clock(clk,duan,wei);//clk:50MHZ时钟输入,duan:数码管段码,wei:数码管位码
    input clk;
    output [7:0]duan;
    output [5:0]wei;
    reg [7:0]duan;
    reg [5:0]wei;
    
    integer count;//1HZ时钟计数器
    integer count2;//扫描时钟计数器
    reg clk_1hz;//1HZ时钟信号
    
    reg [3:0]miao_ge;//秒个位数BCD码
    reg [2:0]miao_shi;//秒十位BCD二进制码
    reg [3:0]fen_ge;//分钟个位数
    reg [2:0]fen_shi;//分钟十位数
    reg [1:0]shi_ge;//时钟个位数
    reg [1:0]shi_shi;//时钟十位数
    
    
    reg clk_scan;//数码管扫描时钟
    reg [2:0]select; //用于扫描时选择显示位码
    
    
    always @(posedge clk)//1HZ时钟进程
      begin
        if(count==25000000)
          begin
             clk_1hz<=~clk_1hz;
             count<=0;
          end
        else
           count<=count+1'b1;
      end
      
    always @(posedge clk_1hz)//秒分时各位累加功能进程
      begin
        if(miao_ge==4'b1001)
        begin
                 miao_ge<=4'b0000;
                 if(miao_shi==3'b101)
                 begin
                         miao_shi<=3'b000;
                         if(fen_ge==4'b1001)
                         begin
                                fen_ge<=4'b0000;
                                if(fen_shi==3'b101)
                                begin
                                    fen_shi<=3'b000;
                                    if(shi_ge==2'b11)
                                    begin
                                          shi_ge<=2'b00;
                                          if(shi_shi==2'b10)
                                            shi_shi<=2'b00;
                                          else
                                            shi_shi<=shi_shi+1'b1;                                      
                                    end
                                    else
                                    shi_ge<=shi_ge+1'b1;
                                end
                                else
                                fen_shi<=fen_shi+1'b1;
                         end
                         else
                         fen_ge<=fen_ge+1'b1;
                 end
                 else
                 miao_shi<=miao_shi+1'b1;
        end
          
        else
          miao_ge<=miao_ge+1'b1;
      end
          
    always @(posedge clk)//数码管扫描时钟产生进程
    begin
       if(count2==10000)
         begin
         count2<=0;
         clk_scan<=~clk_scan;
         end
       else
         count2<=count2+1;
    end
       
    always @(posedge clk_scan)
     begin 
         if(select==3'b110)
         select<=3'b000;
         else
         select<=select+1'b1;
         
     end
       
    always @(miao_ge or miao_shi or fen_ge or fen_shi or shi_ge or shi_shi or select)//敏感信号列表
     begin 
       if(select==3'b001)
       begin
       wei<=6'b111110;//秒个位数显示
       case(miao_ge)
           4'b0000:begin duan<=8'b1100_0000;end
           4'b0001:begin duan<=8'b1111_1001;end
           4'b0010:begin duan<=8'b1010_0100;end
           4'b0011:begin duan<=8'b1011_0000;end
           4'b0100:begin duan<=8'b1001_1001;end
           4'b0101:begin duan<=8'b1001_0010;end
           4'b0110:begin duan<=8'b1000_0011;end
           4'b0111:begin duan<=8'b1111_1000;end
           4'b1000:begin duan<=8'b1000_0000;end
           4'b1001:begin duan<=8'b1001_1000;end
           default duan<=8'bx;
       endcase
       end
       
       else if(select==3'b010)
       begin
       wei<=6'b111101;//秒十位数显示
       case(miao_shi)
           3'b000:duan<=8'b1100_0000;
           3'b001:duan<=8'b1111_1001;
           3'b010:duan<=8'b1010_0100;
           3'b011:duan<=8'b1011_0000;
           3'b100:duan<=8'b1001_1001;
           3'b101:duan<=8'b1001_0010;
           3'b110:duan<=8'b1000_0011;
           default duan<=8'bx;
       endcase
       end
       
       else if(select==3'b011)
       begin
       wei<=6'b111011;//分钟个位数显示
       case(fen_ge)
           4'b0000:begin duan<=8'b1100_0000;end
           4'b0001:begin duan<=8'b1111_1001;end
           4'b0010:begin duan<=8'b1010_0100;end
           4'b0011:begin duan<=8'b1011_0000;end
           4'b0100:begin duan<=8'b1001_1001;end
           4'b0101:begin duan<=8'b1001_0010;end
           4'b0110:begin duan<=8'b1000_0011;end
           4'b0111:begin duan<=8'b1111_1000;end
           4'b1000:begin duan<=8'b1000_0000;end
           4'b1001:begin duan<=8'b1001_1000;end
           default duan<=8'bx;
       endcase
       end
       
       else if(select==3'b100)
       begin
       wei<=6'b110111;//分钟十位数显示
       case(fen_shi)
           3'b000:duan<=8'b1100_0000;
           3'b001:duan<=8'b1111_1001;
           3'b010:duan<=8'b1010_0100;
           3'b011:duan<=8'b1011_0000;
           3'b100:duan<=8'b1001_1001;
           3'b101:duan<=8'b1001_0010;
           3'b110:duan<=8'b1000_0011;
           default duan<=8'bx;
       endcase
       end
       
       else if(select==3'b101)
       begin
       wei<=6'b101111;//时钟个位数显示
       case(shi_ge)
           4'b0000:begin duan<=8'b1100_0000;end
           4'b0001:begin duan<=8'b1111_1001;end
           4'b0010:begin duan<=8'b1010_0100;end
           4'b0011:begin duan<=8'b1011_0000;end
           default duan<=8'bx;
       endcase
       end
       
       else 
       begin
       wei<=6'b011111;//时钟十位数显示
       case(shi_shi)
           3'b000:duan<=8'b1100_0000;
           3'b001:duan<=8'b1111_1001;
           3'b010:duan<=8'b1010_0100;
           default duan<=8'bx;
       endcase
       end
    end
       
    endmodule

    6F17B2A1B71F02F55FE6292711A03BD6

  • 相关阅读:
    apt update ,apt upgrade 和 apt dist-upgrade 的区别
    CVE-2018-8639 简单利用 win7
    如何拆解性能测试需求
    博客搬家啦
    驱动开发学习一
    驱动开发基础之数据结构
    c++容器加迭代器和python装饰器的对比
    c++简单学习
    windows下z3安装
    switch反汇编
  • 原文地址:https://www.cnblogs.com/Fun-with-FPGA/p/4731192.html
Copyright © 2011-2022 走看看