实验一LED显示控制82C55A并行接口数码管显示控制实验.docx

上传人:b****4 文档编号:12260892 上传时间:2023-04-17 格式:DOCX 页数:24 大小:357.74KB
下载 相关 举报
实验一LED显示控制82C55A并行接口数码管显示控制实验.docx_第1页
第1页 / 共24页
实验一LED显示控制82C55A并行接口数码管显示控制实验.docx_第2页
第2页 / 共24页
实验一LED显示控制82C55A并行接口数码管显示控制实验.docx_第3页
第3页 / 共24页
实验一LED显示控制82C55A并行接口数码管显示控制实验.docx_第4页
第4页 / 共24页
实验一LED显示控制82C55A并行接口数码管显示控制实验.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

实验一LED显示控制82C55A并行接口数码管显示控制实验.docx

《实验一LED显示控制82C55A并行接口数码管显示控制实验.docx》由会员分享,可在线阅读,更多相关《实验一LED显示控制82C55A并行接口数码管显示控制实验.docx(24页珍藏版)》请在冰豆网上搜索。

实验一LED显示控制82C55A并行接口数码管显示控制实验.docx

实验一LED显示控制82C55A并行接口数码管显示控制实验

实验1LED显示控制、82C55A并行接口数码管显示控制

一、实验目的和内容

1.掌握三态门,锁存器构成简单I/O端口的原理及应用

2.完成流水灯及其控制的编程实验

3.进一步掌握8255的使用原理

4.掌握动态LED数码显示的原理

5.完成动态LED数码显示的编程实验

(LED显示控制部分)

二、实验电路及说明

实验电路图1,2,3所示,74ALS273锁存器的输出控制LED发光管的亮暗(1:

亮0:

暗)74ALS273的CLK被一些地址线所控制,它的地址为60H(16进制)

ADD7,ADD6,ADD5,ADD4,ADD3,ADD2,ADD1,ADD0

01100000

只有这时7430与非门才输出低电平(八段LED是阴极型)

在DOS下,它的真实地址为PCI接口板的I/O地址加上60H为真实地址。

如PCI的I/O起始地址0为E000H,I/O起始地址1为E400H。

74ALS273的地址为E460H。

注意:

PCI板卡分配了2块I/O空间,I/O空间0是分配给PCI板卡内部寄存器使用的,即9052专用,空间大小128BYTE。

I/O空间1是分配给PCI板卡用户电路使用的,其大小为256BYTE。

流水灯原理如下:

K1、K2是八位拔动开关(位于区域F)的左边第1、2位。

K1=K2=H发光管从上到下移位

K1=L,K2=H发光管从下到上移位

KI=H,K2=L发光管全部闪烁

K1=K2=L-退出

注:

ON方向为L,OFF方向为H

K1、K2为主板上J41数码拔动开关的1、2位。

 

 

图1

 

图2

 

图3

三、程序方框图

 

 

四、程序代码

录入程序时,请特别注意”1”与英文字母”l”的区别,文件的扩展名为C,即文件名一定是?

?

-?

?

.C。

在每个源程序的开头必须加上如下的注解,并按各人实际填写。

/*

源程序的文件名:

实验序号(01-08)-实验组号(01-24).C

实验名称:

___________________________

实验组号:

___________________________

学生姓名及学号:

________________________

*/

#include

#include

#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,

printf("IOBase0=%xH\n",iobase0);

//表明此空间为IO空间参与PCI总线地址译码

err=getPCIbase1();

iobase1=iobase1&0xfffc;

printf("IOBase1=%xH\n",iobase1);

err=getPCImembase1();

err=getPCImembase0();

membase0=membase0+membase1<<16;

//左移16位,将高位地址变换成双字中的高位字

printf("MEMBase0=%lxH\n",membase0);

err=getPCIIRQ();

printf("PCIIRQ=%d\n",err);

//////////////////////////////////

ioadd1=ioadd1+iobase1;//获取步进电机驱动端口地址

