数码管的动态扫描与驱动

数码管的基本原理

    关于数码管,一个单个的数码管可以看做是多个led灯的集合,如下图所示

其中的8和。都是LED组成的,通过引脚上电即可点亮不同的LED然后组成不同的数字,这个过程在数码管的设计中叫做段选。

    在多个数码管的情况下,需要选择哪个数码管点亮,这个在数码管设计中称作位选,多个数码管可以通过位选和段选完成电子时钟设计等功能。

下面通过项目对于多个数码管进行点亮,让其在开发板上显示不同的数据。

预计实验现象:

      在quartus的in system source and probes editor 工具,输入需要显示在数码管上的数据,则数码管显示对应数据。

相关知识点:

    数码管动态扫描的实现、in system source and probes editor调试工具的使用。

设计过程:

    1、数码管动态扫描实现。

    2、In system sources and probes edit (ISSP)调试工具的使用

    3、4输入查找表,6位输出。

    4、分频模块,从系统时钟分频得到1KHz的扫描时钟

    5、6选一多路选择器,选择为当前数码管的位置。

驱动模块逻辑电路图:

下面就是照着逻辑电路图来编写程序了。

创建工程,添加文件

      

module segment(disp_data,rst_n,clk,en ,sel,seg);

input clk;//50M
input rst_n;
input en;
input [23:0]disp_data;
output [5:0]sel;//位选(控制哪个数码管亮)
output reg [6:0]seg;//段选(控制数码管显示什么数据)

//分频器的代码,这里为了完整,不做多个文件来写模块了
reg[14:0] diviter_cnt; //25000-1
reg clk_1k;
reg [5:0]sel_r;
reg [3:0]data_temp;//待显示数据缓存

//生成一个分频计数器计数
[email protected](posedge clk or negedge rst_n)
if (!rst_n)
diviter_cnt<=15‘d0;
else if (!en)
diviter_cnt<=15‘d0;
else if (diviter_cnt==24999)
diviter_cnt<=15‘d0;
else
diviter_cnt<=diviter_cnt+1‘b1;

//1k扫描时钟生成
[email protected](posedge clk or negedge rst_n)
if (!rst_n)
clk_1k<=1‘b0;
else if (diviter_cnt==24999)
clk_1k<=~clk_1k; //大型设计中,这种产生分频器的方法是不可以的

//位选移位寄存器
[email protected](posedge clk_1k or negedge rst_n)
if (!rst_n)
sel_r<=6‘b000_001;
else if(sel_r==6‘b100_000)
sel_r<=6‘b000_001;
else
sel_r<=sel_r<<1;

//设计一个6选一多路器
[email protected](*)
case(sel_r)
6‘b000_001:data_temp=disp_data[3:0];
6‘b000_010:data_temp = disp_data[7:4];
6‘b000_100:data_temp=disp_data[11:8];
6‘b001_000:data_temp=disp_data[15:12];
6‘b010_000:data_temp=disp_data[19:16];
6‘b100_000:data_temp=disp_data[23:20];
default
data_temp<=4‘b0000;
endcase

//译码器
[email protected](*)
case (data_temp)
4‘h0:seg=7‘b1000000;//这里按数码管码表来
4‘h1:seg=7‘b1111001;
4‘h2:seg=7‘b0100100;
4‘h3:seg=7‘b0110000;
4‘h4:seg=7‘b0011001;
4‘h5:seg=7‘b0010010;
4‘h6:seg=7‘b0000010;
4‘h7:seg=7‘b1111000;
4‘h8:seg=7‘b0000000;
4‘h9:seg=7‘b0010000;
4‘ha:seg=7‘b0001000;
4‘hb:seg=7‘b0000011;
4‘hc:seg=7‘b1000110;
4‘hd:seg=7‘b0100001;
4‘he:seg=7‘b0000110;
4‘hf:seg=7‘b0001110;
endcase

