单片机实验报告山东大学.docx

上传人:b****3 文档编号:3888206 上传时间:2022-11-26 格式:DOCX 页数:76 大小:4.85MB
下载 相关 举报
单片机实验报告山东大学.docx_第1页
第1页 / 共76页
单片机实验报告山东大学.docx_第2页
第2页 / 共76页
单片机实验报告山东大学.docx_第3页
第3页 / 共76页
单片机实验报告山东大学.docx_第4页
第4页 / 共76页
单片机实验报告山东大学.docx_第5页
第5页 / 共76页
点击查看更多>>
下载资源
资源描述

单片机实验报告山东大学.docx

《单片机实验报告山东大学.docx》由会员分享,可在线阅读,更多相关《单片机实验报告山东大学.docx(76页珍藏版)》请在冰豆网上搜索。

单片机实验报告山东大学.docx

单片机实验报告山东大学

第三单元Proteus系统仿真实验

实验一基本并行口I/O口实验自我完成实验

1、实验要求

当按键SW1按下之后,D1-D8轮流点亮,点亮时间为100ms,当按键停下后,停止轮换,

再次按下后继续轮换。

2、编程思路

①进行初始化工作,包括设置堆栈指针SP,将P2口所有位设置为1,使P2口所接发光二

极管全部熄灭。

将显示缓冲单元(设为20H单元)初始化为FEH。

②从P1口读数据,查看P1.0位,如果P1.0位为0,则执行如下循环:

将显示缓冲单元

的值送给P2口,调用100ms延时程序,将显示缓冲单元的值循环左移1位,再送回显示缓

冲单元。

如果P1.0位不为0则不执行上述循环。

③重复上面的操作②

3、实验步骤

①根据上述实验内容,参考1.2.2,在Proteus环境下建立图3.5所示原理图,并将其保

存为basicIO_self.DSN文件。

②根据

(2)和(3)编写控制源程序,将其保存为basicIO_self.asm。

③将源程序添加到U1中,并构造(build)该程序。

④执行仿真过程观察D1-D8的指示,查看程序功能是否正确。

⑤修改延时程序延时参数,重新执行③和④。

4、源程序

ORG0000H

AJMPMAIN

ORG0030H

MAIN:

MOVSP,#60H

MOVP2,#0FFH

MOVA,#0FEH

MOV20H,A;缓冲单元

LOOP:

JNBP1.0,LOOP1;;如果P1.0=0,跳转

SJMPLOOP;否则循环不断检测

LOOP1:

MOVP2,20H;将缓冲单元内的值给P2口

LCALLDELAY100MS;延时100ms

;MOVA,20H

RLA;左移一位

MOV20H,A

JBP1.0,LOOP;如果P1.0=1,跳转到LOOP处

LJMPLOOP1;否则循环

DELAY100MS:

MOVR7,#200;1us

DL:

MOVR6,#248;1us

DJNZR6,$;248*2=496us

NOP;1us

DJNZR7,DL;2us

RET

;(496+1+1+2)*200+1=100.001ms

END

5、电路图

6、仿真结果

当按键SW1按下之后,D1-D8轮流点亮,点亮时间为100ms,当按键停下后,停止轮换,

再次按下后继续轮换。

实验二扩展并行I/O口实验自我完成实验

1、实验要求

仿真实现交通信号灯控制功能。

控制顺序为:

①南北绿灯亮,同时东西红灯亮10s;

②南北黄灯亮,同时东西红灯亮2s;

③南北红灯亮,同时东西绿灯亮10s;

④东西黄灯亮,同时南北红灯亮2s;

⑤重复①~④。

2、编程思路

①进行初始化工作,包括设置堆栈指针SP,将两个373的输出口所有位均设置为1,使所有发光二极管全部熄灭。

②分析两个373的地址:

假定所有无关地址均定义为1,那么U4的锁存地址为:

#0FE00H,U5的锁存地址为:

#0FD00H。

③分析4个状态下两个373的输出数据值:

假定“南北绿灯亮,同时东西红灯亮”为状态1,即:

Stat1;“南北黄灯亮,同时东西红灯亮”为状态2,即:

Stat2;

“南北红灯亮,同时东西绿灯亮”为状态3,即:

Stat3;

“东西黄灯亮,同时南北红灯亮”为状态4,即:

Stat4。

3、实验步骤

①根据上述实验内容,参考1.2.2,在Proteus环境下建立图3.7所示原理图,并将其保

存为expandIO_self.DSN文件。

②根据

(2)和(3)编写控制源程序,将其保存为expandIO_self.asm。

③将源程序添加到U1中,并构造(build)该程序。

④执行仿真过程观察各个方向的交通信号灯指示,查看程序功能是否正确。

4、源程序

ORG0000H

AJMPMAIN

ORG0030H

MAIN:

MOVSP,#60H

MOVA,#0FFH

MOVDPTR,#0FE00H

MOVX@DPTR,A

MOVDPTR,#0FD00H

MOVX@DPTR,A

STAT1:

MOVA,#0F3H

MOVDPTR,#0FE00H

MOVX@DPTR,A

MOVA,#0CH

MOVDPTR,#0FD00H

MOVX@DPTR,A

LCALLDELAY10S

STAT2:

MOVA,#0C3H

MOVDPTR,#0FE00H

MOVX@DPTR,A

MOVA,#0FH

MOVDPTR,#0FD00H

MOVX@DPTR,A

LCALLDELAY2S

STAT3:

MOVA,#0FCH

MOVDPTR,#0FE00H

MOVX@DPTR,A

MOVA,#03H

MOVDPTR,#0FD00H

MOVX@DPTR,A

LCALLDELAY10S

STAT4:

MOVA,#3CH

MOVDPTR,#0FE00H

MOVX@DPTR,A

MOVA,#0FH

MOVDPTR,#0FD00H

MOVX@DPTR,A

LCALLDELAY2S

LJMPSTAT1

DELAY2S:

MOVR7,#20

DL2:

MOVR6,#200

DL1:

MOVR5,#250

DJNZR5,$

DJNZR6,DL1

DJNZR7,DL2

RET

DELAY10S:

MOVR7,#100

DL3:

MOVR6,#200

DL4:

MOVR5,#250

DJNZR5,$

DJNZR6,DL4

DJNZR7,DL3

RET

END

5、电路图

6、实验结果

①南北绿灯亮,同时东西红灯亮10s;

②南北黄灯亮,同时东西红灯亮2s;

③南北红灯亮,同时东西绿灯亮10s;

④东西黄灯亮,同时南北红灯亮2s;

实验三静态LED显示实验自我完成实验

1、实验要求

图中7SEG2为十位显示数码管,7SEG1为个位显示数码管,KEY_LOAD为倒计时初

值按钮,KEY_START为倒计时启动按钮。

要求实现的功能是:

当KEY_LOAD按钮按下时加载倒计时初值(如:

10s),当按下KEY_START按钮时,开始倒计时,每过1s,计时器减1,直到减到“00”为止。

减到“00”时使P3.0引脚上的LED按10Hz频率进行闪烁,直到再次按下KEY_LOAD按钮才重新加载初值,并熄灭LED。

再次按下KEY_START按钮又一次开始倒计时,如此反复。

2、编程思路

①分析两个373的地址:

假定所有无关地址均定义为1,那么U2的锁存地址为:

#0FE00H,U3的锁存地址为:

#0FD00H。

②程序流程图:

 

3、实验步骤

①根据上述实验内容,参考1.2.2,在Proteus环境下建立图3.9所示原理图,并将其保

存为staticLED_self.DSN文件。

②根据

(2)和(3)编写控制源程序,将其保存为staticLED_self.asm。

