基于Verilog的7段数码管动态扫描驱动模块设计

news/2025/4/2 12:22:16/文章来源:https://www.cnblogs.com/zclv/p/18799150

1、7段数码管动态扫描驱动模块概述

功能:通过动态扫描方式驱动6位共阳极7段数码管

特性:

(1)支持6位数码管显示(24位输入数据,每4位代表一个数字)

(2)采用动态扫描技术,降低功耗

(3)支持十六进制显示(0-F)

(4)带异步复位功能

2、7段数码管模块硬件原理图+6位一体共阳极数码管

3、7段数码管动态扫描驱动模块的Verilog描述

  1 module disp7led_dyna(
  2 
  3     input        wire                 clk,        // 系统时钟输入(50MHz)
  4     input     wire                 rst_n,    // 异步复位信号,低电平有效
  5     input        wire     [23:0]    data_in,    // 24位显示数据输入,[23:20]为第1位,[3:0]为第6位
  6     output     reg    [5:0]        sel6,        // 6位数码管位选信号(低电平有效,sel6[0]对应第1位)
  7     output     reg    [7:0]        seg7        // 7段+小数点输出(低电平有效,seg7[7]为小数点)
  8 );    
  9 
 10     parameter DELAY_1MS = 16'd50_000;    // 1ms延时计数值,数码管扫描时间
 11     
 12     // 内部寄存器定义
 13     reg [15:0]     count;        // 1ms定时计数器(16位宽度可支持最大65535个周期)
 14     reg [2:0]     cnt;            // 当前显示位计数器(0-5对应6位数码管)
 15     reg [3:0]      show_data;    // 当前要显示的数字(4位二进制,可表示0-15)
 16     
 17     
 18      //------------------------------------------------------------------
 19     // 1ms定时器生成逻辑
 20     // 功能:产生精确的1ms时间间隔,用于数码管动态扫描
 21     // 工作原理:在50MHz时钟下,每计数50,000次产生一个1ms标志
 22     //------------------------------------------------------------------    
 23     always@(posedge clk or negedge rst_n)begin
 24         if(rst_n == 1'b0)
 25             count <= 16'b0;            // 异步复位,计数器清零
 26         else if(count < DELAY_1MS - 1'b1)
 27             count <= count + 1'b1;    // 计数器递增
 28         else
 29             count <= 16'b0;             // 达到1ms时计数器归零
 30     end
 31     
 32      //------------------------------------------------------------------
 33     // 数码管位选择计数器
 34     // 功能:循环计数0-5,对应6位数码管
 35     // 扫描频率:每1ms切换一位,6ms完成一个完整扫描周期(约167Hz刷新率)
 36     //------------------------------------------------------------------
 37     always@(posedge clk or negedge rst_n)begin
 38         if(rst_n == 1'b0)
 39             cnt <= 3'd0;        // 复位时指向第1位数码管
 40         else if(count == DELAY_1MS - 1'b1)begin    // 每1ms更新一次
 41             if(cnt < 3'd6)
 42                 cnt <= cnt + 1'b1;    // 循环计数0→1→2→3→4→5
 43             else
 44                 cnt <= 3'd0;    // 计数到5后归零
 45         end
 46         else
 47             cnt <= cnt;            // 保持当前计数值
 48     end
 49     
 50      //------------------------------------------------------------------
 51     // 数据选择器(多路复用器)
 52     // 功能:根据当前位选择对应4位数据输出
 53     // 注意:这是组合逻辑电路,无时钟延迟
 54     //------------------------------------------------------------------
 55     always@(*)begin
 56         case(cnt)
 57             3'd0: show_data = data_in[23:20];    // 选择第1位数据(最高4位)
 58             3'd1: show_data = data_in[19:16];    // 选择第2位数据
 59             3'd2: show_data = data_in[15:12];    // 选择第3位数据
 60             3'd3: show_data = data_in[11:8];        // 选择第4位数据
 61             3'd4: show_data = data_in[7:4];        // 选择第5位数据
 62             3'd5: show_data = data_in[3:0];        // 选择第6位数据(最低4位)
 63         default: show_data = 4'b0000;                // 默认情况(理论上不会发生)
 64         endcase
 65     end
 66     
 67      //------------------------------------------------------------------
 68     // 7段译码器(带小数点)
 69     // 功能:将4位二进制数转换为7段数码管控制信号
 70     // 编码规则(共阳极数码管,低电平有效):
 71     //   seg7[7] = dp (小数点)
 72     //   seg7[6:0] = g f e d c b a (从高位到低位)
 73     // 注意:此实现未使用小数点(默认熄灭)
 74     //------------------------------------------------------------------
 75     always@(posedge clk or negedge rst_n)begin
 76         if(rst_n == 1'b0)
 77             seg7 <= 8'b1111_1111;    // 复位时关闭所有段
 78         else
 79             case(show_data)
 80                 4'd0:    seg7 = 8'b1100_0000;    // 显示"0"
 81                 4'd1:    seg7 = 8'b1111_1001;    // 显示"1"    
 82                 4'd2:    seg7 = 8'b1010_0100;    // 显示"2"
 83                 4'd3:    seg7 = 8'b1011_0000;    // 显示"3"
 84                 4'd4:    seg7 = 8'b1001_1001;    // 显示"4"
 85                 4'd5:    seg7 = 8'b1001_0010;    // 显示"5"
 86                 4'd6:    seg7 = 8'b1000_0010;    // 显示"6"
 87                 4'd7:    seg7 = 8'b1111_1000;    // 显示"7"
 88                 4'd8:    seg7 = 8'b1000_0000;    // 显示"8"
 89                 4'd9:    seg7 = 8'b1001_0000;    // 显示"9"
 90                 4'd10:seg7 = 8'b1000_1000;    // 显示"A"   
 91                 4'd11:seg7 = 8'b1000_0011;    // 显示"b"
 92                 4'd12:seg7 = 8'b1100_0110;    // 显示"C"
 93                 4'd13:seg7 = 8'b1010_0001;    // 显示"d"
 94                 4'd14:seg7 = 8'b1000_0110;    // 显示"E"
 95                 4'd15:seg7 = 8'b1000_1110;    // 显示"F"
 96             default:    seg7 <= 8'b1111_1111;    // 默认关闭所有段
 97             endcase
 98     end
 99     
100      //------------------------------------------------------------------
101     // 位选信号生成器
102     // 功能:根据当前位计数器生成对应的位选信号
103     // 特性:
104     //   - 低电平有效(0表示选中对应位数码管)
105     //   - 每次只选中一位,实现动态扫描
106     //------------------------------------------------------------------
107     always@(posedge clk or negedge rst_n)begin
108         if(rst_n == 1'b0)
109             sel6 <= 6'b11_1111;        // 复位时关闭所有位数码管
110         case(cnt)
111             3'd0: sel6 <= 6'b11_1110;    // 选中第1位数码管(sel6[0]=0)
112             3'd1: sel6 <= 6'b11_1101;    // 选中第2位数码管(sel6[1]=0)
113             3'd2: sel6 <= 6'b11_1011;    // 选中第3位数码管(sel6[2]=0)
114             3'd3: sel6 <= 6'b11_0111;    // 选中第4位数码管(sel6[3]=0)
115             3'd4: sel6 <= 6'b10_1111;    // 选中第5位数码管(sel6[4]=0)
116             3'd5: sel6 <= 6'b01_1111;    // 选中第6位数码管(sel6[5]=0)
117         default: sel6 <= 6'b11_1111;     // 默认关闭所有位数码管
118         endcase
119     end
120     
121 endmodule 

4、7段数码管动态扫描驱动模块的测试平台

功能:对disp7led_dyna模块进行仿真测试

测试内容:复位功能测试、动态扫描时序测试、数据显示正确性测试

 1 `timescale 1ns/1ns    // 仿真时间单位1ns,精度1ns
 2 
 3 module disp7led_dyna_tb();
 4     
 5     // 测试信号定义
 6     reg                 clk;        // 模拟系统时钟信号(50MHz,周期20ns)
 7     reg                rst_n;    // 模拟异步复位信号,低电平有效
 8     reg     [23:0]    data_in;    // 模拟24位显示数据输入,[23:20]为第1位,[3:0]为第6位
 9     
10     wire    [5:0]        sel6;        // 监测位选信号输出(低电平有效,sel6[0]对应第1位)
11     wire    [7:0]        seg7;        // 监测段选信号输出(低电平有效,seg7[7]为小数点)
12     
13      // 实例化被测模块
14     disp7led_dyna uut(            
15         .clk            (clk),         // 连接测试时钟
16         .rst_n        (rst_n),         // 连接测试复位信号
17         .data_in        (data_in),     // 连接测试数据输入
18         .sel6            (sel6),         // 连接位选信号输出
19         .seg7            (seg7)         // 连接段选信号输出
20     );
21     
22     // 修改被测模块参数(缩短仿真时间)
23    // 将原1ms扫描间隔缩短为50个时钟周期(1us)
24     defparam uut.DELAY_1MS = 50;
25     
26     // 时钟信号生成(50MHz)
27     initial clk = 1'b0;        // 初始时钟置0
28     always #10 clk = ~clk;    // 每10ns翻转一次(周期20ns)
29     
30     // 测试激励生成
31     initial begin
32         rst_n = 1'b0;                 // 复位信号有效(低电平)
33         data_in = 24'h123456;    // 测试数据:6位数码管显示1-2-3-4-5-6
34         #203;                            // 等待203ns(超过10个时钟周期)
35         rst_n = 1'b1;                // 释放复位(开始正常工作)
36         
37         // 观察完整扫描周期
38       // 等待2个完整扫描周期(6位数×50周期×2次)
39         #(20*50*6*2);
40         $stop;        // 停止仿真(在Modelsim等工具中暂停)
41     end
42 
43 endmodule 
View Code

提示:当数码管的段选段(seg7)和位选段(sel)不同步时,就会导致选中的管子和想要显示的数字不是完全同步的,由于不同步的时间相对比较少,所以显示出错误的数字的时间较短,点亮的程度就会比较小,称为“鬼影”。

5、7段数码管动态扫描驱动顶层模块+开发板测试

  • 主要用于测试和展示disp7led_dyna模块的功能

  • 实际使用时,可将data_in替换为需要显示的真实数据

 1 // 7段数码管动态扫描驱动顶层模块
 2 // 功能:实例化动态扫描驱动模块并提供测试数据
 3 // 特性:
 4 //   1. 连接系统时钟和复位信号
 5 //   2. 提供固定的24位测试数据(0x123456)
 6 //   3. 输出数码管位选和段选信号
 7 module disp7led_dyna_top(
 8     input        wire                 clk,        // 系统时钟输入(50MHz)
 9     input     wire                 rst_n,    // 异步复位信号,低电平有效
10     output     wire    [5:0]        sel6,        // 6位数码管位选信号输出,低电平有效,sel6[0]对应最左边的数码管
11     output     wire    [7:0]        seg7        // 7段数码管段选信号输出(包含小数点)
12 );
13 
14     // 内部信号定义
15     wire     [23:0]    data_in;    // 24位显示数据线
16     
17     assign data_in = 24'h123456;      // 将24'h123456固定赋值给data_in
18     
19      // 动态扫描驱动模块实例化
20     // 将顶层模块的端口与驱动模块连接
21     disp7led_dyna uut(            
22         .clk            (clk),        // 连接系统时钟
23         .rst_n        (rst_n),        // 连接复位信号
24         .data_in        (data_in),    // 连接显示数据
25         .sel6            (sel6),         // 连接位选信号输出
26         .seg7            (seg7)        // 连接段选信号输出
27     );
28 
29 endmodule

 

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

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

相关文章

leetcode每日一题:图中的最长环

题目 2360. 图中的最长环 给你一个 n 个节点的 有向图 ,节点编号为 0 到 n - 1 ,其中每个节点 至多 有一条出边。 图用一个大小为 n 下标从 0 开始的数组 edges 表示,节点 i 到节点 edges[i] 之间有一条有向边。如果节点 i 没有出边,那么 edges[i] == -1 。 请你返回图中的…

三菱PLC数据 转 EthernetIP项目案例

VFBOX协议转换网关支持PLC,modbus,EthernetIP,Profinet,CCLink,EtherCAT,IEC61850,IEC104,bacnet,DLT645,HJ212,opc ua,opc da,DNP3。目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 网关采集三菱PLC数据 2 5 使用ETHERNETIP转发数据 5 6 其他说明 7 7 …

比较LLM的function calling,Agent 和MCP

比较对比维度 ​MCP(Model Context Protocol)​ ​Function Calling ​Agent(智能体)​​定义 由 Anthropic 推出的开放协议,标准化 LLM 与外部数据源、工具的通信接口。 LLM 调用外部函数的机制,通过 JSON 参数规范模型与外部系统的交互。 自主运行的智能系统,通过分析…

20C++数组(1)——教学

1、什么是数组; 2、数组越界; 3、循环移位; 4、冒泡排序一、什么是数组 教学参考视频尼克、格莱尔等5位同学进行了一次信息学测试,试编一程序,实现查分功能。先输入成绩,然后输入学号输出相应的成绩。按以前方法:可以用al~a5分别保存1~5号同学的成绩,然后进行判断,若输入…

102201542曾庆徽-综测成绩证明材料

2023-2024年度下学期2024-2025年度上学期

web136笔记(tee妙用)

<?php error_reporting(0); function check($x){if(preg_match(/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i, $x)){die(too young too simple sometimes naiv…

「收藏级」指针的前世今生:写给所有被C/C++折磨过的人

大家好,我是小康。今天聊聊让编程新手头疼的"指针"——这个 C 语言第一难点究竟是什么,为什么会被发明出来? 从直接操作内存到编程语言的"导航员" 你有没有过这样的经历:学习编程时,一切都还算顺利,直到遇见了"指针"这个概念,突然感觉像遇…

VLM-3D空间理解

VLM-3D空间理解 CoT Thinking in spaceNotably, prevailing linguistic reasoning techniques (e.g., chain-of-thought, self-consistency, tree-of-thoughts) fail to improve performance, whereas explicitly generating cognitive maps during question-answering enhance…

PCR406-ASEMI智能家居专用PCR406

PCR406-ASEMI智能家居专用PCR406编辑:LL PCR406-ASEMI智能家居专用PCR406 型号:PCR406 品牌:ASEMI 封装:TO-92 阻断电压:600V 通态电流:0.6A 类型:单向可控硅 浪涌电流:10A 工作温度:-40℃~150℃ 灵敏触发与低功耗‌ 触发电流低至‌5~200μA‌(分段可选),门极触发电…

SvelteKit 最新中文文档教程(14)—— 错误处理

前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

银行网点加钞间作业人数异常报警系统

银行网点加钞间作业人数异常报警系统检测银行网点加钞间区域内作业人数,对超过设定人数阈值,进行预警。加钞间少于2人进行报警,规范员工操作,落实银行制度。自助环境区域、防护舱内区域重点关注大于等于2人,预防案件发生。通过人脸识别比对系统,对加钞间非授权人员进行检…

RAGFlow部署

参照https://eogee.com/article/detail/17进行 其中主要就是放开ragflow/docker/.env文件中的RAGFLOW_IMAGE华为云镜像地址 修改ragflow/docker/docker-compose.yml文件中的端口 Q:访问网页注册登录无反应 打开控制台看是报了502的错误 A:确保mysql,redis,minio,es等先启动,然…