雾盈 发表于 2016-8-10 19:59:51

雾盈FPGA笔记之(二十)显示三位数字的通用数码管程序

本帖最后由 雾盈 于 2016-8-28 13:42 编辑

显示三位数字的通用数码管程序
雾盈                2016-8-10

雾盈FPGA笔记汇总目录

        我们先不讲数码管的原理,我们先说步骤,从步骤中把其中的原理都讲清楚。
        为了让数码管显示,有哪些步骤?

        第一步、数据转换

        让十进制数字能够在数码管上显示出来 ,例如128
        Ones = (data_In )% 10;
        Ones =128 % 10=8
        Tens =(data_In /10 )% 10;
        Tens =128/10%10 = 2
        Hundres = (data_in /100 ) % 10 ;
        Hunders =128 /100 % 10 = 1
        更多位数的十进制数字以此类推。
那我们可不可以总结出一个小公式,这样也算有了一个小算法啊对不对,
算了,想了一会儿发现,其实这个已经够简练了,再 整个算法就复杂了。= =
谁有简单的方式可以分享一下。
   
        第二步、分频一个片选扫描时钟

        因为选择让哪个数码管显示是由片选信号SEL 决定的。Sel是个三位位宽的38译码器。

000 表示 选中 第一个数码管
001 表示 选中 第二个数码管
011 表示 选中 第四个数码管
以此类推。

        但是,你也看出来了,sel控制的信号一次只能选中一个数码管,为了让多位数码管同时显示,怎么办呢?
        于是,我们要用到这个扫描时钟,这个时钟不能频率太高,太高扫描速度太快,你根本不能看到数码管显示。
也不能频率太低,太低的话,你看到的数码管就不是同时亮了,而是有间隔延迟的亮灭。
        一般我们会根据经验选择1kHz - 10 kHz 的分频时钟驱动sel去扫描数码管。

        第三步、数码管数据的查找表

        数码管的原理图如下



一个数码管由8个led灯构成(包括小数点),让每个led 保持高电平或者低电平就可以显示不同的字母或数字。
这样就会有0-F 对应的显示查找表。代码如下:

case( seg_data )
                                0: seg = 8'hc0;
                                1: seg = 8'hf9;
                                2: seg = 8'ha4;
                                3: seg = 8'hb0;
                                4: seg = 8'h99;
                                5: seg = 8'h92;
                                6: seg = 8'h82;
                                7: seg = 8'hf8;
                                8: seg = 8'h80;
                                9: seg = 8'h90;
                                10: seg = 8'h88;
                                11: seg = 8'h83;
                                12: seg = 8'hc6;
                                13: seg = 8'ha1;
                                14: seg = 8'h86;
                                15: seg = 8'h8e;         
             endcase



到这里,数码管最核心的三个部分讲完了,其它就是根据不同的功能,增加不同的程序了。

后面贴上显示三位数的数码管通用程序。

//=====================================================================
// module name:                smg
// function:                project iic_rd
// create data:                from 2016-8-5 10:04:16 to2016-8-10 17:48:14
// editor:                        miao
// note :                           reference the code of techer chen
// Tool versions:         quartus 13.0
//=====================================================================
module        smg(
                        //system signal
                        input                                        clk                        ,       //50MHZ system clock
                        input                                        rst_n                ,
                        //external input
                        input                                data_in                        ,
                        // output         signal
                        output        reg                 sel                                 ,         // CS signal
                        output        reg                 seg                                     // LS signal
                        );
//=========================================================================================================
//**************************   Define parameter and internal signals          *********************************
//=========================================================================================================
reg                        clk_10K        ;                         // 10KHZ clock for sel
reg                 count        ;                        //count for frequency division10KHZ
parameter         CNT_MAX         = 2500 - 1;                         // count 2500 times for 10KHZ

reg         seg_data        ;
reg         ones         ;
reg         tens                 ;
reg         hundreds         ;

//=========================================================================================================
//*********************************         frequency division 10KHZ for sel*********************************
//=========================================================================================================
always @ (posedge clk or negedge rst_n)
begin
   if(!rst_n)
      begin
                        clk_10K <= 1'b0;
      end
   elsebegin
            if( count == CNT_MAX )
                                begin
                                        count <= 1'b0        ;
                                        clk_10K <= ~clk_10K ;
                                end
                        elsebegin
                                        count <= count + 1'b1;
                                  end
             end
end
//=========================================================================================================
//*********************************         data convert                 ***********************************
//=========================================================================================================
always @ (posedge clk or negedge rst_n)
begin
   if(!rst_n)
      begin
                  ones <= 4'd0                ;
                  tens <= 4'd0                ;
                  hundreds <= 4'd0        ;
      end
   elsebegin
            ones <= data_in % 10;
                        tens <= (data_in / 10) % 10                ;
                        hundreds <= (data_in /100) % 10        ;                       
            end
end
//=========================================================================================================
//*********************************         smg code                 ***********************************
//=========================================================================================================

// cut out the last three of sel
always @ (posedge clk_10K or negedge rst_n)
begin
   if(!rst_n)
      begin
                        sel <= 3                        ;
      end
   elsebegin
                    if( sel <= 5 )
                        sel <= sel + 1'b1        ;
                  else
                        sel <= 3                        ;
             end
end

// seg_data for display
always @ (posedge clk or negedge rst_n)
begin
   if(!rst_n)
      begin               
                  seg_data <= 4'd0                ;
      end
   elsebegin
                 case( sel )
             3:begin
                seg_data <= hundreds ;
               end
             4:begin
                seg_data <= tens ;
               end
          5:begin
                seg_data <= ones ;
               end
             default: seg_data <= seg_data ;            
             endcase
             end
end

// LUT for display
always @ (posedge clk or negedge rst_n)
begin
   if(!rst_n)
      begin                       
                        seg <= 8'hff;
                       d
   elsebegin
         case( seg_data )
                                0: seg = 8'hc0;
                                1: seg = 8'hf9;
                                2: seg = 8'ha4;
                                3: seg = 8'hb0;
                                4: seg = 8'h99;
                                5: seg = 8'h92;
                                6: seg = 8'h82;
                                7: seg = 8'hf8;
                                8: seg = 8'h80;
                                9: seg = 8'h90;
                                10: seg = 8'h88;
                                11: seg = 8'h83;
                                12: seg = 8'hc6;
                                13: seg = 8'ha1;
                                14: seg = 8'h86;
                                15: seg = 8'h8e;         
             endcase
             end
end


endmodule











雾盈 发表于 2016-8-10 20:08:26

代码编辑器好难用

zhiweiqiang33 发表于 2016-8-11 09:44:11

写的不错 值得分享 谢谢 楼主

芙蓉王 发表于 2016-8-11 16:08:58

                                           谢谢分享

Sunlife 发表于 2016-8-13 17:09:12

                厉害

zhiweiqiang33 发表于 2016-8-16 11:56:53

受教,好好努力,加油;;

Esmiamor 发表于 2016-8-17 11:22:08

   支持。

嘿哈嘿哈哈 发表于 2023-7-23 09:08:02

雾盈FPGA笔记之(二十)显示三位数字的通用数码管程序
页: [1]
查看完整版本: 雾盈FPGA笔记之(二十)显示三位数字的通用数码管程序