③将源程序添加到U1中,并构造(build)该程序。

④执行仿真过程观察秒表程序功能是否正确。

4、源程序

ORG0000H

AJMPMAIN

ORG0030H

MAIN:

MOVSP,#60H;堆栈初始化

MOVR0,#0

;各位

MOVR1,#1;十位

SETBP3.0;关掉LED1

CLRF0

LOOP:

JBP1.1,LOOP2;如果P1.1=1,跳转到LOOP2,

LOOP1:

CLRF0

MOV30H,R0

MOV31H,R1;装载初值

SETBP3.0;关闭LED1

LCALLDISPLAY;显示

LOOP2:

JBP1.0,LOOP;如果P1.0=1,跳回LOOP,否则继续执行

LOOP3:

LCALLDISPLAY;刷新显示

LCALLDELAY1S;延时1s

LCALLADJUST2;调整计时器寄存器

JBF0,LOOP4

LJMPLOOP3

LOOP4:

CLRP3.0;LED闪烁程序

LCALLDELAY100MS

SETBP3.0

LCALLDELAY100MS

JBP1.1,LOOP4

LJMPLOOP1

DISPLAY:

;显示子程序

MOVA,30H

MOVDPTR,#TABLE

MOVCA,@A+DPTR

MOVDPTR,#D1ADD

MOVX@DPTR,A

MOVA,31H

MOVDPTR,#TABLE

MOVCA,@A+DPTR

MOVDPTR,#D10ADD

MOVX@DPTR,A

RET

ADJUST2:

DEC30H

MOVA,30H

CJNEA,#-1,GOTORET

MOV30H,#9

DEC31H

MOVA,31H

CJNEA,#-1,GOTORET

SETBF0

RET

GOTORET:

RET

DELAY1S:

MOVR7,#10

DL2:

MOVR6,#200

DL1:

MOVR5,#250

DJNZR5,$

DJNZR6,DL1

DJNZR7,DL2

RET

DELAY100MS:

MOVR7,#200

DL:

MOVR6,#248

DJNZR6,$

NOP

DJNZR7,DL

RET

TABLE:

DB0C0H,0f9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H

D1ADDEQU0FE00H;U3的锁存地址

D10ADDEQU0FD00H

END

5、电路图

6、仿真结果

当KEY_LOAD按钮按下时加载

倒计时初值(如:

10s),当按下KEY_START按钮时,开始倒计时,每过1s,计时器减1,

直到减到“00”为止。

减到“00”时使P3.0引脚上的LED按10Hz频率进行闪烁,直到再次

按下KEY_LOAD按钮才重新加载初值,并熄灭LED。

再次按下KEY_START按钮又一次开始倒计时,如此反复。

实验四矩阵键盘扫描实验自我完成实验

1、实验要求

D1~D8八个发光二极管构成彩色旋转灯,D9~D13为档位指示灯,一档旋转速度最慢(周期1s,D13亮),二档较快(周期0.8s,D12亮),三档更快(周期0.6s,D11亮),四档再快(周期0.4s,D10亮),五档最快(周期0.2s,D10亮)。

四个按键KEY0-KEY1于设定旋转方向为顺时针旋转或者逆时针旋转,KEY2-KEY3用于增快或则减慢旋转速度。

2、编程思路

按键扫描的方式可以采用前面示例程序中的方法:

线反转法或行扫描法。

可以用汇编语言

实现,也可以用C语言实现。

建议如前面示例所示,汇编采用行扫描法,C语言用线反法。

程序控制流程是:

首先初始化设置默认运行参数,然后读取按键,识别键码,并根据键码

的不同执行运行参数调整,最后根据当前的运行参数执行发光二极管D1-D8的轮流旋转。

速度的控制通过控制调用延时程序的次数来决定,假设延时程序的延时长度为5ms。

延时

程序可以按如下方式实现(假设晶振频率为12MHz):