//二选一多路器
assign sel=(en)?sel_r:6‘b000_000;

endmodule

编写testbench文件来进行仿真

`timescale 1ns/1ns

`define clk_period 20

module HXE_tb;

reg Clk; //50M
reg Rst_n;
reg En; //数码管显示使能,1使能,0关闭

reg [31:0]disp_data;

wire [7:0] sel;//数码管位选(选择当前要显示的数码管)
wire [6:0] seg;//数码管段选(当前要显示的内容)

HXE8 HXE8(
.Clk(Clk),
.Rst_n(Rst_n),
.En(En),
.disp_data(disp_data),
.sel(sel),
.seg(seg)
);

initial Clk = 1;
always#(`clk_period/2) Clk = ~Clk;

initial begin
Rst_n = 1‘b0;
En = 1;
disp_data = 32‘h12345678;
#(`clk_period*20);
Rst_n = 1;
#(`clk_period*20);
#20000000;
disp_data = 32‘h87654321;
#20000000;
disp_data = 32‘h89abcdef;
#20000000;
$stop;
end

endmodule

点击仿真运行,可以看到sel和seg的输出与我们期望的是一样的,即位选进行移位操作,段选显示123456和abcdef。

一般都需要进行后仿,才能得到实际的工作时的数据波形,这里由于使用的是Cyclone V系列的芯片,而quartus 取消了对该系列的门级仿真,故而此次设计的后仿就不做了。但是我们这里发现,友晶的开发板的连接模式与下面这种常规的位选段选接法不同,其连接方式为并行接法,每个数码管连接一个IO管脚,通过IO管脚的设置来决定数据的显示,这里两者的区别是位选的有无

重新编写segment程序

module segment_2(disp_data,rst_n,clk,en ,data_out);
input clk;//50M
input rst_n;
input en;
input [23:0]disp_data;

output reg [41:0]data_out;
reg[24:0]cnt;//定义计数寄存器
reg [3:0]data_temp;//待显示数据缓存
reg [6:0]seg;//段选(控制数码管显示什么数据)
reg num;
[email protected](posedge clk or negedge rst_n)
//设置500ms的延时
if(rst_n==1‘b0)
cnt<=25‘d0;
else if (cnt==25‘d24_999_999)//(500_000_000/20) -1的结果。
cnt<=25‘d0;
else
cnt<=cnt+1‘b1;

[email protected](posedge clk or negedge rst_n)
if (rst_n==1‘b0)
data_temp=4‘b0001;
else if (cnt==25‘d24_999_999)
case (num)
1‘h0: begin data_temp<=disp_data[3:0];num<=num+1; end
1‘h1:begin data_temp<=disp_data[7:4] ; num<=num+1;end
1‘h2:begin data_temp<=disp_data[11:8] ;num<=num+1;end
1‘h3:begin data_temp<=disp_data[15:12] ; num<=num+1;end
1‘h4:begin data_temp<=disp_data[19:16] ; num<=num+1;end
1‘h5:begin data_temp<=disp_data[23:20] ; num<=num+1;end
default
num<=0;
endcase
[email protected](*)
begin
case (data_temp)
4‘h0:seg=7‘b1000000;//这里按数码管码表来
4‘h1:seg=7‘b1111001;
4‘h2:seg=7‘b0100100;
4‘h3:seg=7‘b0110000;
4‘h4:seg=7‘b0011001;
4‘h5:seg=7‘b0010010;
4‘h6:seg=7‘b0000010;
4‘h7:seg=7‘b1111000;
4‘h8:seg=7‘b0000000;
4‘h9:seg=7‘b0010000;
4‘ha:seg=7‘b0001000;
4‘hb:seg=7‘b0000011;
4‘hc:seg=7‘b1000110;
4‘hd:seg=7‘b0100001;
4‘he:seg=7‘b0000110;
4‘hf:seg=7‘b0001110;
endcase
data_out<=({seg,seg,seg,seg,seg,seg,seg});
end