flagm=1;

printf("PressK1andK2tolowtoexit.\n");//选择正、反转或退出

do//主循环

{

rio=inportb(ioadd1);//从IO端口读入数据

rio=rio&0x3;//保留低两位

switch(rio)//判断数据并做相应处理

{

case0:

//为0时LED全亮

flagm=m_k0();

break;

case1:

//为1时LED全部闪烁

m_k1();

break;

case2:

//为2时LED从下到上循环点亮

m_k2();

break;

case3:

//为3时LED从上到下循环点亮

m_k3();

break;

default:

break;

}

}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);

}

return;

}

voidm_k2()//LED从下到上循环点亮

{

voiddelay1();

inttemp;

temp=m_bit&0x80;

(5);

if(temp==0x80)

m_bit=m_bit|1;

outportb(ioadd1,m_bit);

delay1();

return;

}

voidm_k3()//LED从上到下循环点亮

{

voiddelay1();

inttemp;

temp=m_bit&(6);

m_bit=m_bit>>(7);

if(temp==0x1)

m_bit=m_bit|0x80;

outportb(ioadd1,m_bit);

delay1();

return;

}

voiddelay1()//延时

{

inti,j,a=0;

for(i=1;i<=5000;i++)

{

for(j=1;j<=10000;j++)

{

a=a+0;

}

}

return;

}

将PCIcard.h与上述的C源程序存放在同一目录下,PCIcard.h的内容如下:

#include

#include

#include

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,®s,®s);//调用指定的X86中断

bl=regs.h.bl;//返回的设备号高5位,低3位为功能号

bh=regs.h.bh;//返回的总线号

return(regs.h.ah);//返回状态

}

intgetPCIbase0(void)//获得PCI卡的IO0的地址

{

unionREGSregs;//定义用C语言调用BIOS中断所用的寄存器组合

regs.h.ah=0xb1;//调用PCIBIOS中断

regs.h.al=0x09;//配置空间用字的方式读入

regs.x.di=0x14;//PCI配置空间中基地址0的地址

regs.h.bl=bl;//要读入配置空间的PCI卡的设备号和功能号

regs.h.bh=bh;//要读入配置空间的PCI卡的总线号

int86(0x1a,®s,®s);//调用指定的X86中断

iobase0=regs.x.cx;//CX为返回的IO0的基地址

return(regs.h.ah);//返回状态

}

intgetPCIbase1(void)

{

unionREGSregs;//同上

regs.h.ah=0xb1;

regs.h.al=0x09;

regs.x.di=0x1c;//PCI配置空间基地址1的地址

regs.h.bl=bl;

regs.h.bh=bh;

int86(0x1a,®s,®s);

iobase1=regs.x.cx;

return(regs.h.ah);

}

intgetPCImembase0(void)

{

unionREGSregs;//同上

regs.h.ah=0xb1;

regs.h.al=0x09;

regs.x.di=0x18;//PCI配置空间存储器基地址0的低位地址

regs.h.bl=bl;

regs.h.bh=bh;

int86(0x1a,®s,®s);

membase0=regs.x.cx;

return(regs.h.ah);

}

intgetPCImembase1(void)

{

unionREGSregs;//同上

regs.h.ah=0xb1;

regs.h.al=0x09;

regs.x.di=0x1a;//PCI配置空间存储器基地址0的高位地址

regs.h.bl=bl;

regs.h.bh=bh;

int86(0x1a,®s,®s);

membase1=regs.x.cx;

return(regs.h.ah);

}

intgetPCIIRQ(void)