voiddelays()

{

uchart,ms;

ms=5;//延时5ms

while(ms--)for(t=0;t<120;t++);

}

或者采用内嵌汇编来实现:

voiddelays()

{

#pragmaasm

MOVR2,#50//;5ms延时程序

DL1:

MOVR1,#48

DL2:

DJNZR1,DL2//;内循环100us

NOP

DJNZR2,DL1//;中循环10ms

#pragmaendasm

}

旋转彩灯线反转法C语言程序控制流程图

 

(1)主控流程图

(2)键盘扫描子程序Keyscan流程图

 

旋转彩灯行扫描法汇编控制流程图

 

3、实验步骤

①根据上述实验内容,参考1.2.2,在Proteus环境下建立图3.11所示原理图,并将其

保存为keyscan_self.DSN文件。

②根据

(2)和(3)编写控制源程序,将其保存为keyscan_self.asm或keyscan_self.c。

③将源程序添加到U1中,并构造(build)该程序。

④执行仿真过程观察秒表程序功能是否正确。

 

4、源程序

#include"reg52.h"

#include"intrins.h"

#defineucharunsignedchar

#defineuintunsignedint

sbitg0=P0^4;

ucharcodeT_TABLE[]={200,160,120,80,40};//周期值表

ucharcodekey_code[]={0x22,0x12,0x21,0x11};

voiddelay()//延时5ms

{

uchart,ms;

ms=5;

while(ms--)

for(t=0;t<120;t++);

}

voidmain()

