18 19 SPI接口的74HC595驱动数码管实验

1. 串行移位寄存器原理(以四个移位寄存器为例)

1. 通过移位寄存器实现串转并:一个数据输入端口可得到四位并行数据。

通过给data输送0101数据,那么在经过四个时钟周期后,与data相连的四个寄存器的输出端口得到了0101这样的数据,然后我们将latch信号拉高,在下一个时钟周期,D0, D1, D2, D3同时分别获得了这四个数据1010。(其中DFF指D触发器,LATCH信号也可连接锁存器来控制输出)

2. 级联

级联:数据输出端口作为另外的移位寄存器数据端的输入。

2.使用74HC595驱动数码管

1. ACX720上不是直接用fpga的管脚驱动数码管的,而是用74HC595这样的一种串转并的串行移位寄存器来驱动的

2.1 74HC595端口图:

2.2 74HC595时序图

 2.3 74HC595时钟工作频率

取工作频率为12.5MHz。

3. 使用74HC595芯片驱动数码管的verilog代码实现

1.要完成的模块为hc595_driver,实现将16位并行数据转为串行数据发送至74HC595中,实现三线制控制数码管。因此我们的输入需遵循74HC595时序图。

3.1 设计代码

我们要输出shcp,stcp和ds,并满足它们的时序波形(照葫芦画瓢)。shcp的为最小的时间单元,我们可以根据它来作为其他信号波形的参照,但是切记不可将其作为门控时钟,我们只需要把这些要输出的信号当成普通信号,按照时序图上的时序输出即可。

1. shcp的时钟频率为12.5MHz,即一个周期为80ns,我们取半个周期为最小时间单元进行变化,即40ns。

2. 根据最小时间单元产生对应的节点,需要一个计数器记录这些节点(节点执行完开始下一次节点执行),产生节点后再在每个节点做相应的事情即可。

3. hc595_driver里的寄存器是从小到大排列的(0到15),即第0位数据最后进,放在最外面,第15位数据放在最里面。先进15,最后进0。

module hex8_2(
    clk,
    rstn,
    disp_data,
    sel,
    led
);
    
    parameter times = 50000; // 1ms
    input clk;
    input rstn;
    input [31:0]disp_data;
    output reg [7:0] sel;
    output reg [7:0] led;
    
    reg [15:0]div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(div_cnt >= times - 1)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'd1;
     
    //使能时钟  
    reg clk_lk;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        clk_lk <= 0;
    else if(div_cnt == times - 1)
        clk_lk <= 1'd1;
    else
        clk_lk <= 0;
    
    //cnt累加器
    reg [2:0] num_cnt;    
    always@(posedge clk_lk or negedge rstn)
    if(!rstn)
        num_cnt <= 0;
    else if(clk_lk == 1)
        num_cnt <= num_cnt + 1'd1;
    
    //三八译码器    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        sel <= 0;
    else case(num_cnt)
        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
   
    //八选一多路器
    reg [3:0]disp_tmp;
    always@(posedge clk)
    case(num_cnt)
        0:disp_tmp = disp_data[3:0];
        1:disp_tmp = disp_data[7:4];
        2:disp_tmp = disp_data[11:8];
        3:disp_tmp = disp_data[15:12];
        4:disp_tmp = disp_data[19:16];
        5:disp_tmp = disp_data[23:20];
        6:disp_tmp = disp_data[27:24];
        7:disp_tmp = disp_data[31:28];
    endcase
    
    //四十六译码器 
    always@(posedge clk)
    case(disp_tmp)
        0:led = 8'hc0;
        1:led = 8'hf9;
        2:led = 8'ha4;
        3:led = 8'hb0;
        4:led = 8'h99;
        5:led = 8'h92;
        6:led = 8'h82;
        7:led = 8'hf8;
        8:led = 8'h80;
        9:led = 8'h90;
        4'ha:led = 8'h88;
        4'hb:led = 8'h83;
        4'hc:led = 8'hc6;
        4'hd:led = 8'ha1;
        4'he:led = 8'h86;
        4'hf:led = 8'h8e;  
        default:led = 8'hc0;
    endcase

endmodule

