实验四数码管扫描显示控制器设计与实现
2011211208班 2011211055 4 于圣泽
一、 实验目的
1. 掌握VHDL语言的语法规范,掌握时序电路描述方法;
2. 掌握多个数码管动态扫描显示的原理及设计方法。
二、 实验原理
多个数码管动态扫描显示,是将所有数码管的相同段并联在一起,通过选通信号分时控制各个数码管的公共端,循环依次点亮多个数码管,利用人眼的视觉暂留现象,只要扫描的频率大于50Hz,将看不到闪烁现象。一个数码管要稳定显示要求显示频率大于50Hz,那么6个数码管则需要50×6=300Hz以上才能看到持续稳定点亮的现象。
cat1~cat6是数码管选通控制信号,分别对应于6个共阴极数码管的公共端,当catn=‘0’时,其对应的数码管被点亮。因此,通过控制cat1~cat6,就可以控制6个数码管循环依次点亮。
三、 实验内容
1. 用VHDL语言设计并实现六个数码管串行扫描电路,要求同时显示0、1、2、3、4、5这6个不同的数字图形到6个数码管上,仿真验证其功能,并下载到实验板测试。
2. 用VHDL语言设计并实现六个数码管滚动显示电路
(1) 循环左滚动,始终点亮6个数码管,左出右进。状态为:012345→123450→234501→3450123→450123→501234→012345
(2) 向左滚动,用全灭的数码管填充右边,直至全部变灭,然后再依次从右边一个一个地点亮。状态为:012345→12345X→2345XX→345XXX→45XXXX→5XXXXX→XXXXXX→XXXXX0→XXXX01→XXX012→XX0123→X01234→012345,其中‘X’表示数码管不显示。
四、 设计思路和过程
对50MHz时钟进行5000分频,得到10kHZ时钟scanclk。把scanclk作为6进制计数器的时钟,对计数器的状态进行译码,得到cat(5 downto 0)的选通脉冲。定义信号q(5 downto 0)作为各个二极管当前应该显示的输出数字,在cat(i)置0前将对应的q(i)通过decode()函数译码为a(6 downto 0)控制数码管a~g输出,实现数码管扫描。
对于实验内容2,对scanclk进行10000分频,得到1Hz时钟moveclk,把它作为控制数字变化的时钟,根据不同要求定时改变q(5 downto 0)的值,实现显示数字的变化。对于’X’不显示状态,通过定义decode(10)译码得“0000000”实现熄灭。
五、 VHDL程序
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity LED is
port(clk : in std_logic;
ctrl : in std_logic_vector(2 downto 0);
a : out std_logic_vector(6 downto 0);
cat : out std_logic_vector(5 downto 0));
end LED;
architecture behave of LED is
function decode(i:integer) return std_logic_vector is -- 七段译码函数
variable q : std_logic_vector(6 downto 0);
begin
case i is
when 0 => q := "1111110";
when 1 => q := "0110000";
when 2 => q := "1101101";
when 3 => q := "1111001";
when 4 => q := "0110011";
when 5 => q := "1011011";
when 6 => q := "1011111";
when 7 => q := "1110000";
when 8 => q := "1111111";
when 9 => q := "1111011";
when others => q := "0000000";
end case;
return q;
end decode;
signal scanclk: std_logic;
signal moveclk: std_logic;
type array_type1 is array (0 to 5) of integer range 0 to 10;
type array_type2 is array (0 to 11) of integer range 0 to 10;
signal q : array_type1 := (0,1,2,3,4,5);
begin
p1:process(clk) -- 分频比:5000
variable temp : integer range 0 to 4999;
begin
if (clk'event and clk = '1') then
if temp = 4999 then temp := 0;
else temp := temp+1;
end if;
if (temp = 4999) then scanclk <= '1';
else scanclk <= '0';
end if;
end if;
end process;
p2:process(scanclk) -- 产生选通脉冲和输出译码
variable temp : integer range 0 to 10;
begin
if (scanclk'event and scanclk = '1') then
if temp = 5 then temp := 0;
else temp := temp+1;
end if;
cat <= "111111";
cat(temp) <= '0';
a <= decode(q(temp));
end if;
end process;
p3:process(scanclk) --分频比:10000
variable temp : integer range 0 to 9999;
begin
if (scanclk'event and scanclk = '1') then
if temp = 9999 then temp := 0;
else temp := temp+1;
end if;
if (temp = 9999) then moveclk <= '1';
else moveclk <= '0';
end if;
end if;
end process;
p5:process(moveclk) -- 定时改变显示数字
variable temp : integer range 0 to 10;
variable q1 : array_type1 := (0,1,2,3,4,5);
variable q2 : array_type1 := (0,1,2,3,4,5);
variable q3 : array_type2 := (0,1,2,3,4,5,10,10,10,10,10,10);
begin
if (moveclk'event and moveclk ='1') then -- ctrl控制模式
if ctrl = "010" then
temp := q2(0);
for i in 0 to 4 loop
q2(i) := q2(i+1);
end loop;
q2(5) := temp;
elsif ctrl = "100" then
temp := q3(0);
for i in 0 to 10 loop
q3(i) := q3(i+1);
end loop;
q3(11) := temp;
end if;
if ctrl = "001" then
for i in 0 to 5 loop
q(i) <= q1(i);
end loop;
elsif ctrl = "010" then
for i in 0 to 5 loop
q(i) <= q2(i);
end loop;
elsif ctrl = "100" then
for i in 0 to 5 loop
q(i) <= q3(i);
end loop;
end if;
end if;
end process;
end;
六、 仿真波形图
ctrl=’001’
ctrl=’010’
ctrl=’100’
七、 仿真波形分析
为了便于仿真,将scanclk分频比改成2,将moveclk分频比改成12
ctrl=’001’时,cat(i)=’0’,时a对应i的七段译码值;
ctrl=’010’时,黄色框内显示输出012345,绿色框内显示输出123450;
ctrl=’100’时,黄色框内显示输出2345XX,绿色框内显示输出345XXX。
八、 故障及问题分析
刚开始很迷茫,根本不知道如何下手写代码,后来将要实现的功能分解成一个一个小模块,通过不同的process得以完成了实验内容。在过程中还遇到了需要实时调用的decode,通过查书我学会了函数的编写规范,最终用函数实现了七段译码。总体来说有了之前三次VHDL的编程经验,完成这次实验并不困难,遇到的几个小问题也通过调试解决了。
九、 实验总结
四周的数电实验很快就结束了,期间通过老师的讲解和我自己的领悟,我了解了EDA技术和PLD开发工具Quartus II的基本使用方法,学会了通过原理图和VHDL语言设计、综合、仿真、下载程序,实现了一些简单功能,如计数器,也实现了一些稍微复杂但更实用的功能,如数码管扫描显示。四周实验在教会我这些技能的更教会了我如何思考和解决问题,同时也让我体会到了测试成功后油然而生的喜悦。虽然我知道目前我的水平还很肤浅,只是了解了EDA技术的表面,我很期待下学期的数电综合实验,也希望通过这两个学期的实验为未来继续学习打下坚实的基础。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define ch451_rst 0x0201 //复位
#define ch451_lmov 0x0300 //设置移动方式-左移 #define ch451_lcyc 0x0301 //设置移动方式-左循 #define ch451_rmov 0x0302 //设置移动方式-右移 #define ch451_rcyc 0x0303 //设置移动方式-右循
#define ch451_soff 0x0400 //关显示、键盘、看门狗 #define ch451_son 0x0401 //开显示
#define ch451_dsp 0x0500 //设置默认显示方式 #define ch451_BCD 0x0580 //设置BCD译码方式 #define ch451_twinkle 0x0600 //设置闪烁控制
#define ch451_DIG0 0x0800 //数码管位0显示 #define ch451_DIG1 0x0900 //数码管位1显示 #define ch451_DIG2 0x0A00 //数码管位2显示 #define ch451_DIG3 0x0B00 //数码管位3显示 #define ch451_DIG4 0x0C00 //数码管位4显示 #define ch451_DIG5 0x0D00 //数码管位5显示 #define ch451_DIG6 0x0E00 //数码管位6显示 #define ch451_DIG7 0x0F00 //数码管位7显示
sbit ch451_load=P0^0;
sbit ch451_din =P0^1;
sbit ch451_dclk=P0^2;
const uchar DatCode[18]={0x3F,0x06,0x5B,0x4F,//0,1,2,3
0x66,0x6D,0x7D,0x07,//4,5,6,7
0x7F,0x6F,0x77,0x7C,//8,9,A,b
0x39,0x5E,0x79,0x71,//C,d,E,F
0x40,0x00};//-,全灭
const uint DigCode[8]={ch451_DIG0,ch451_DIG1,ch451_DIG2,ch451_DIG3,
ch451_DIG4,ch451_DIG5,ch451_DIG6,ch451_DIG7};
const uint
table[]={0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009};
void delay(uchar t)
{
uchar tt;
for(;t>0;t--)
for(tt=200;tt>0;tt--);
}
void long_delay(uchar t)
{
for(;t>0;t--)
delay(255);
}
void write_ch451(uint cmd)
{
uchar i;
ch451_load=0;
for(i=0;i<12;i++)
{
ch451_din=cmd&1; ch451_dclk=0;
cmd=cmd>>1;
ch451_dclk=1;
}
ch451_load=1;
}
void ch451_init()
{
ch451_din=0;
ch451_din=1;
write_ch451(ch451_rst);
write_ch451(0x0401); //开显示 }
void main()
{
uchar i;
uint temp=0x01;
ch451_init();
long_delay(5);
// } write_ch451(0x0c80); write_ch451(0x08ff); write_ch451(0x09ff); write_ch451(0x0aff); write_ch451(0x0bff); write_ch451(0x0cff); write_ch451(0x0dff); write_ch451(0x0eff); write_ch451(0x0fff); while(1) { /* for(i=0;i<8;i++) { write_ch451(DigCode[i]|table[i]); long_delay(2); } */ }
数码管动态显示实验一实验要求1在Proteus软件中画好51单片机最小核心电路包括复位电路和晶振电路2在电路中增加四个7段数码管共…
实验四数码管动态显示实验一一实验要求1在Proteus软件中画好51单片机最小核心电路包括复位电路和晶振电路2在电路中增加四个7段…
HUNANUNIVERSITY课程实验报告实验名称学生姓名学生学号专业班级指导老师数码管显示实验20xx1217实验三数码管显示实…
实验七八段数码管显示实验1实验目的1了解数码管动态显示的原理2了解用总线方式控制数码管显示2实验要求利用实验仪提供的显示电路动态显…
实验四七段数码管显示实验一实验目的掌握数码管显示数字的原理二实验内容1静态显示数码管为共阴极通过BCD码译码驱动器CD4511驱动…
数码管动态显示实验一实验要求1在Proteus软件中画好51单片机最小核心电路包括复位电路和晶振电路2在电路中增加四个7段数码管共…
机器人控制课程总结报告机器人控制仿真实验二数码管动态显示姓名李铃年级20xx级系别信息工程学院计科师学号1111000048同组人…
实验四数码管动态显示实验一一实验要求1在Proteus软件中画好51单片机最小核心电路包括复位电路和晶振电路2在电路中增加四个7段…
实验七八段数码管显示实验1实验目的1了解数码管动态显示的原理2了解用总线方式控制数码管显示2实验要求利用实验仪提供的显示电路动态显…
实验七数码管动态扫描实验姓名专业学号20xx412381成绩一实验目的1掌握KeilC51软件与protues软件联合仿真调试的方…