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

news2024/11/26 18:39:34

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 针对数码管的管脚约束文件

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高德地图上绘制热力图的方法

百度地图和高德地图的JavaScript API都提供了热力图的绘制方法&#xff0c;都是将热力图作为新的图层&#xff0c;叠加到地图上。但是百度地图的经纬度体系与我们的经纬度存在偏差&#xff0c;高德的与我们相符&#xff0c;应当使用高德地图JavaScript API。 因为是JavaScript…

一个人被锁死在公司底层的根本原因

一、现代社会对员工角色的认知 随着经济全球化和科技进步,现代社会对员工的认知发生了深刻的变化。传统上,员工被视为公司的执行者和生产者,承担着重复性、机械性的工作。然而,随着知识经济和服务型经济的兴起,员工角色逐渐从“执行者”转变为“创造者”和“合作者”。员…

python-分享篇-五子棋

文章目录 代码效果 代码 """五子棋之人机对战"""import sys import random import pygame from pygame.locals import * import pygame.gfxdraw from checkerboard import Checkerboard, BLACK_CHESSMAN, WHITE_CHESSMAN, offset, PointSIZE 3…

CSRNET图像修复,DNN

CSRNET图像修复 CSRNET图像修复&#xff0c;只需要OPENCV的DNN

Momentum2

攻击机 192.168.223.128 目标机 192.168.223.147 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -A -p- 192.168.223.147 开启了22 80 端口 看一下web界面 源码&#xff0c;robots.txt ,url都观察了一下好像没什么有用信息 扫一下目录 gobuster dir -u http:…

H5 树叶飘动二次元引导页源码

H5 树叶飘动二次元引导页源码 源码介绍&#xff1a;一款H5 树叶飘动二次元引导页源码&#xff0c;带有很多可选跳转按钮。 下载地址&#xff1a; https://www.changyouzuhao.cn/10386.html

【C语言】指针的入门篇2,深入理解指针和数组的关系

欢迎来CILMY23的博客喔&#xff0c;本期系列为【C语言】指针的入门篇2&#xff0c;深入理解指针和数组的关系&#xff0c;图文讲解指针和数组关系的知识&#xff0c;带大家理解指针和数组的关系&#xff0c;以及指针数组的用法&#xff0c;感谢观看&#xff0c;支持的可以给个赞…

投资理财的正确方式,实现个人的财富积累

一、教程描述 本套理财教程&#xff0c;大小18.98G&#xff0c;共有16个文件。 二、教程目录 第01课&#xff1a;记账为什么能帮月薪3000的你&#xff0c;省20%&#xff1f;.mp4 第02课&#xff1a;玩转信用卡&#xff0c;银行帮你越刷越有钱.mp4 第03课&#xff1a;巧用公…

代码+视频基于R语言进行K折交叉验证

我们在建立数据模型后通常希望在外部数据验证模型的检验能力。然而当没有外部数据可以验证的时候&#xff0c;交叉验证也不失为一种方法。交叉验验证&#xff08;交叉验证&#xff0c;&#xff23;&#xff36;&#xff09;则是一种评估模型泛化能力的方法&#xff0c;广泛应用…

30、二维数组/字符串操作相关练习20240214

一、编程实现二维数组的杨辉三角。 代码&#xff1a; #include<stdlib.h> #include<string.h> #include<stdio.h>int main(int argc, const char *argv[]) {int n;printf("please enter n:");scanf("%d",&n);int arr[n][n];for(in…

Django学习全纪录:Django开发环境的搭建

导言 对于Django&#xff0c;它是Python的一个开发框架&#xff0c;之前系统地学习过。遗憾的是&#xff0c;对于一些遇到的问题&#xff0c;没有及时地记录下来。因此&#xff0c;我将它重新捡起&#xff0c;进行学习和实践。从搭建环境开始&#xff0c;重新去学习它&#xff…

【从Python基础到深度学习】4. Linux常用命令(进阶)

接上篇 【从Python基础到深度学习】4. Linux 常用命令-CSDN博客 1.文件查找 - find 命令 find [搜索路径] [搜索条件] [操作]1.1 常用选项和参数 -name&#xff1a;按文件名搜索。 find 命令的 -name 选项可以接受通配符来匹配文件名。通配符可以帮助你更灵活地搜索文件名&a…

第13章 网络 Page724 asio定时器

程序代码&#xff1a; 11行&#xff0c;声明一个ios对象 13行&#xff0c;使用ios对象作为参数声明一个定时器&#xff0c;此时&#xff0c;定时器和ios完成了关联&#xff0c;后面定时器如果有任务的话&#xff0c;就可以将任务交给ios 16行&#xff0c;为定时器设置一个定…

MySQL数据库基础(一):数据库概述

文章目录 数据库概述 一、数据库介绍 二、数据库分类 1、关系型数据库 2、非关系型数据库NoSQL 三、常见数据库介绍 1、关系型数据库 2、非关系型数据库 数据库概述 一、数据库介绍 数据库就是存储数据的仓库&#xff0c;其本质是一个文件系统&#xff0c;按照特定的…

【Pygame手册01/20】最简应用:窗口

目录 一、说明 二、pygame是什么&#xff1f; 2.1 为游戏开发设计 2.2 版本发展史 2.3 特点 三、pygame安装要点 四、入门知识 4.1 初始使用 4.2 要更改 pygame 窗口的外观 4.3 完整窗口程序 4.4 窗口对象接口示例 五、隐形窗口和显性窗口 六、结论 一、说明 为什…

EasyRecovery专业版2024最新版本数据恢复软件

EasyRecovery专业版2024是一款功能强大的数据恢复软件&#xff0c;专为满足专业用户的需求而设计。它支持恢复各种类型的数据&#xff0c;包括文档、图片、视频、音频等&#xff0c;且可以恢复的数据存储介质也非常多样化&#xff0c;如硬盘、U盘、移动硬盘、数码相机、手机等。…

如何流畅进入Github

前言 以下软件是免费的&#xff0c;放心用 一、进入右边的下载链接https://steampp.net/ 二、点击下载 三、点击接受并下载 四、随便选一个下载链接进行下载 五、软件安装好打开后&#xff0c;找到Github 六、点击全部启用 七、再点击左上角的一键加速 八、这个时候你再进Git…

java的面向对象编程(oop)——认识泛型

前言&#xff1a; 打好基础&#xff0c;daydayup! 泛型 1&#xff0c;认识泛型&#xff1a; 定义类&#xff0c;接口&#xff0c;方法时&#xff0c;同时声明了一个或多个类型变量&#xff08;例&#xff1a;<E>&#xff09;,称为泛型&#xff0c;泛型接口&#xff0c;泛…

error MSB8008: 指定的平台工具集(v143)未安装或无效。请确保选择受支持的 PlatformToolset 值解决办法

右击解决方案&#xff0c;选择属性 将工具集为143的修改为其他&#xff0c;如图 重新编译即可运行

应用进程跨越网络的通信

目录 1 系统调用和应用编程接口 应用编程接口 API 几种应用编程接口 API 套接字的作用 几种常用的系统调用 1. 连接建立阶段 2. 传送阶段 3. 连接释放阶段 1 系统调用和应用编程接口 大多数操作系统使用系统调用 (system call ) 的机制在应用程序和操作系统之间传递控制…