{

unionREGSregs;//同上

regs.h.ah=0xb1;

regs.h.al=0x09;

regs.x.di=0x3c;//PCI配置空间中断线的地址

regs.h.bl=bl;

regs.h.bh=bh;

int86(0x1a,®s,®s);

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

五.程序代码(八段数码显示)

#include

#include

#include“PCIcard.h”

unsignedlongintic8255a=0x0,ic8255b=0x1,ic8255type=0x3;

intbuffer1[10]={0x0c0,0x0f9,0x0a4,0x0b0,0x99,

0x92,0x82,0x0f8,0x80,0x98};

intdis1[4]={0,0,0,0};

voidmain()

{

interr,count1,flagm=1,flag1=1;

voidplus1();

voidmydisp1();

intmypckey();

err=findPCIcard();

if(err!

=0)

{

printf("ThePCIcardisn'tfound!

!

!

\n");

flagm=0;

}

err=getPCIbase0();

iobase0=iobase0&0xfffc;

//从PCI配置空间读入的与地址空间有关的数据其bit0位为1,

printf("IOBase0=%xH\n",iobase0);

//表明此空间为IO空间参与PCI总线地址译码

err=getPCIbase1();

iobase1=iobase1&0xfffc;

printf("IOBase1=%xH\n",iobase1);

err=getPCImembase1();

err=getPCImembase0();

membase0=membase0+membase1<<16;

//左移16位,将高位地址变换成双字中的高位字

printf("MEMBase0=%lxH\n",membase0);

err=getPCIIRQ();

printf("PCIIRQ=%d\n",err);

ic8255a=ic8255a+iobase1;//获取8255A、B口和控制寄存器的地址

ic8255b=ic8255b+iobase1;

ic8255type=ic8255type+iobase1;

printf("Pressetoexit:

\n");//显示提示字符

outportb(

(1));//初始化8255

outportb(ic8255a,

(2));//灭所有的段

outportb(ic8255b,(3));//灭所有的位

do//主循环

{

count1=0xff;//设置计数值

plus1();//将显示数据加1

flag1=1;//将小循环标志置位

do//小循环

{

mydisp1();//调显示子程序

count1=count1-1;//计数值减1

if(count1==0)//判断是否退出小循环

flag1=0;

}while(flag1==1);

flagm=mypckey();//扫描键盘

}while(flagm==1);

////////////////////////////////////////////////////////////////////////////

return;

}

intmypckey()//扫描键盘子程序

{

intpckey1();

intflagk,judge;

judge=pckey1();

if(judge=='e')

flagk=0;

else

flagk=1;

return(flagk);

}

intpckey1()//调用int21H中断

{

unionREGSregs;

regs.h.ah=0x6;

regs.h.dl=0x0ff;

int86(0x21,®s,®s);

return(regs.h.al);

}

voidplus1()//加1子程序

{

inti;

dis1[0]=dis1[0]+1;

for(i=0;i<=2;i++)

{

if(dis1[i]>=10)

{

dis1[i]=dis1[i]-10;

dis1[i+1]=dis1[i+1]+1;

}

else

break;

}

if(dis1[3]>=10)

dis1[3]=0;

return;

}

voidmydisp1()//显示子程序

{

voiddelay1();

inti,a1,a2=0x0fe;

for(i=0;i<=3;i++)

{

outportb(ic8255a,0x0ff);

a1=buffer1[dis1[i]];

outportb(ic8255a,a1);

outportb(ic8255b,a2);

a2=a2<<1;

a2=a2|(4);//作用是:

(5)

delay1();

}

return;

}

voiddelay1()//延时子程序

{

inti,j,a=0;

for(i=1;i<=50;i++){

for(j=1;j<=1000;j++)a=a+0;

}

return;

}

思考题:

1.本实验采用的LED数码管是共阳的还是共阴的?

7407的作用是什么?

2.8255的端口是如何初始化的?

如何实现动态显示的?

用示波器观察PB口的波形,分别画出PB0,PB1,PB2,PB3的波形。

3.Delay1()的延时时间应在什么范围内,可以使LED没有闪烁感?

4.仔细观察LED为什么不该亮的段有隐隐的闪亮?

仔细分析mydiap1()中输出数据的先后关系,如何改进可以消除上述现象?

5.分析main(),CPU的时间主要花在哪个函数上?

常用什么方法可以减少对CPU的占用时间?

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1