微机原理与接口技术课程设计报告.docx
《微机原理与接口技术课程设计报告.docx》由会员分享,可在线阅读,更多相关《微机原理与接口技术课程设计报告.docx(16页珍藏版)》请在冰豆网上搜索。
微机原理与接口技术课程设计报告
微机原理与接口技术
课程设计报告
项目名称:
十进制数计算器的设计与实现
专业名称:
计算机科学与技术(交通信息工程)
学生:
俊(201324020311)
教师:
马荣贵
2016年1月1日
一、项目名称及要求
1项目名称
十进制数计算器的设计与实现
2项目要求
运用学过的《微机原理与接口技术》课程以及本学期的上机实验操作经验,根据题目设计要求进行软硬件系统的设计和实现,从而加深对本课程知识点的理解。
通过具体项目的实践,来提高学生的动手能力以及实时解决问题的能力,使学生综合能力得到显著提升。
本课题要求学生熟练运用并行接口8255A芯片、4*4键盘输入模块以及LED数码管输出模块的工作原理以及相应元件驱动程序的编写。
要求通过4*4键盘输入,LED数码管显示来完成简单计算器的功能(加减乘除操作)
二、项目背景及设计目的
1项目背景
大学课程设计是为了辅助学生加深对本课程的理论知识的理解和提高。
通过动手完成实际的项目设计及实现,减小理论与实践的距离,让同学对实际项目实现的流程有个大体的感受。
通过合作完成项目,提高同学的合作意识,以及模块化设计理念。
2项目目的
通过十进制数计算器的设计与实现,了解proteus软件使用;
熟练掌握原理图的设计方法
知道各硬件的功能以及电路实现
三、设计思路
1总体设计思路
4*4键盘输入模块:
键盘“0~9”对应数字0~9
键盘“A”对应符号“+”
键盘“B”对应符号“-”
键盘“C”对应符号“*”
键盘“D”对应符号“/”
键盘“E”对应符号“CE”
键盘“F”对应符号“=”
并行接口8255A:
A口用于LED数码管的段码输出
B口用于LED数码管的位码输出
C口用于4*4键盘的输入
LED数码管输出模块:
采用动态显示的方式,将并行接口8255A中A口中的段码显示
2设计流程图
四、项目方案及原理图
1项目方案
先设计原理图,然后用PCB布线仿真,最后去实验室用实验器材实现设计
2并行接口8255A
并行接口8255A:
8255A是通用可编程并行接口芯片,是有40个引脚的双列直插式组件,其基本功能为:
8255A接口芯片有3个8位并行输入/输出端口,可利用编程方法设置3个端口是作为输入端口还是输出端口;8255A能适应CPU与I/O接口之间的多种数据传送方式的要求,如无条件传送、查询方式传送、中断方式传送。
与此相对应,8255A设置了方式0、方式1以及方式2;
8255A的C口比较特殊,除作为数据口之外,在工作方式1和方式2下,它的部分信号线被分配作为专用的联络应答信号。
8255A引脚图:
8255A的工作原理:
方式0:
基本输入输出方式;
方式1:
选通式输入/输出方式;
方式2:
双向选通输入/输出方式。
8255的控制字:
工作方式选择控制字,D7~D0控制位的含义见下图:
本实验中使8255端口C高四位(PC7-PC4)与键盘扫描行连接,低四位(PC0-PC3)与键盘扫描列连接,B口低四位(PB0-PB3)用于控制数码管位码,端口A输出段码信号用于控制数码管对键盘数值的显示。
3键盘输入模块
4*4键盘:
矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。
在行线和列线的每一个交叉点上,设置一个按键。
这样键盘中按键的个数是4×4个。
这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。
4*4键盘的电路实现:
4LED数码管输出模块
LED数码管:
8段数码显示管用于一般的状态或数字的显示
共阴极对应字符的段码表:
显示字形
dp
g
f
e
d
c
b
a
段码
0
0
0
1
1
1
1
1
1
3fh
1
0
0
0
0
0
1
1
0
06h
2
0
1
0
1
1
o
1
1
5bh
3
0
1
0
0
1
1
1
1
4fh
4
0
1
1
0
0
1
1
0
66h
5
0
1
1
0
1
1
0
1
6dh
6
0
1
1
1
1
1
0
1
7dh
7
0
0
0
0
0
1
1
1
07h
8
0
1
1
1
1
1
1
1
7fh
9
0
1
1
0
1
1
1
1
6fh
.
1
0
0
0
0
0
0
0
80h
V
0
0
1
1
1
1
1
0
3eh
5原理图设计
五、结果与分析
1实现现象
2现象分析
由于LED显示是动态的,就没有以图片的方式展示,不过在电子版的报告中,现象视频在附录文件中。
上述现象包含加减乘除以及混合运算的演示。
其中已经演示了包含高于两位十进制数、负数的运算。
六、总结及体会
这次实验真是一波三折,刚开始我的选题是8259的级联,我和我的小组成员已经将实验的流程以及具体实施方案规划好了。
但是由于临时的变动了选题,我们开始重新设计,利用课余时间陆陆续续的完成了整个设计流程。
到课设的第一天,我们开始连线,以及将驱动程序写入,但是测试的时候出现各种问题,比如说显示不正常,屏幕闪烁太频繁。
我们晚上回去思考,第二天重新调试,得到了预期的结果。
由于课设的时间还没有结束,我们又将其功能进行了扩展:
可以实现多位计算器,可实现负数运算,可实现连续运算。
不足的地方在于,没有实现对不同级别运算的先后顺序的判断。
七、附录
1参考文献
《微机原理与接口技术》,郭兰英等编著,清华大学,2006年
《C++语言程序设计》(第四版),丽等编著,清华大学,2010年
《TPC-ZK产品说明》,清华大学器材部编写,清华大学,2008年
2源代码
/***************************************/
/****实验名称:
运算器********************/
/****实验容:
实现加减乘除运算**********/
/****作者:
俊、丰翔********************/
/****时间:
2015-11-21*******************/
/***************************************/
#include
#include
#include"ApiExusb.h"
#pragmacomment(lib,"ApiExusb.lib")
charled[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,
0x71,0x00,0x40};/*0~F无字符负号*/
voidtoshu(byte*a,int&shu1){/*将数组a中的字符转化为一个数*/
if(a[3]==16)shu1=0;
elseif(a[2]==16)shu1=a[3];
elseif(a[1]==16)shu1=a[3]+10*a[2];
elseif(a[0]==16)shu1=a[3]+10*a[2]+100*a[1];
elseshu1=a[3]+10*a[2]+100*a[1]+1000*a[0];
}
voidshuto(byte*a,intshu1){/*将一个数的各个位转化到数组a中*/
intfuhao1;
if(shu1<0){
fuhao1=-1;
shu1=-shu1;
}
a[0]=shu1/1000%10;/*保证溢出的时候仍能正常显示低位*/
a[1]=shu1/100%10;
a[2]=shu1/10%10;
a[3]=shu1%10;
if(a[0]==0&&a[1]==0&&a[2]==0&&a[3]==0){
a[0]=16;
a[1]=16;
a[2]=16;
a[3]=0;
}
elseif(a[0]==0&&a[1]==0&&a[2]==0){
a[0]=16;
a[1]=16;
a[2]=16;
if(fuhao1<0)a[2]=17;
}
elseif(a[0]==0&&a[1]==0){
a[0]=16;
a[1]=16;
if(fuhao1<0)a[1]=17;
}
elseif(a[0]==0){
a[0]=16;
if(fuhao1<0)a[0]=17;
}
}
voidjisuan(int&shu1,intshu2,charfuhao){/*计算,将结果存入shu1中*/
if(fuhao=='+')shu1+=shu2;
elseif(fuhao=='-')shu1=shu2-shu1;
elseif(fuhao=='*')shu1*=shu2;
elseif(fuhao=='/'&&shu1!
=0)shu1=shu2/shu1;
else{printf("运算不合法");exit(0);}
}
voidmain()
{
bytedata;
bytei,j,k=3,ll=0,l=0;/*k是用来控制数码管位码的*/
bytea[4]={16,16,16,0};/*用来存储LED对应段码的在数组中的下标*/
intshu1=0,shu2=0;/*shu1是临时操作数;shu2是上一步的计算结果*/
charfuhao='+';
printf("Pressanykeytobegin!
\n");
getch();
if(!
Startup())/*打开设备*/
{
printf("ERROR:
OpenDeviceError!
\n");
return;
}
printf("pressanykeytoexit\n");
PortWriteByte(0x28b,0x81);/*设置8255的A口B口均为输出、C口输入100010001*/
PortWriteByte(0x28a,0x0f);
PortReadByte(0x28a,&data);/*预读端口值*/
i=data;
while(!
kbhit())/*如果不按接盘,一直循环工作*/
{
PortWriteByte(0x28b,0x81);/*设置8255的A口B口均为输出C口输入100010001*/
//PortWriteByte(0x289,0);
PortWriteByte(0x288,led[a[3]]);
PortWriteByte(0x289,0x01);/*动态显示a中的数字*/
Sleep(50);
PortWriteByte(0x288,led[a[2]]);
PortWriteByte(0x289,0x02);
Sleep(50);
PortWriteByte(0x288,led[a[1]]);
PortWriteByte(0x289,0x04);