数码管动态扫描显示

摸鱼记录 Day_16      (゚O゚)

review

        前边已经学习了:

        串口接收:Vivado 串口接收优化-CSDN博客

1.  今日摸鱼任务

串口接收数据

并用数码管显示 (゚O゚)

小梅哥视频:

17A 数码管段码显示与动态扫描原理_哔哩哔哩_bilibili

17B 数码管动态扫描显示数字逻辑建模_哔哩哔哩_bilibili

17C 数码管动态扫描显示的Verilog实现_哔哩哔哩_bilibili

17D 使能时钟和门控时钟的原理与差异_哔哩哔哩_bilibili

//虽然看起来很多,但是不会很难滴 (゚O゚)

2.  数码管显示原理

        ACZ702 EDA 扩展板上板载的是共阳数码管。同时为了显示数字或字符,必须对数字或字符进行编码译码。

        先不考虑小数点也就是简化为 7 段数码管,其编码译码格式如下表所示:

        段式数码管工作方式有两种:静态显示方式动态显示方式

        静态显示:每个数码管的段选必须接一个 8 位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。

        这种方法由于每个数码管均需要独立的数据线,硬件电路比较复杂,成本较高,很少使用。

        动态显示:将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。

         电路结构如下所示,这样 3 个数码管接在一起就比静态的少了 7*2 I/O
        sel拉高选中

3.   时钟分频:门控时钟与使能时钟

门控时钟:

        使用计数器和逻辑门翻转产生

    reg [14:0]div_clk;    
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        div_clk <= 1'b0;
    else if(div_clk == 24999) 
        div_clk <= 1'b0;
    else 
        div_clk <= div_clk + 1'b1;
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        clk_1 <= 1'b0;
    else if(div_clk == 24999) 
        clk_1 <= ~clk_1;

使能时钟:

        用到计数器,但是不会用到反相器,生成的信号也不会直接用于其他电路的触发

    reg [14:0]div_clk;    
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        div_clk <= 1'b0;
    else if(div_clk == 24999) 
        div_clk <= 1'b0;
    else 
        div_clk <= div_clk + 1'b1;

always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        disp_en <= 1'b0;
    else if(div_clk == 24999) 
        disp_en <= 1'b1;
    else 
        disp_en <= 1'b0;  

对比:

        门控时钟的时钟延迟不稳定,且延迟比较大

                          使得时钟的波形变差

                          驱动能力差

小结:设计中一般情况下使用使能时钟的时钟分频方式

4.  hex_8

4.1 design sources

hex_8

module hex_8(input clk,
             input reset_n,
             input [31:0]disp_data,
             output reg [7:0]sel,
             output reg [7:0]seg
             );

//[31:0]disp_data  16hex 4*8
//[7:0]sel 位选信号
//[7:0]seg 段选信号

// 1kHz分频时钟 
    reg [14:0]div_clk;
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        div_clk <= 1'b0;
    else if(div_clk == 24999) 
        div_clk <= 1'b0;
    else 
        div_clk <= div_clk + 1'b1;
    reg disp_en;
   always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        disp_en <= 1'b0;
    else if(div_clk == 24999) 
        disp_en <= 1'b1;
    else 
        disp_en <= 1'b0;    

//  位选sel
    reg[2:0]sel_num;
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        sel_num <= 3'b000;
    else if(disp_en) 
        sel_num <= sel_num + 1'b1;
        //sel_num =3’b111; +1'b1  3'b000;
    always@(posedge clk or negedge reset_n)
    if(!reset_n) 
        sel <= 8'b0000_0000;
    else case(sel_num) 
         0:sel <= 8'b0000_0001;
         1:sel <= 8'b0000_0010;
         2:sel <= 8'b0000_0100;
         3:sel <= 8'b0000_1000;
         4:sel <= 8'b0001_0000;
         5:sel <= 8'b0010_0000;
         6:sel <= 8'b0100_0000;
         7:sel <= 8'b1000_0000;
    endcase   
   
