693|0

44

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

【Tang Primer25K Dock】三——数码管基本显示和原理 [复制链接]

 
本帖最后由 Zhao_kar 于 2023-12-9 16:11 编辑

【Tang Primer25K Dock】三——数码管基本显示和原理

备注:

  • 本节主要为数码管的基本测试,单独测试数码管从0-9+led的辅助显示的测试,同时计数满一个周期,切换到下一个数码管显示;
  • 前面大概说过这个数码管的原理,这个数码管只有一个位选信号,位选信号的高低电平分别选择两个数码管的显示,与常规的一个数码管由一个位选信号决定亮灭不太一样
  • 下一节为数码管的动态显示电路,从00到11,从而到99,去做一个基础的动态显示测试。

一、数码管原理

  1. 根据从官方下载的原理图可以看出,本次测试使用的是八段数码管,八段数码管如下所示(原理图),是一个8字型的数码管,分为八段,对应abcdefg和小数点dp,每一段就是一个发光二极管,这样的八段我们称为段选,实际上,每个段选实际上就是控制着led的亮灭。

     

  2. 数码管分为共阳极和共阴极,具体原因就不仔细解释了,这个是可以根据原理图判断的,而sipeed的pmod是共阳极的,根据共阳极的表,你可以根据表来进行操作,比如我想让他显示1,那就是让数码管的右边的两个led亮就行了,如下图(显示图)

     

  3. 根据表,可以得到我们想要的实际数据,比如我想让数码管显示0,就对七个段选给信号就行了,这边以abcdefg为例,应该为7'b0000001,但是这个数码管,如果按照实际的表来,你会发现他是反过来的,为了契合我们的25k开发板,pmod朝下,所以我借鉴了官方例程的值,如下。
  4. 说了这么多,其实简单表述就是,你给一个七位的段选值,让数码管显示对应的值,而具体的效果你可以根据原理图操作,可以查表直接用,这个一般是固定的,没有什么特别的。
/***************parameter*************/
localparam          P_0 = 7'b0000001    ;
localparam          P_1 = 7'b1111001    ;
localparam          P_2 = 7'b0010010    ;
localparam          P_3 = 7'b0110000    ;
localparam          P_4 = 7'b1101000    ;
localparam          P_5 = 7'b0100100    ;
localparam          P_6 = 7'b0000100    ;
localparam          P_7 = 7'b1110001    ;
localparam          P_8 = 7'b0000000    ;
localparam          P_9 = 7'b0100000    ;
localparam          P_X = 7'b1111111    ;
/***************reg*******************/

二、时序设计实现

  1. 前面两节都没有时序逻辑的解释,而这一节大概讲讲,首先根据需求去设计,我们要做的是一个0-9的显示,其实简单说就是一个0-9的计数器,外加led的显示和数码管的位选信号的测试。
  2. 既然要0-9变化,所以要给一个1s的信号,而这个1s的信号(应该说时钟信号),用他来决定计数时间,比如我在一个always里面,如果使用的系统时钟(上升沿下降沿不解释了,先知道一般时钟上升沿触发,rst下降沿触发就行了),那么这一部分的执行,会在每次时钟上升沿来临时执行一次,所以,如果实现0-9的计数器,我们需要一个中间值,在1s信号来临的时候,计数1次,以此类推,当计数到9时,再执行清零。
  3. 阻塞与非阻塞这个比较麻烦,我不觉得我能短篇幅内解释清楚,这里给出一个我个人的理解:先看下面两个代码和一张图,关键是看时序图,在这张图里面,阻塞赋值部分,两个时钟输出是一样的,而非阻塞的out2要慢一个时钟周期,这个就是区别,具体为,always语句过程种,阻塞赋值时,block1已经=block_in了,然后到b2=b1,此时b1已经为in的值了,所以两个值是一样的;而非阻塞赋值,b1=b_in时,值不会马上变,然后到b2=b1,此时b2等于的是还没上升的b1,所以后续体现为0,而这个变化会在always结束后体现,也就是值的变化操作在always结束后执行,而在虽然b1=b_in了,但是always还没结束,此时b1还是0,而b2等于的是结束前的b1,所以b2会比b1慢一个时钟周期变化。对于阻塞部分,因为是在进行的过程就进行了操作,也就是b2=b1时,b1已经等于b-in了。

     

  4. 前面都是基础知识,现在讲关键,分频的实现,总所周知这个是50M的系统时钟,我们要把他变成1hz的时钟,也就是1/50_000_000s * cnt =1s,由此得计数的cnt值为50_000_000,但是计数1s实际上应该给0.5s的显示,因为两个电平,所以最后cnt应该为25_000_000。

三、代码+注释

 