module hc595_driver(
    clk,
    rstn,
    data,
    s_en,
    shcp,
    stcp,
    ds  
);

    parameter times = 2; //40ns为最小刻度
    input clk;
    input rstn;
    input [15:0] data;
    input s_en;
    output reg shcp;
    output reg stcp;
    output reg ds;
    
    reg [15:0] r_data;
    always@(posedge clk)
    if(s_en)
        r_data <= data;
    
    //1.产生74hc595时序所需的最小时间单元
    reg [7:0] div_cnt;
    
    //脉冲信号
    wire sck_plus;
    assign sck_plus = div_cnt >= times - 1;
    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(div_cnt >= times - 1)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'd1;
    
    //2.依据sck_plus做相对应的事情
    //先记录sck_plus的节点数
    reg [5:0]shcp_edge_counter;    
    always@(posedge clk or negedge rstn)
    if(!rstn)   
        shcp_edge_counter <= 0;
    else if(sck_plus) //sck_plus不是寄存器的输出    
        if(shcp_edge_counter == 32)            
            shcp_edge_counter <= 0;
        else
            shcp_edge_counter <=  shcp_edge_counter + 1'd1;
        
    always@(posedge clk or negedge rstn)
    if(!rstn) begin
        shcp <= 0;
        stcp <= 0;
        ds <= 0;
    end
    else case(shcp_edge_counter)
        0: begin shcp <= 0; ds <= r_data[15]; stcp <= 0; end
        1: shcp <= 1'd1;
        2: begin shcp <= 0; ds <= r_data[14]; end
        3: shcp <= 1'd1;
        4: begin shcp <= 0; ds <= r_data[13]; end
        5: shcp <= 1'd1;
        6: begin shcp <= 0; ds <= r_data[12]; end
        7: shcp <= 1'd1;
        8: begin shcp <= 0; ds <= r_data[11]; end
        9: shcp <= 1'd1;
        10: begin shcp <= 0; ds <= r_data[10]; end
        11: shcp <= 1'd1;
        12: begin shcp <= 0; ds <= r_data[9]; end
        13: shcp <= 1'd1;
        14: begin shcp <= 0; ds <= r_data[8]; end
        15: shcp <= 1'd1;
        16: begin shcp <= 0; ds <= r_data[7]; end
        17: shcp <= 1'd1;
        18: begin shcp <= 0; ds <= r_data[6]; end
        19: shcp <= 1'd1;
        20: begin shcp <= 0; ds <= r_data[5]; end
        21: shcp <= 1'd1;
        22: begin shcp <= 0; ds <= r_data[4]; end
        23: shcp <= 1'd1;
        24: begin shcp <= 0; ds <= r_data[3]; end
        25: shcp <= 1'd1;
        26: begin shcp <= 0; ds <= r_data[2]; end
        27: shcp <= 1'd1;
        28: begin shcp <= 0; ds <= r_data[1]; end
        29: shcp <= 1'd1;
        30: begin shcp <= 0; ds <= r_data[0]; end
        31: shcp <= 1'd1;
        32: begin shcp <= 0; stcp <= 1; ds <= 0; end
        default : begin
            shcp <= 0;
            stcp <= 0;
            ds <= 0;
        end
    endcase
        
endmodule

3.2 针对hc595_driver的仿真代码