// 段选seg   [31:0]disp_data  16hex 4*8
    reg [3:0] dis_tmp;
    always@(posedge clk )
    case(sel_num) //高位放前面
         0:dis_tmp <= disp_data[31:28];
         1:dis_tmp <= disp_data[27:24];
         2:dis_tmp <= disp_data[23:20];
         3:dis_tmp <= disp_data[19:16];
         4:dis_tmp <= disp_data[15:12];
         5:dis_tmp <= disp_data[11:8];
         6:dis_tmp <= disp_data[7:4];
         7:dis_tmp <= disp_data[3:0];
    endcase 
    
    always@(posedge clk)
    case(dis_tmp) 
         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;
         4'ha:seg <= 8'h88;
         4'hb:seg <= 8'h83;
         4'hc:seg <= 8'hc6;
         4'hd:seg <= 8'ha1;
         4'he:seg <= 8'h86;
         4'hf:seg <= 8'h8e;
    endcase 

endmodule

4.2 hex_8_tb

`timescale 1ns / 1ns
    module hex_8_tb( );
    reg clk , reset_n;
    reg [31:0]disp_data;
    wire[7:0]sel;
    wire[7:0]seg;
     hex_8 hex_8_(. clk(clk),
                 . reset_n(reset_n),
                 . disp_data(disp_data),
                 . sel(sel),
                 . seg(seg) );
                 
         initial clk = 1 ;
         always#10 clk = ~clk;
         
         initial 
             begin
                reset_n = 0 ;
                #201;
                reset_n = 1 ;
                disp_data = 32'h01234567;
             #10000000;
             disp_data = 32'h89abcdef;
             #10000000;
             $stop;
             end            

    endmodule

红色框框内输入数据发生了改变,但是很快就会闪过去

所以没有像串口发送添加一个存储数据让其保持一个运行周期

Vivado 串口通信(UART)------串口发送-CSDN博客

5.  串口接收 + 数码管动态显示

5.1 design sources

module uart_rx(input clk ,
                 input reset_n ,
                 input uart_rx ,
                 output reg [7:0]rx_data,
                 output reg rx_done    );
    //默认使用波特率BAUD 9600  时钟频率 CLK_FREQ  50MHz
//    parameter start_bit = 0 ;
//    parameter stop_bit  = 1 ;
    parameter BAUD = 9600;
    parameter CLK_FREQ = 50_000_000;
    parameter bps_c = CLK_FREQ / BAUD ;    
    reg rx_en ;   
    reg[3:0] rx_flag;
        // bps 
        reg [30:0] counter_bps ;        
      always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            counter_bps <= 0 ;
        else if (rx_en)
            if(counter_bps == bps_c - 1)
                counter_bps <= 0 ;
            else
                counter_bps <= counter_bps + 1'b1 ;
        else
            counter_bps <= 0 ;
        reg dff_rx_0 , dff_rx_1 ;
        reg r_uart_rx; 
        wire neg_rx_go ;
        always@(posedge clk )    
            dff_rx_0 <= uart_rx ;
        always@(posedge clk )    
            dff_rx_1 <= dff_rx_0 ;
        always@(posedge clk )    
            r_uart_rx <= dff_rx_1 ;
            
        assign neg_rx_go = (dff_rx_1 == 0)&&(r_uart_rx == 1);
        
      // rx_en 
        always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            rx_en <= 0 ;
        else if(neg_rx_go) 
            rx_en <= 1 ;
        else if((rx_flag==9)&&(counter_bps == bps_c / 2))
            rx_en <= 0 ;
        else if((rx_flag==0)&&(counter_bps == bps_c/2 )&&(dff_rx_1==1)) 
            rx_en <= 0 ;
               
     // rx_flag
        always@(posedge clk or negedge reset_n)
        if(!reset_n) rx_flag <= 4'b0000 ;
        else if((rx_flag == 9)&&(counter_bps == bps_c /2)) rx_flag <= 4'b0000 ;
        else if(counter_bps == bps_c - 1)  rx_flag <= rx_flag + 1'b1 ;
         
     // [7:0]r_rx_data   
     reg [7:0] r_rx_data;
     always@(posedge clk )
       if(!rx_en) r_rx_data <= r_rx_data;
       else if(counter_bps == bps_c / 2)
        begin 
            case(rx_flag)
            1 : r_rx_data[0] <= dff_rx_1;
            2 : r_rx_data[1] <= dff_rx_1;
            3 : r_rx_data[2] <= dff_rx_1;
            4 : r_rx_data[3] <= dff_rx_1;
            5 : r_rx_data[4] <= dff_rx_1;
            6 : r_rx_data[5] <= dff_rx_1;
            7 : r_rx_data[6] <= dff_rx_1;
            8 : r_rx_data[7] <= dff_rx_1;
            default : r_rx_data <= r_rx_data;
            endcase
            
        end      
    // rx_done
     always@(posedge clk)
            rx_done <= (rx_flag==9)&&(counter_bps == bps_c /2);
    // rx_data ;
       always@(posedge clk)
           if(rx_done) rx_data <= r_rx_data;  
endmodule
 
rx_hex8
module rx_hex8(input clk,
               input reset_n,
               input uart_rx ,
               output  [7:0]sel,
               output  [7:0]seg
                );
                
reg  [1:0] rx_done_flag;
reg [31:0]disp_data;
wire [7:0] rx_data;
wire rx_done;
    uart_rx uart_rx_(. clk(clk) , . reset_n(reset_n) ,.uart_rx(uart_rx) ,
                 . rx_data(rx_data), . rx_done(rx_done)    );
    always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            rx_done_flag <= 2'b11 ;
        else if(rx_done) 
            rx_done_flag <= rx_done_flag + 1'b1 ;
    always@(posedge clk or negedge reset_n)
        if(! reset_n) 
            disp_data <= 8'h0000_0000 ;
        else 
        case(rx_done_flag)
            0:begin disp_data <= disp_data; disp_data[7:0] <= rx_data;end
            1:begin disp_data <= disp_data; disp_data[15:8] <= rx_data;end
            2:begin disp_data <= disp_data; disp_data[23:16] <= rx_data;end
            3:begin disp_data <= disp_data; disp_data[31:24] <= rx_data;end
        endcase
    
    hex_8 hex_8_(. clk(clk),
             . reset_n(reset_n),
             . disp_data(disp_data),
             .sel(sel),
             .seg(seg)
             );
endmodule

5.2  rx_hex8_tb

`timescale 1ns / 1ns
    module hex_8_tb( );
    reg clk , reset_n , uart_rx_;
    wire[7:0]sel;
    wire[7:0]seg;
     rx_hex8 rx_hex8_(. clk(clk),
                 . reset_n(reset_n),
                 . uart_rx(uart_rx_),
                 . sel(sel),
                 . seg(seg)
                 );        
         initial clk = 1 ;
         always#10 clk = ~clk;
         
         initial 
             begin
                reset_n = 0 ;
                #201;
                reset_n = 1 ;
                uart_rx_ = 1 ;#(5208*20);
                //0 f   
        uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
        
             //9 6    
        uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
        
                //4 5  
        uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);uart_rx_ = 1 ;

         #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
         
        // 3 c   
        uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
        
                //0 f   
        uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
        
             
        uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
        
                
        uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
         
        
       uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);
         
         uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);

        uart_rx_ = 0 ; #(5208*20);uart_rx_ = 0 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);

        uart_rx_ = 1 ; #(5208*20);uart_rx_ = 1 ; #(5208*20);
        uart_rx_ = 1 ; #(5208*20);     
                # 10000;      
             $stop;
             end            

    endmodule