endmodule

编写testbench文件并设定路径

`timescale 1ns/1ns
`define clk_period 20
module segment_2_tb;

reg clk;//50M
reg rst_n;
reg en;
reg [23:0]disp_data;
wire [41:0]data_out;//段选(控制数码管显示什么数据)

segment_2 segment0(.disp_data(disp_data),
.rst_n(rst_n),
.clk(clk),
.en (en),
.data_out(data_out)
);

initial clk = 1;
always#(`clk_period/2) clk = ~clk;
initial begin
rst_n=1‘b0;
en=1;
disp_data=24‘h123456;
#(`clk_period*20)
rst_n=1;
#(`clk_period*20)
#20_000_000;
disp_data<=24‘habcdef;
#20_000_000;
$stop;
end
endmodule

仿真波形如图

到了这一步就需要一个工具,即之前说到的In sysytem sources and probes editor (ISSP)

打开一个IP核

之后一直next知道finish,ctrl+o将产生的文件添加到工程中。将端口添加到顶层文件中

新建一个segment_top文件,将文件端口都链接进来

module segment_top(clk,rst_n,data_out);

input clk;//50M
input rst_n;
wire [23:0]disp_data;

output [41:0]data_out;

segment_data segment_data0(
.probe(),
.source(disp_data));

segment_2 segment0(.disp_data(disp_data),
.rst_n(rst_n),
.clk(clk),
.en (1‘b1),
.data_out(data_out));

endmodule

至此,工程修改完了,之后就是分配引脚

将.sof文件下载到开发板中

下载之后,开发板上的数码管一直显示00_00_00,这是因为没有给它需要显示的值。

现在在电脑上调用in system programer 工具

将数据格式改为16进制

在Data框中输入希望显示的数据,会发现数码管上的数据会随着输入的数据的变化而变化。

到这里,数码管的点亮的试验的基本目标就已经完成了,但是本次实验还有很多不足,比如让不同数码管显示不同数据,复位按钮按下后,显示不是从头开始跳变的,只是按下的时候会改变显示显示8而已,这点也是一个很大的不足,如果需要做一个电子时钟的话,程序还需要很多的修改,在下一篇文章中,我会将这些问题一一解决,并将程序及设计步骤发到博客上来。

时间: 2024-08-04 18:54:41

数码管的动态扫描与驱动的相关文章

重拾单片机 第二天 数码管的使用 (动态扫描数码管)

我们要实现的功能是什么呢? 从 第一个数码管扫描 1 到第二个数码管 2 ,第三个数码管 3,.......一直到 第8个数码管 显示8 1 /*--------------www.szjcdz.cn-------------------- 2 名称:数码管动态扫描 3 编写:shenhui 4 日期:2015.10.28 5 内容:数码管动态扫描 6 ------------------------------------------------*/ 7 #include<reg52.h>

惠普(HP) LaserJet Pro M1136 MFP 黑白多功能激光一体机 (打印 复印 扫描)驱动安装记录

惠普(HP) LaserJet Pro M1136 MFP 黑白多功能激光一体机 (打印 复印 扫描) 新入手的打印机,如果没有安装经验,不要急着开箱组装! 先打开电脑,放入驱动光盘,运行安装向导,会有动画安装指南,一步一步的教你如何操作. 考虑买这款打印机的可以去产品官方商品页面看看. 如果没有驱动光盘,可以去官方产品支持页面下载. 下面是我的安装过程: 从官网上下载的驱动程序,由于下图中没有完全对应打印机正面显示的LaserJet M1136 MFP型号的驱动,纠结了半天到底应该安装哪一个型

module_param 用于动态开启/关闭 驱动打印信息