module digital_cnt
#(
    parameter   CNT_1HZ=28'd24_999_999//计数值
)
(
    input clk,//输入时钟
    input rst,//复位
    output[7:0]led,//8个led,忘记改了,其实二进制显示4个就行
    output reg [6:0]seg_n,//七个位选,决定数码管显示的值
    output sel
);
/***************parameter*************/
localparam          P_0 = 7'b0000001    ;
localparam          P_1 = 7'b1111001    ;
localparam          P_2 = 7'b0010010    ;
localparam          P_3 = 7'b0110000    ;
localparam          P_4 = 7'b1101000    ;
localparam          P_5 = 7'b0100100    ;
localparam          P_6 = 7'b0000100    ;
localparam          P_7 = 7'b1110001    ;
localparam          P_8 = 7'b0000000    ;
localparam          P_9 = 7'b0100000    ;
localparam          P_X = 7'b1111111    ;
/***************reg*******************/
reg [27:0] cnt_1hz;//1hz的寄存计数器
reg clk_1hz=1'b0;
//分1s时钟
always @(posedge clk or negedge rst)
    if (rst == 1'b0) begin//如果按下复位按键,此时cnt为0,重置
        cnt_1hz <= 28'd0;
    end else if (cnt_1hz == CNT_1HZ) begin//如果计数到最大值清零
        cnt_1hz <= 28'd0;
        clk_1hz = ~clk_1hz;//翻转
    end else begin
        cnt_1hz <= cnt_1hz + 1'b1;//加1计数,一个clk加一次
    end

//数码管计数0-9
reg [3:0]   data_temp;
wire [3:0]  data;//值
reg sel_temp;//sel的选择值,以数码管显示0-9为一个周期,变化一次
assign data=data_temp;    
always@(posedge clk_1hz or negedge rst)
    if(rst==1'b0)
       data_temp<=4'b0000;
    else if(data_temp==4'b1001)begin//如果等于9
         data_temp<=4'b0000;//数码管中间值为0
         sel_temp <= ~sel_temp;位选翻转
    end  else
        data_temp<=data_temp+1'b1;//+1

//led的计数,原理跟数码管一样
reg [3:0] led_out;
assign led=~led_out;
always@(posedge clk_1hz or negedge rst)
    if(rst==1'b0)
       led_out<=4'b0000;
    else if(led_out==4'b1001)
        led_out<=4'b0000;
    else
       led_out<=led_out+1'b1;

//数码管数据选择,译码部分,见第二节
always @ (data)
        case(data)
            4'b0000: seg_n <= P_0;
            4'b0001: seg_n <= P_1;
            4'b0010: seg_n <= P_2;   
            4'b0011: seg_n <= P_3;
            4'b0100: seg_n <= P_4;
            4'b0101: seg_n <= P_5;
            4'b0110: seg_n <= P_6;
            4'b0111: seg_n <= P_7;
            4'b1000: seg_n <= P_8;
            4'b1001: seg_n <= P_9;
            default: seg_n <= P_X;      
        endcase

assign sel=sel_temp;//数码管使能,默认

endmodule

四、引脚约束(其实变动的只有数码管)

1、code

//Copyright (C)2014-2023 Gowin Semiconductor Corporation.
//All rights reserved. 
//File Title: Physical Constraints file
//GOWIN Version: V1.9.9 Beta-5
//Part Number: GW5A-LV25MG121NES
//Device: GW5A-25
//Device Version: A
//Created Time: Fri 12 08 18:00:14 2023

IO_LOC "sel" K5;
IO_PORT "sel" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "seg_n[6]" L11;
IO_PORT "seg_n[6]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "seg_n[5]" K11;
IO_PORT "seg_n[5]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "seg_n[4]" L5;
IO_PORT "seg_n[4]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "seg_n[3]" E10;
IO_PORT "seg_n[3]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "seg_n[2]" E11;
IO_PORT "seg_n[2]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "seg_n[1]" A11;
IO_PORT "seg_n[1]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "seg_n[0]" A10;
IO_PORT "seg_n[0]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[7]" C10;
IO_PORT "led[7]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[6]" C11;
IO_PORT "led[6]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[5]" B10;
IO_PORT "led[5]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[4]" B11;
IO_PORT "led[4]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[3]" D10;
IO_PORT "led[3]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[2]" D11;
IO_PORT "led[2]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[1]" G10;
IO_PORT "led[1]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "led[0]" G11;
IO_PORT "led[0]" PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
IO_LOC "rst" F5;
IO_PORT "rst" PULL_MODE=NONE DRIVE=OFF BANK_VCCIO=3.3;
IO_LOC "clk" E2;
IO_PORT "clk" PULL_MODE=NONE DRIVE=OFF BANK_VCCIO=3.3;

2、foolplanner图

五、演示,详情见视频

PS:在宿舍录的,背景很吵,请把声音关掉观看。

0-9显示

 

点赞 关注(1)
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表