`timescale 1ns / 1ps

module hc595_driver_tb();
    
    reg clk;
    reg rstn;
    reg [15:0] data;
    reg s_en;
    wire shcp;
    wire stcp;
    wire ds;

    hc595_driver hc595_driver_inst(
        clk,
        rstn,
        data,
        s_en,
        shcp,
        stcp,
        ds  
    );
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
        rstn = 0;
        #201;
        rstn = 1;
        #200;
        s_en = 1;
        data = 16'h1357;
        #4000;
        s_en = 0;
        #200;
        s_en = 1;
        data = 16'h2468;
        #4000;
        s_en = 0;
        $stop;
    end
    
endmodule

3.3 针对hc595_driver的仿真波形

 3.4 针对数码管的管脚约束文件

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode Python - 16.最接近的三数之和

目录 题目答案运行结果 题目 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,2,1,-4],…

项目访问量激增该如何应对

✨✨ 欢迎大家来到喔的嘛呀的博客✨✨ &#x1f388;&#x1f388;希望这篇博客对大家能有帮助&#x1f388;&#x1f388; 目录 引言 一. 优化数据库 1.1 索引优化 1.2 查询优化 1.3 数据库设计优化 1.4 事务优化 1.5 硬件优化 1.6 数据库配置优化 二. 增加服务器资源…

精品jsp+ssm基于Java的财务收支记账管理系统

《[含文档PPT源码等]精品jspssm基于Java的收支管理系统[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 使用技术&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&…

一周学会Django5 Python Web开发-Django5应用配置

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计14条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

日志监控须知

在这个领域,最流行的应该是ELK. ELK可以让收集日志,检索日志更加的简单,让定位日志问题更加的高效,在也不需要挨个登录服务器,然后用一堆Linux命令去搜索日志了. ELK ( Elasticsearch Logstash Kibana ) ELK架构: 各个微服务,通过某种机制把自己的日志交给Logstash 这里的某…

【教程】C++语言基础学习笔记(五)——Vector向量

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【C语言基础学习】系列文章 第一章 《项目与程序结构》 第二章 《数据类型》 第三章 《运算符》 第四章 《流程控制》 第五章…

ucosIII下创建任务读取DS18B20采集到的温度数据

学习链接&#xff1a;ucosIII下创建任务读取并输出DHT11采集到的温湿度数据 相关代码及事项&#xff1a; 首先&#xff0c;需要添加下面两个文件&#xff0c; 其次&#xff0c;main.c 中如下的代码&#xff1a; #include "led.h" #include "delay.h" #…

第10集《佛说四十二章经》

请大家打开讲议第十一面&#xff0c;第十九章、假真并观。 前面一章念等本空&#xff0c;说明大乘佛法的修学&#xff0c;身口意应安住在非空非有的中道实相。本章对中道实相的修学&#xff0c;再做明确的说明。修中道实相观要有空观与假观的观照&#xff0c;从空观中远离有相…

VueCLI核心知识综合案例TodoList

目录 1 拿到一个功能模块首先需要拆分组件&#xff1a; 2 使用组件实现静态页面的效果 3 分析数据保存在哪个组件 4 实现添加数据 5 实现复选框勾选 6 实现数据的删除 7 实现底部组件中数据的统计 8 实现勾选全部的小复选框来实现大复选框的勾选 9 实现勾选大复选框来…

​StableSwarmUI#超越文本的prompt

今天看到一个新的webui方案&#xff0c;是Stability-AI开源的&#xff1a; StableSwarmUI 是一个模块化的稳定扩散web用户界面&#xff0c;着重于使强大的工具易于访问、高性能和可扩展性。 由于项目还在开发中&#xff0c;我们可以先了解下&#xff0c;翻看了它的特点&#xf…

幻兽帕鲁游戏联机的时候,显示“网络连接超时”怎么解决?

如果你在游戏联机的时候&#xff0c;显示“网络连接超时”&#xff0c;可以检查下&#xff1a; 1、前提是你已经按照教程部署成功 2、检查防火墙有没有忘记设置&#xff0c;协议是UDP&#xff08;只有TCP不行&#xff0c;一定要有UDP&#xff09;&#xff0c;端口是否填了8211&…

K210开发环境搭建(VS Code)

一、新建一个文件夹&#xff0c;就叫K210 二、再K210文件夹里面再新建一个文件夹&#xff0c;就叫CMake 三、找到官方提供的资料包里的cmake安装包&#xff0c; 或者直接去cmake官方下载网址进行下载 CMake官方下载网址&#xff1a;https://cmake.org/download/ 四、双击安装…

每日一题 (不用加减乘除做加法,找到数组中消失的数字)

不用加减乘除做加法_牛客题霸_牛客网 (nowcoder.com) 可以使用位运算符实现两个整数的加法&#xff1a; 在二进制加法中&#xff0c;我们通常使用“逐位相加”的方法来模拟常规加法的过程。当两个数字进行加法运算时&#xff0c;从最低位&#xff08;通常是右侧&#xff09;开…

开源≠不赚钱,开源软件盈利的7大模式。

开源不是目的&#xff0c;目的是圈用户&#xff0c;留住用户&#xff0c;盈利自然不成问题。 开源系统可以通过多种方式赚钱&#xff0c;以下是其中几种常见的方式&#xff1a; 提供付费支持&#xff1a; 开源系统可以提供付费的技术支持服务&#xff0c;包括安装、配置、维…

PyTorch深度学习快速入门教程 - 【小土堆学习笔记】

小土堆Pytorch视频教程链接 声明&#xff1a; 博主本人技术力不高&#xff0c;这篇博客可能会因为个人水平问题出现一些错误&#xff0c;但作为小白&#xff0c;还是希望能写下一些碰到的坑&#xff0c;尽力帮到其他小白 1 环境配置 1.1 pycharm pycharm建议使用2020的&…

ArcgisForJS基础

文章目录 0.引言1.第一个ArcgisForJS应用程序1.1.安装部署ArcgisForJS1.2.实现ArcgisForJS应用程序 2.开发与调试工具2.1.集成开发环境2.2.调试工具2.3.Firebug 0.引言 ArcGIS API for JavaScript是一款由Esri公司开发的用于创建WebGIS应用的JavaScript库。它允许开发者通过调…

【王道数据结构】【chapter5树与二叉树】【P158t9】

假设二叉树采用二叉链存储结构存储&#xff0c;设计一个算法&#xff0c;求先序遍历序列中第k个结点的值 #include <iostream> #include <stack> typedef struct treenode{char data;struct treenode *left;struct treenode *right; }treenode,*ptreenode;ptreenod…

支付交易——清结算

摘要 老王有个账本&#xff0c;店里进了哪些货、进的谁家货、花了多少钱&#xff0c;老王都会—一记下来;卖了哪些货、卖给了谁、卖了多少钱&#xff0c;也都会记下来。为什么要有个账本&#xff0c;看看老王是怎么进货和卖货的就知道了。老王店里虽然商品种类很多&#xff0c…

【数据结构】图

文章目录 图1.图的两种存储结构2.图的两种遍历方式3.最小生成树的两种算法&#xff08;无向连通图一定有最小生成树&#xff09;4.单源最短路径的两种算法5.多源最短路径 图 1.图的两种存储结构 1. 图这种数据结构相信大家都不陌生&#xff0c;实际上图就是另一种多叉树&…

刘谦竟然不是第一个吃螃蟹的!——历年春晚数学魔术精选

早点关注我&#xff0c;精彩不错过&#xff01; 在今年2024的央视春晚&#xff0c;刘谦用一个手法数学魔术的流程&#xff0c;配合上小尼的完美衬托&#xff0c;时隔5年&#xff0c;再一次为全国观众见证奇迹。 如此江湖地位的加持&#xff0c;使得他表演什么甚至失误都已经不再…