1.定义模块参数的方法: module_param(name, type, perm); 其中,name:表示参数的名字;      type:表示参数的类型;      perm:表示参数的访问权限; type参数设定的类型和perm的访问权限具体数值数值请参考内核定义. 2.可以在insmod(装载模块)的时候为参数指定值,如果没有指定则使用默认值 static int num=10; module_param(num,int,S_IRUGO); static int hello_init(

高速扫描振镜驱动设计-模拟伺服驱动器Galvanometer

振镜是一种优良的矢量扫描器件.它是一种特殊的摆动电机 . 基本原理是通电线圈在磁场中产生力矩 ,但与旋转电机不同 ,其转子上通过机械纽簧或电子的方法加有复位力矩 ,大小与转子偏离平衡位置的角度成正比 ,当线圈通以一定的电流而转子发生偏转到一定的角度时 ,电磁力矩与回复力矩大小相等 ,故不能象普通电机一样旋转 ,只能偏转 ,偏转角与电流成正比 ,与电流计一样 ,故振镜又叫电流计扫描振镜(galvanomet ric scanner) .扫描振镜其专业名词叫做高速扫描振镜Galvo scanning

FPGA开发随笔汇总

点击标题即可进入相关随笔: 1.FPGA的发展史及FPGA 的基础架构 2.用VerilogHDL设计一个与门逻辑,并进行前仿和后仿 3.点亮一个LED灯 4.3-8 译码器的设计 5.计数器设计与应用 6.利用IP核设计高性能的计数器 7.设计一个BCD码计数器. 8.用一个例子来学习阻塞赋值和非阻塞赋值 9.状态机的设计实例 10.数码管的动态扫描与驱动 11.按键消抖试验及一个数码管电子时钟的设计 12.uart通讯协议

AC620教程 第十五节 8位7段数码管驱动设计与验证

本章导读 电子系统中常用的显示设备有数码管.LCD液晶以及VGA显示器等.其中数码管又可分为段式显示(7段.米字型等)以及点阵显示(8*8.16*16等),LCD液晶的应用可以分为字符式液晶(1602.12864等)以及真彩液晶屏,VGA显示器一般是现在的电脑显示器.芯航线开发板对以上三种设备均提供了硬件接口. 本章将实现FPGA驱动数码管动态显示并提取出实现的电路结构,从电路结构入手编写代码,仿真对设计进行验证.最终板级调试时使用In system sources and probes edi

10-8位7段数码管驱动实验——小梅哥FPGA设计思想与验证方法视频教程配套文档

芯航线--普利斯队长精心奉献 ? 实验目的: 1.实现FPGA驱动数码管动态显示: 2.使用In system sources and probes editor工具,输入需要显示在数码管上的的数据,数码管显示对应数值. 实验平台:芯航线FPGA核心板.数码管_VGA_PS2模块 实验原理: ????电子设计系统中常用的显示设备有数码管.LCD液晶以及VGA显示器等.其中数码管又可分为段式显示(7段.米字型等)以及点阵显示(8*8.16*16等),LCD液晶的应用可以分为字符式液晶(1602.1

数码管的动态显示

实验板:TX-1C     ---   八段数码管采用共阴极连接 内容:显示123456 原理:动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效.选亮数码管采用动态扫描显示.所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示.动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的. #include <reg52.h> #include <intrins

AVR单片机教程——矩阵键盘

本文隶属于AVR单片机教程系列. ? 开发板上有4个按键,我们可以把每一个按键连接到一个单片机引脚上,来实现按键状态的检测.但是常见的键盘有104键,是每一个键分别连接到一个引脚上的吗?我没有考证过,但我们确实有节省引脚的方法. 矩阵键盘 这是一个4*4的矩阵键盘,共有16个按键只需要8个引脚就可以驱动.我们先来看看它的原理. 每个按键有两个引脚,当按键按下时接通.每一行的一个引脚接在一起,分别连接到左边4个端口,称为"行引脚":每一列的另一个引脚接在一起,分别连接到右边的4个端口,称