实验一LED显示控制82C55A并行接口数码管显示控制实验Word文件下载.docx
《实验一LED显示控制82C55A并行接口数码管显示控制实验Word文件下载.docx》由会员分享,可在线阅读,更多相关《实验一LED显示控制82C55A并行接口数码管显示控制实验Word文件下载.docx(24页珍藏版)》请在冰点文库上搜索。
![实验一LED显示控制82C55A并行接口数码管显示控制实验Word文件下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/2/c4616b89-0b18-47bf-b43e-ef1487475550/c4616b89-0b18-47bf-b43e-ef14874755501.gif)
四、程序代码
录入程序时,请特别注意”1”与英文字母”l”的区别,文件的扩展名为C,即文件名一定是?
?
-?
.C。
在每个源程序的开头必须加上如下的注解,并按各人实际填写。
/*
源程序的文件名:
实验序号(01-08)-实验组号(01-24).C
实验名称:
___________________________
实验组号:
学生姓名及学号:
________________________
*/
#include<
stdio.h>
dos.h>
#include“PCIcard.h”
intd1=0,m_bit=0x1;
voidmain()
{
interr,rio,flagm;
intm_k0();
voidm_k1();
voidm_k2();
voidm_k3();
err=findPCIcard();
if(err!
=0)
{
printf("
ThePCIcardisn'
tfound!
!
\n"
);
flagm=0;
}
err=getPCIbase0();
iobase0=iobase0&
0xfffc;
//从PCI配置空间读入的与地址空间有关的数据其bit0位为1,
IOBase0=%xH\n"
iobase0);
//表明此空间为IO空间参与PCI总线地址译码
err=getPCIbase1();
iobase1=iobase1&
IOBase1=%xH\n"
iobase1);
err=getPCImembase1();
err=getPCImembase0();
membase0=membase0+membase1<
<
16;
//左移16位,将高位地址变换成双字中的高位字
MEMBase0=%lxH\n"
membase0);
err=getPCIIRQ();
PCIIRQ=%d\n"
err);
//////////////////////////////////
ioadd1=ioadd1+iobase1;
//获取步进电机驱动端口地址
flagm=1;
PressK1andK2tolowtoexit.\n"
//选择正、反转或退出
do//主循环
rio=inportb(ioadd1);
//从IO端口读入数据
rio=rio&
0x3;
//保留低两位
switch(rio)//判断数据并做相应处理
case0:
//为0时LED全亮
flagm=m_k0();
break;
case1:
//为1时LED全部闪烁
m_k1();
case2:
//为2时LED从下到上循环点亮
m_k2();
case3:
//为3时LED从上到下循环点亮
m_k3();
default:
}while(flagm==1);
//////////////////////////////////////
return;
}
intm_k0()//LED全亮并退出程序
intflagk;
outportb(ioadd1,
(1));
flagk=0;
return(flagk);
voidm_k1()//LED闪烁
voiddelay1();
if(d1==0)
outportb(
(2));
(3);
d1=1;
else
outportb(ioadd1,0x0);
delay1();
(4);
voidm_k2()//LED从下到上循环点亮
inttemp;
temp=m_bit&
0x80;
(5);
if(temp==0x80)
m_bit=m_bit|1;
outportb(ioadd1,m_bit);
voidm_k3()//LED从上到下循环点亮
temp=m_bit&
(6);
m_bit=m_bit>
>
(7);
if(temp==0x1)
m_bit=m_bit|0x80;
voiddelay1()//延时
inti,j,a=0;
for(i=1;
i<
=5000;
i++)
for(j=1;
j<
=10000;
j++)
a=a+0;
将PCIcard.h与上述的C源程序存放在同一目录下,PCIcard.h的内容如下:
conio.h>
unsignedlongintiobase0,iobase1,membase0,membase1;
unsignedlongintinterrupt_line,ioadd1=0x60;
unsignedcharbh;
unsignedcharbl;
intfindPCIcard(void);
//找寻PCI卡的总线号及设备号及功能号
intgetPCIbase0(void);
//获得PCI卡的IO0的地址
intgetPCIbase1(void);
intgetPCImembase0(void);
intgetPCImembase1(void);
intgetPCIIRQ(void);
structdx
intdl;
intdh;
}mydx;
intfindPCIcard(void)//找寻PCI卡的总线号及设备号及功能号
unionREGSregs;
regs.h.ah=0xb1;
regs.h.al=0x02;
//寻找指定厂商和设备号的PCI卡的位置
regs.x.cx=0x8376;
regs.x.dx=0x10eb;
//输入要寻找的厂商号和设备号
regs.x.si=0x00;
//输入要寻找的PCI卡索引号
int86(0x1a,&
regs,&
regs);
//调用指定的X86中断
bl=regs.h.bl;
//返回的设备号高5位,低3位为功能号
bh=regs.h.bh;
//返回的总线号
return(regs.h.ah);
//返回状态
intgetPCIbase0(void)//获得PCI卡的IO0的地址
unionREGSregs;
//定义用C语言调用BIOS中断所用的寄存器组合
//调用PCIBIOS中断
regs.h.al=0x09;
//配置空间用字的方式读入
regs.x.di=0x14;
//PCI配置空间中基地址0的地址
regs.h.bl=bl;
//要读入配置空间的PCI卡的设备号和功能号
regs.h.bh=bh;
//要读入配置空间的PCI卡的总线号
iobase0=regs.x.cx;
//CX为返回的IO0的基地址
intgetPCIbase1(void)
//同上
regs.x.di=0x1c;
//PCI配置空间基地址1的地址
iobase1=regs.x.cx;
intgetPCImembase0(void)
regs.x.di=0x18;
//PCI配置空间存储器基地址0的低位地址
membase0=regs.x.cx;
intgetPCImembase1(void)
regs.x.di=0x1a;
//PCI配置空间存储器基地址0的高位地址
membase1=regs.x.cx;
intgetPCIIRQ(void)
regs.x.di=0x3c;
//PCI配置空间中断线的地址
interrupt_line=regs.x.cx;
return(regs.h.cl);
五、思考题:
1、在图1中,从数据端口送出”1”使LED亮,还是使LED灭?
2、将K1L、K2L这一点亮退出功能修改为:
自上而下一个一个点亮,然后自下而上一个一个熄灭,循环不断。
3、根据框图和原理填写源程序中的空白处,并写出注解。
(82C55A并行接口数码管实验部分)
实验电路如图6所示。
动态LED数码显示的原理如下:
8255的A口工作简单输出方式(1:
亮,0:
暗)输出数据(段码)控制所有数码管的不同段。
PB0~3设置为输出,控制4个LED数码管公共端的电流通路(0:
通,1:
断),轮流使其中一个数码管亮,从而构成动态LED数码显示器。
编程要求:
设立一计数单元,该单元做0~9999的十进制加计数。
编制动态LED数码显示的子程序和计数单元计数并显示的主程序。
显示0~F数字并循环。
图6
图7
三、硬件实验步骤
本实验在板上由G与B部分组成,有短路块与跳线两种方式。
短路块为缺省方式。
下面介绍跳线方式。
1、把J16的短路块去掉
2、通过跳线把G区的PA0与数码管部分的B区A相连;
3、PA1与B相连
4、PA2与C相连
5、PA3与D相连
6、PA4与E相连
7、PA5与F相连
8、PA6与G相连
9、PA7与DP相连
10、把B区的J36、J38、J35、J39的短路块去掉
11、J37的第1脚与PB0相连
12、J37的第2脚与PB2相连
13、J37的第3脚与PB1相连
14、J37的第4脚与PB3相连
四、程序框图
BCD码头与7段码关系
00c0H,10f9H20a4H30b0H499H
592H682H70f8H880H998H
A88HB83HC0c6HD0a1HE86H
F8eH
五.程序代码(八段数码显示)
unsignedlongintic8255a=0x0,ic8255b=0x1,ic8255type=0x3;
intbuffer1[10]={0x0c0,0x0f9,0x0a4,0x0b0,0x99,
0x92,0x82,0x0f8,0x80,0x98};
intdis1[4]={0,0,0,0};
interr,count1,flagm=1,flag1=1;
voidplus1();
voidmydisp1();
intmypckey();
ic8255a=ic8255a+iobase1;
//获取8255A、B口和控制寄存器的地址
ic8255b=ic8255b+iobase1;
ic8255type=ic8255type+iobase1;
Pressetoexit:
//显示提示字符
outportb(
(1));
//初始化8255
outportb(ic8255a,
(2));
//灭所有的段
outportb(ic8255b,(3));
//灭所有的位
count1=0xff;
//设置计数值
plus1();
//将显示数据加1
flag1=1;
//将小循环标志置位
do//小循环
mydisp1();
//调显示子程序
count1=count1-1;
//计数值减1
if(count1==0)//判断是否退出小循环
flag1=0;
}while(flag1==1);
flagm=mypckey();
//扫描键盘
////////////////////////////////////////////////////////////////////////////
intmypckey()//扫描键盘子程序
intpckey1();
intflagk,judge;
judge=pckey1();
if(judge=='
e'
)
flagk=1;
intpckey1()//调用int21H中断
regs.h.ah=0x6;
regs.h.dl=0x0ff;
int86(0x21,&
return(regs.h.al);
voidplus1()//加1子程序
inti;
dis1[0]=dis1[0]+1;
for(i=0;
=2;
if(dis1[i]>
=10)
dis1[i]=dis1[i]-10;
dis1[i+1]=dis1[i+1]+1;
if(dis1[3]>
dis1[3]=0;
voidmydisp1()//显示子程序
inti,a1,a2=0x0fe;
=3;
outportb(ic8255a,0x0ff);
a1=buffer1[dis1[i]];
outportb(ic8255a,a1);
outportb(ic8255b,a2);
a2=a2<
1;
a2=a2|(4);
//作用是:
(5)
voiddelay1()//延时子程序
=50;
i++){
=1000;
j++)a=a+0;
}
思考题:
1.本实验采用的LED数码管是共阳的还是共阴的?
7407的作用是什么?
2.8255的端口是如何初始化的?
如何实现动态显示的?
用示波器观察PB口的波形,分别画出PB0,PB1,PB2,PB3的波形。
3.Delay1()的延时时间应在什么范围内,可以使LED没有闪烁感?
4.仔细观察LED为什么不该亮的段有隐隐的闪亮?
仔细分析mydiap1()中输出数据的先后关系,如何改进可以消除上述现象?
5.分析main(),CPU的时间主要花在哪个函数上?
常用什么方法可以减少对CPU的占用时间?