{

intaa=0xfe;

uintdir=1;

uintspeed=0;

inttemp,temp2,keycode;

intj,key;

g0=0;

while

(1)

{

P3=0x30;

temp=P3;

if((temp&0x30)!

=0x30)//按键检测

{

delay();

delay();

P3=0x30;

temp=P3;

if((temp&0x30)!

=0x30)

{

P3=0x03;

temp2=P3;

keycode=temp|temp2;

for(j=0;j<4;j++)

{

if(keycode==key_code[j])

{

key=j;

}

}

if(key==0)dir=1;//正转

if(key==1)dir=0;//反转

if(key==2)

{

speed++;

if(speed==5)speed=4;//换档

}

if(key==3)

{

if(speed==0)speed++;//换档

speed--;

}

switch(speed)

{

case0:

P0=0xef;break;

case1:

P0=0xf7;break;

case2:

P0=0xfb;break;

case3:

P0=0xfd;break;

case4:

P0=0xfe;break;

default:

break;

}

P3=0x03;

while(!

(P3==0x03));

}

}

if(dir==1)//正转时执行

{

P1=aa;

for(j=0;j

delay();

aa=_crol_(aa,1);//左移

}

if(dir==0)//反转时执行

{

P1=aa;

for(j=0;j

delay();

aa=_cror_(aa,1);//右移

}

}

}

5、电路图:

6、仿真结果:

D1~D8八个发光二极管构成彩色旋转灯,D9~D13为档位指示灯,一档旋转速度最慢,二档较快,三档更快,四档再快,五档最快。

四个按键KEY0-KEY1于设定旋转方向为顺时针旋转或者逆时针旋转,KEY2-KEY3用于增快或则减慢旋转速度。

实验五定时器计数器实验自我完成实验

1、实验要求

用NE555构成的脉冲信号发生器,右边是用定时/计数器0和定时/计数器1构成的频率计。

为了检验频率计量是否准确,用Proteus的虚拟频率计来进行测量脉冲信号频率进行比对。

7SEG1-7SEG6用于频率计百分位、十分位、个位、十位、百位、千位的显示,

单位为Hz。

要求单片机上电运行后作为频率计将一直运行,改变脉冲发生器所产生的脉冲

频率,则频率计的显示将跟随变化。

2、编程思路

定时/计数器0工作在定时器模式方式1(16位),定时/计数器1工作在计数器模式方

式2(8位自动重装初值)。

定时/计数器1计数200个脉冲后(每计数200个脉冲产生一次中断)统计这200个脉

冲总的时间长度,计算出平均每个周期的时间长度。

200个脉冲所用时间长度的测量是靠定时/计数器0来实现的,定时/计数器0的初值为

0。

当定时/计数器1产生中断时,读出定时/计数器0当前计数器值,再加上在定时/计数器0中断中累积的值即可得到。

3、实验步骤

①根据上述实验内容,参考1.2.2,在Proteus环境下建立图3.11所示原理图,并将其保存为frequencycounter.DSN文件。

②根据

(2)和(3)编写控制源程序,将其保存为frequencycounter.c。

③运行KeiluVision2开发环境,按照1.1.3节介绍的方法建立工程

frequencycounter.uV2,CPU为AT89C51,包含启动文件STARTUP.A51。

④按照1.2.2第(6)节介绍的方法将C语言源程序frequencycounter.c加入工程

frequencycounter.uV2,并设置工程frequencycounter.uV2属性,将其晶振频率设置

为12MHz,选择输出可执行文件,仿真方式为选择硬仿真,并选择其中的“PROTEUSVSM

MONITOR51DRIVER”仿真器。

⑤构造(Build)工程frequencycounter.uV2。

如果输入有误进行修改,直至构造正确,

生成可执行程序frequencycounter.hex为止。

⑥为AT89C51设置可执行程序frequencycounter.hex。

⑦运行程序,观察数码管的显示与虚拟频率计是否一致。

⑧改变RV2的值,继续观察频率测量结果,观察数码管的显示与虚拟频率计是否一致。

 

4、源程序

#include"reg52.h"

#defineucharunsignedchar

#defineuintunsignedint

ucharcodeled_table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

ucharxdatada001_at_0xfe00;

ucharxdatada01_at_0xfd00;

ucharxdatada1_at_0xfb00;

ucharxdatada10_at_0xf700;

ucharxdatada100_at_0xef00;

ucharxdatada1k_at_0xdf00;

uchardv001,dv01,dv1,dv10,dv100,dv1k;

longsumtime=0;//总时间

floatfrequency,ptime;//分别为频率,单周期时间

uinttimer0H;

uinttimer0L;

voids_timer0()interrupt1

{

EA=0;

sumtime=sumtime+65536;

TH0=timer0H;

TL0=timer0L;

EA=1;

}

voids_timer1()interrupt3

{

EA=0;

sumtime=sumtime+TH0*256+TL0;

TH0=timer0H;

TL0=timer0L;

ptime=(float)sumtime/200;

sumtime=0;

frequency=(float)1000000/ptime;

dv1k=(uchar)(frequency/1000);

frequency=frequency-dv1k*1000;

dv100=(uchar)(frequency/100);

frequency=frequency-dv100*100;

dv10=(uchar)(frequency/10);

frequency=frequency-dv10*10;

dv1=(uchar)frequency;

frequency=frequency-dv1;

frequency=frequency*10;

dv01=(uchar)frequency;

frequency=frequency-dv01;

frequency=frequency*10;

dv001=(uchar)frequency;

da001=led_table[dv001];

da01=led_table[dv01];

da1=led_table[dv1];

da10=led_table[dv10];

da100=led_table[dv100];

da1k=led_table[dv1k];

EA=1;

}

voidmain()

{

TMOD=0X61;//T1计数器,方式2,T0定时器,方式1

timer0H=0;//T0定时器初值

timer0L=0;

TH1=TL1=56;//T1计数器初值256-200=56

EA=1;//开总中断

ET0=1;//开定时器0中断

TR0=1;//启动定时器0

ET1=1;//开启T1中断

TR1=1;//开启T1

while

(1);

}

5、电路图

6、仿真结果

频率计显示的与脉冲发生器的频率基本一致。

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

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

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

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