基于8255的8LED显示的动态显示器南京邮电大学
学年 第 学期
课程设计实验报告
题 目 基于8255的8LED显示的动态显示器
专 业 通信工程
学 号
姓 名
指导老师
实验日期 年 月 日
题目:基于8255的8LED显示的动态显示器
一 ,实验目的和要求
1,Proteus软件的MCS51...
南京邮电大学
学年 第 学期
课程设计实验报告
题 目 基于8255的8LED显示的动态显示器
专 业 通信工程
学 号
姓 名
指导老师
实验日期 年 月 日
题目:基于8255的8LED显示的动态显示器
一 ,实验目的和
1,Proteus软件的MCS51单片机仿真学习
2,根据提供的参考工程,在proteus平台自己重新设计实验电路所需要的电器原理图,并在此基础上编写相对应的程序,实现其功能,学习proteus软件的使用,其中包括原理图器件的选取,原理图的电气连接,程序的编写编译以及运行,并能查出其错误等。
基本要求:
1. 用数码管正常显示数字“12345678”。
2. 通过按键可改变显示方式。
3. 设计显示屏的动态效果,用10个按键,每键对应一种滚动技术。
4. 基于8255口是指显示和键盘都由8255的IO口控制
发挥部分:
1 设计所有动作的联合效果。
2 设计二个变速按键,可多级改变滚动速度。
3 设计一台魔术电子钟,采用自动变换,随机组合,数据每10秒变换一次。
动态显示格式:
1 静止
2 整体闪烁
3 单字闪烁
4 整体向前、向后滚动
5 单字移动
6 两边向中间压缩
7 中间向两边扩张
8 上下压缩
9 文字上下滚动
10组合动作(每一字符执行上述一个动作,并同时运动)
二,实验仪器
微型计算机
三,实验原理
基于8255的8LED显示的动态显示器,是由8255a做键盘控制口连接c51,并驱动8位7段数码管实现相应显示功能。具体的,c51,p1口直接进行led数码管的位控制;p2口经74HC573译码后控制8255a的片选与内部奇存器选择;p0口连接8255a的D端口,并由它的PA口驱动7段led, PB口连接键盘,并做为I/O口与c51通信,以实现相应显示变化。
四,基本原件及其原理
单片机微型计算机简称单片机,是指在一块芯片体上集成了中央处理器CPU、随机存储器RAM、程序存储器ROM或EPROM、定时器/计数器、中断控制器以及串行和并行I/O接口等部件,构成一个完整的微型计算机。目前,新型单片机内还有A/D及D/A转换器、高速输入/输出部件、DMA通道、浮点运算等特殊功能部件。由于它的结构和指令功能都是按工业控制设计要求设计的,特别适用于工业控制及其数据处理场合,因此,确切的称谓是微控制器,单片机只是习惯称呼。
51单片机引脚图如下:
(1)单片机的特点
1)有优异的性能价值比。
2)集成度高、体积小、有很高的可靠性。单片机把各个功能部件集成在一块芯片上,内部采用总线结构,减少了各芯片之间的连线,大大提高了单片机的可靠性与抗干扰能力。另外,其体积小,对于强磁场环境易于采取
,适合于恶劣环境下工作;也易于产品化。
3)控制功能强。为了满足工业控制的要求,一般单片机的指令系统中均有及其丰富的转移指令、I/O口逻辑操作及位处理指令。一般来说,单片机的逻辑控制功能及运行速度高于同意档次的微机。
4)单片机的系统扩展和系统配置都比较典型、规范,而且非常容易构成各种规模的应用系统。
(2)单片机并行I/O接口的扩展
单片机与外部交换信息是通过I/O接口电路来实现的。AT89C51单片机本身有4个8位的并行I/O口P0-P3,但实际使用时往往再增加些I/O口,以便与外部设备交换数据。AT89C51单片机外部RAM和扩展I/O接口是统一编址的。用户可以把外部64KB RAM空间的一部分作为扩展I/O接口地址空间,每一个I/O接口相当于一个RAM存储单元,访问外部RAM存储单元就像访问外部I/O接口,即用“MOVX”指令对扩展I/O接口进行输入输出操作。
查询式键盘的接口电路
查询式键盘属于独立式键盘,键盘的各个按键之间彼此是独立的且是最简单的键盘电路。每个键地接入一根数据输入线。如图所示。注意:由于每一个按键均需要一根I/O口线 ,当键盘按键数量比较多时,需要的I/O口线也较多,因此独立式键盘只适合于按键较少的应用场合。一般情况下,按键数等于占用I/O端口数。
查询式键盘的结构图如图所示:
P1.0
P1.1
查询式键盘的接口电路
查询式键盘可以工作在多种方式下,中断方式、程序查询方式、定时查询发送和中断查询方式。
在中断模式下,按键的数量受到外部中断源的限制。在有特殊需要的场合,还可以借用内部的定时器中断。所以在这种模式下,按键的数目小于外部中断源和单片机定时器数量之和。
程序查询和定时查询类似,都是通过读I/O状态,当有键被按下时相应的I/O口线变为低电平,而未被按下的键对应的I/O口线保持为高电平,这样通过读I/O口状态可判断是否有键按下和哪一个键被按下。
7SEG-MPX8-CA-BLUE的基本参数
7SEG-MPX8-CA-BLUE为蓝色共阳极8位七段数码管
7SEG-MPX8-CA-BLUE
五,仿真软件的使用
1.Keil软件的使用:
首先正确安装keil软件—>打开keil—>project—>new Uvision project—>为工程取名字,并选择工程要保存的路径,建议每个工程新建一个文件夹,方便文件管理—>出来一个对话框,是选择芯片的,你根据你的芯片公司和型号来选择就行了,比如:最常用的at89c51,点atmel,找到at89c51,点OK后会出来一个对话框,问你是否添加启动文件,点“是”—>这样就建好了一个工程,点File菜单下New新建文件—>先保存文件,点保存按钮后出来路径框,取名字后缀是.c或者.h,点保存—>接下来在左边project下把Target1点开,在Source Group 1上右键,点击Add File to Group 'Source Group 1'—>在弹出的框中点刚刚保存的文件,然后点Add,关闭对话框,左边project框中可以看到文件已经添加—>在开始之前还是先来配置一下keil环境,点击工具栏品字图标左边像魔棒一样的按钮—>接下来的配置比较复杂,我用图来解释,Target项目下只改一个晶振的值,Output下要点击生产HEX文件,Debug下左边是keil仿真调试配置,右边是程序下载到芯片调试配置,看你是怎么用了。—>完工,可以编程调试。
2.proteus软件的使用:
新建文件,查找元件,并添加。画好电路图后,添加用keil生成的hex文件,即可运行。
六,实验数据
1.实验连接图
2.实验结果图(初始状态)
3.显示功能
4.实验程序
/*--------------------库文件--------------------------*/
#include
#include
/*---------------------宏定义-------------------------*/
#define uint unsigned int
#define uchar unsigned char
/*----------------芯片端口地址定义---------------------*/
#define COM8255 XBYTE[0X7FFF] //8255的命令口
#define PA8255 XBYTE[0X1FFF] //8255的PA
#define PB8255 XBYTE[0X3FFF] //8255的PB
uchar code du_code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//8段共阳极数码管显示码值
uchar code bit_code[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//数码管显示的位值
/*--------------定义系统变量--------------------------------*/
bit flag=0; //定义状态标志位
uchar value=0,wei;
uchar count;
/*------------------------------------------*/
/*形式参数:void */
/*返回值:void */
/*函数描述:延时函数 */
/*------------------------------------------*/
void delayms(uchar x) //ms延时函数
{
uchar y;
for(;x>0;x--)
for(y=150;y>0;y--) ;
}
void keyscan()
{
uchar i=0,j=0;
PB8255=0xf0;
if(PB8255!=0xf0)
{
delayms(1);
if(PB8255!=0xf0)
{
switch(PB8255)
{
case 0xe0:j=1; break;
case 0xd0:j=2; break;
case 0xb0:j=3; break;
case 0x70:j=4; break;
}
PB8255=0x0f; //反转
switch(PB8255)
{
case 0x0e:i=0;break;
case 0x0d:i=1;break;
case 0x0b:i=2;break;
case 0x07:i=3;break;
}
value=i*4+j-1;
flag=1;
if(value==2)
{
wei++;
if(wei>=9)
wei=1;
}
while(PB8255!=0x0f); //按键弹起
}
}
}
/*************************状态一-静止****************************/
void state1()
{
uchar i;
while(value==0) //判断是否为状态1
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(1); //延时
}
}
}
/**************************状态二-整体闪烁***************************/
void state2()
{
uchar i=0,j=0;
while(value==1) //判断是否为状态2
{
for(j=0;j<50;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(2); //延时
}
}
for(j=0;j<50;j++)
{
P1=0x00;
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(20);
}
} //延时
}
/******************************状态三-单字闪烁***************************/
void state3()
{
uchar i=0,j=0;
while(value==2) //判断是否为状态3
{
for(j=0;j<50;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(2); //延时
}
}
for(j=0;j<50;j++)
{
for(i=1;i<9;i++)
{
if(i==wei)
P1=0x00;
else
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(2); //延时
}
}
}
}
/*************************状态四-整体向前、向后滚动*************************/
void state4()
{
uchar i=0,j=0,z=0;
while(value==3) //判断是否为状态4
{
for(z=0;z<8;z++)
{
for(j=1;j<120;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[(i+z)%8+1]; //输入段选码值
keyscan();
if(flag==1) //扫描键盘
{
flag=0;
return; //有键按下返回
}
delayms(2);
} //延时
}
}
}
}
/***************************状态五-单字移动*******************************/
void state5()
{
uchar i=0,j=0;
while(value==4) //判断是否为状态5
{
for(j=1;j<9;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[j]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(1500); //延时
}
}
}
}
/************************状态六-两边向中间压缩*************************/
void state6()
{
uchar i=0,j=0;;
while(value==5) //判断是否为状态6
{
for(j=1;j<100;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
delayms(3);
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
delayms(500); //延时
for(j=1;j<100;j++)
{
for(i=2;i<5;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i-1]; //输入段选码值
delayms(3);
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
for(i=5;i<8;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i+1]; //输入段选码值
delayms(3);
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
delayms(500); //延时
for(j=1;j<100;j++)
{
for(i=3;i<5;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i-2]; //输入段选码值
delayms(3);
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
for(i=5;i<7;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i+2]; //输入段选码值
delayms(3); //延时
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
delayms(500); //延时
for(j=1;j<100;j++)
{
P1=bit_code[4]; //输入位选码值
PA8255=du_code[1]; //输入段选码值
delayms(10);
//输入位选码值
P1=bit_code[5]; //输入段选码值
PA8255=du_code[8];
delayms(10); //延时
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
}
/**************************状态七7-中间向两边扩张***************************/
void state7()
{
uchar i=0,j=0;;
while(value==6) //判断是否为状态7
{
for(j=1;j<100;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
delayms(3); //延时
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
delayms(500); //延时
for(j=1;j<100;j++)
{
for(i=1;i<4;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i+1]; //输入段选码值
delayms(3); //延时
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
for(i=6;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i-1]; //输入段选码值
delayms(3); //延时
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
delayms(500); //延时
for(j=1;j<100;j++)
{
for(i=1;i<3;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i+2]; //输入段选码值
delayms(3);
keyscan(); //扫描键盘
if(flag==1)
{
flag=0; //有键按下返回
return;
}
}
for(i=7;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i-2]; //输入段选码值
delayms(3); //延时
keyscan();
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
delayms(500);
for(j=1;j<100;j++)
{
P1=bit_code[1]; //输入位选码值
PA8255=du_code[4]; //输入段选码值
delayms(10); //延时
P1=bit_code[8]; //输入位选码值
PA8255=du_code[5]; //输入段选码值
delayms(10);
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
}
/*************************状态八函数-全功能**************************/
void state8()
{
uchar i=0,j=0,z=0;
while(value==7) //判断是否为状态8
{
for(z=0;z<8;z++)
{
for(j=0;j<50;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[(i+z)%8+1]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(2); //延时
}
}
P1=0x00;
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(1500); //延时
}
}
}
void state9()
{
uint i=0,j,z;
while(value==8)
{
for(j=0;j<200;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
delayms(2);
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
for(z=1;z<8;z++)
{
for(j=0;j<50;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
delayms(2);
if(flag==1)
{
flag=0;
return; //有键按下返回
}
}
}
for(j=0;j<50;j++)
{
P1=0x00;
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(20);
}
}
for(z=0;z<8;z++)
{
for(j=0;j<50;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(2); //延时
}
}
for(j=0;j<50;j++)
{
for(i=1;i<9;i++)
{
if(i==1)
P1=0x00;
else
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[i]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(2); //延时
}
}
}
for(z=0;z<8;z++)
{
for(j=1;j<120;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[(i+z)%8+1]; //输入段选码值
keyscan();
if(flag==1) //扫描键盘
{
flag=0;
return; //有键按下返回
}
delayms(2);
} //延时
}
}
for(j=1;j<9;j++)
{
for(i=1;i<9;i++)
{
P1=bit_code[i-1]; //输入位选码值
PA8255=du_code[j]; //输入段选码值
keyscan(); //扫描键盘
if(flag==1)
{
flag=0;
return; //有键按下返回
}
delayms(500); //延时
}
}
}
}
void Initial()
{
COM8255=0x80; //输入输出方式设置 定义8255的A口为输出 BC 为IO
PA8255=0XFF;
P1=0X00;
}
void main()
{
Initial(); //系统初始化
while(1)
{
keyscan();
state1(); //查询状态一
state2(); //查询状态二
state3(); //查询状态三
state4(); //查询状态四
state5(); //查询状态五
state6(); //查询状态六
state7(); //查询状态七
state8();
state9();
}
}
七.实验小结:
通过本次试验,我对proteus和keil软件的应用有了进一步认识,并且通过对c51的编程,复习巩固了c语言的相关知识。虽然实验要求的仅是关于c51单片机的简单显示操作,但由于8255a的加入,让编程一度出现困难,好在经过多方的查找资料和讨论,最终问题得到了圆满解决。
在此非常感谢在这过程中老师的指导和同学间的讨论,让此次实验获得了成功。
最后通过此次试验,我不仅仅学到了本上的知识,而且也培养了小组之间互相讨论,互相协作的良好习惯。相信在以后的学习过程中,会有更大的收获。
本文档为【基于8255的8LED显示的动态显示器】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。