//好耶~~~~~

//摸鱼结束哩   (゚O゚)

//顺便挖坑SPI协议

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/540241.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.绪论

目录 1.1 Web原理基础 1.1.1 Internet与万维网 1.1.2 Web架构 1.2 Web前端技术基础 1.2.1 HTML技术 1.2.2 CSS技术 1.2.3 JavaScript技术 1.3 Web前端新技术 1.3.1 HTML5技术 1.3.2 CSS3技术 1.3.3 jQuery技术 1.4 Web开发工具 1.1 Web原理基础 1.1.1 Internet与万…

Github和TeamCity的持续集成构建

一、简介 TeamCity是JetBrains旗下的一款持续集成[Continuous Integration&#xff0c;简称CI]工具&#xff0c;开箱即用。TeamCity提供一系列特性可以让团队快速实现持续集成&#xff1a;IDE工具集成、各种消息通知、各种报表、项目的管理、分布式的编译等等。 二、安装使用(…

Python实时追踪关键点组成人体模型

项目背景 最近遇到这样一个需求&#xff1a; 1&#xff1a;实时追踪关键点组成人体模型&#xff08;手臂包括三个点&#xff1a;手腕&#xff0c;肘关节&#xff0c;双肩&#xff1b;腿部包括胯骨&#xff0c;膝盖&#xff0c;脚踝&#xff09; 2&#xff1a;运用追踪到的关键…

github 中的java前后端项目整合到本地运行

前言: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未…

K8S CNI

OCI基本概念 OCI&#xff0c;Open Container Initiative&#xff0c;开放容器标准&#xff0c;是一个轻量级&#xff0c;开放的治理结构&#xff08;项目&#xff09;&#xff0c;在 Linux 基金会的支持下成立&#xff0c;致力于围绕容器格式和运行时创建开放的行业标准。 OCI…

减资公告重磅上线:批量查询与实时监控,教你如何在公告期洞察企业风险!

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 新《公司法》将于2024年7月1日起施行。不少企业注意到其中的一大变化&#xff1a;新《公司法》对有限责任公司认缴登记制进行了完善&#xff0c;明确全体股东认缴的出资额由股东按照公司章程的规定自公司成立之日…

全栈的自我修养 ———— python使用绘制工具turtle

实现基础turtle入门 一、下载二、基础知识三、实现效果1、圆2、五3、蛇5、循环的正方形 一、下载 turtle是python中模块中自带的一般不需要下载如果报错如下&#xff0c;需要下载自己下载python-tk模块,详细请看python-tk下载 (mac的话可以直接用brew install python-tk) (my…

工具篇--分布式定时任务springBoot--elasticjob简单使用(1)

文章目录 前言一、elasticjob 介绍&#xff1a;二、elasticjob 使用&#xff1a;2.1 部署zookeeper&#xff1a;2.2 引入库2.2 定义任务&#xff1a;2.3 任务执行&#xff1a;2.4 任务执行控制台输出&#xff1a; 三、elasticjob 启动错误&#xff1a;3.1 KeeperErrorCode Ope…

JavaWeb(二)

目录 二、JavaScript 1.定义 2.js引入方式 1.内部脚本 2.外部脚本 3.js基本语法 1.书写语法 2.变量 3.数据类型、运算符、流程控制语句 1.原始类型 2.引用类型 3.运算符 4.类型转换 1.字符串类型转为数字&#xff1a; 2.其他类型转为boolean&#xff1a; 5.流程…

Git概述及安装步骤

一、Git简介 Git是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目。Git 易于学习&#xff0c;占地面积小&#xff0c;性能极快。它具有廉价的本地库&#xff0c;方便的暂存区域和多个工作流分支等特性。其性能优于Subversion、CV…

Elasticsearch:使用标记修剪提高文本扩展性能

作者&#xff1a;来自 Elastic Kathleen DeRusso 本博客讨论了 ELSER 性能的令人兴奋的新增强功能&#xff0c;该增强功能即将在 Elasticsearch 的下一版本中推出&#xff01; 标记&#xff08;token&#xff09;修剪背后的策略 我们已经详细讨论了 Elasticsearch 中的词汇和…

Windows客户端漏洞挖掘(红队角度)

0x01 前言 周五的时候看了key佬的演讲受益良多呀&#xff0c;来水水&#xff0c;写下目前针对Windows客户端类程序的部分挖掘入口吧&#xff0c;然后分享一下随手挖的很简单很简单的案例。 传统客户端 监听类的: 这里说的监听类的&#xff0c;指的就是安装客户端后启动的端口…