单片机原理与接口技术实验指导书Word文档格式.docx

上传人:b****6 文档编号:21384215 上传时间:2023-01-30 格式:DOCX 页数:41 大小:314.39KB
下载 相关 举报
单片机原理与接口技术实验指导书Word文档格式.docx_第1页
第1页 / 共41页
单片机原理与接口技术实验指导书Word文档格式.docx_第2页
第2页 / 共41页
单片机原理与接口技术实验指导书Word文档格式.docx_第3页
第3页 / 共41页
单片机原理与接口技术实验指导书Word文档格式.docx_第4页
第4页 / 共41页
单片机原理与接口技术实验指导书Word文档格式.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

单片机原理与接口技术实验指导书Word文档格式.docx

《单片机原理与接口技术实验指导书Word文档格式.docx》由会员分享,可在线阅读,更多相关《单片机原理与接口技术实验指导书Word文档格式.docx(41页珍藏版)》请在冰豆网上搜索。

单片机原理与接口技术实验指导书Word文档格式.docx

第二步,点击[OpenFile]按钮,打开编译生成的BIN文件或HEX文件。

第三步,选择串口,设置波特率。

如:

COM1,115200。

第四步,可按默认值不用设置。

第五步,下载程序。

在进行第五步之前,一定要保持实验板的串行通信线及电源线与PC机连接良好,并且实验板的电源开关处于关闭状态,然后,点击[下载]按钮,再打开实验板电源开关,此时,软件将自动完成程序下载,下载完毕,实验板上的单片机立即开始运行。

目前,MCS51内核单片机中STC89C5X(宏晶)和AT89S5X(ATMEL)两种芯片支持在线下载功能。

实验一LED流水灯

一、实验目的

1.学习单片机并口的使用方法。

2.学习延时子程序的编写和使用。

3.学习集成开发环境MedWin的安装与使用。

4.学习STC单片机在线下载软件STC-ISP的使用。

二、实验内容

所谓流水灯就是8个发光二极管(LED)轮流点亮,周而复始。

实验板上以P0口作输出口,经74LS244驱动,接8只发光二极管LED0-LED7。

当单片机的引脚输出为低电平时发光二极管点亮,为高电平时息灭。

编写程序,使8个发光二极管循环点亮,时间间隔约0.5秒。

三、实验电路连线

实验板上与本实验有关的硬件如下图所示。

74LS244驱动输出串联8个限流电阻接8个LED发光管,以防止其电流过大而烧坏。

单片机的主时钟为11.0592MHz。

JMP0和JMP1都短接1-2脚。

四、实验说明

1、P0口作为通用接口时是一准双向口,它作为输出口时与一般的双向口使用方法相同。

由准双向口结构可知当P0口用作输入口时必须先对它置“1”。

若不先对它置“1”,读入的数据是不正确的。

输出时需要接上拉电阻,P0口内部没有上拉电阻,若将外围电路设计为低有效,高无效,则无需再外接上拉电阻。

2、编写一个软件延时子程序,延时时间约0.5秒,采用三重循环实现,汇编语言程序如下:

DELAY:

MOVR7,#198

DEL1:

MOVR6,#50

DEL2:

MOVR5,#23

DJNZR5,$

DJNZR6,DEL2

DJNZR7,DEL1

RET

查指令表可知执行MOV指令需用1个机器周期,DJNZ指令需用2个机器周期,在11.0592MHz晶振时,一个机器周期时间长度为1.085μs,所以该段程序执行时间为:

[1+(1+2×

23)×

50]×

198×

1.085μs≈500mS

3、若使用C语言,可用for循环实现延时,下面的程序延时约500mS。

voiddelay(void)

{inti,j;

for(i=0;

i<

1000;

i++)

for(j=0;

j<

50;

j++)

{_nop_();

_nop_();

}

4、流水灯的主程序(汇编语言)为:

ORG0000H

LJMPMAIN

ORG0100H

MAIN:

CLRP1.5;

P1.5=0,关闭蜂鸣器。

MOVA,#0FEH

LOP:

MOVP0,A

LCALLDELAY

RLA

SJMPLOP

END

5、流水灯的C语言主程序为:

#include<

reg51.h>

stdio.h>

intrins.h>

voidmain(void)

{unsignedchara,c;

P1=0xdf;

//P1.5=0,关闭蜂鸣器。

a=0xfe;

while

(1)

{P0=a;

c=a&

0x80;

a=a<

<

1;

a=a|(c==0x80);

delay();

}

五、思考题

1.如何使点亮的LED从右往左移动?

2.如何使点亮的LED从两边往中间移动?

3.学习LED数码管的驱动、编码。

实验板上有8个LED数码管,编写程序,使最右边的一个LED数码管循环显示0~9十个数字。

时间间隔约0.5秒,其余LED数码管关闭。

8个共阳的LED数码管(S0-S7)上同名的引脚连接在一起,由单片机P0口通过74HC244驱动(段控制),R12-R19为限流电阻。

单片机P2口的8个引脚分别通过三极管Q0-Q7控制8个LED数码管的公共端(位控制)。

JMP0短接2-3脚,JMP1短接1-2脚。

1、P0口和P2都是准双向口,输出时需要接上拉电阻。

P0内部没有上拉电阻,P2口内部有弱上拉。

2、下表为驱动LED数码管的段代码表,1--代表对应的笔段亮,0--代表对应的笔段不亮。

若需要在最右边(S0)显示数字“5”,只要将从表中查得的段代码2CH写入P0口,再将P2.0置高,P2.1-P2.7置低即可。

数字

d

p

e

c

g

b

f

a

十六进制

P0.7

P0.6

P0.5

P0.4

P0.3

P0.2

P0.1

P0.0

共阴

共阳

1

B7

48

14

EB

2

AD

52

3

9D

62

4

1E

E1

5

9B

64

6

BB

44

7

15

EA

8

BF

40

9

9F

60

3、实现最右边的一个LED数码管循环显示0~9十个数字的C语言程序如下:

#defineucharunsignedchar

constucharcodetab[]={0x48,0xeb,0x52,0x62,0xe1,0x64,0x44,0xea,0x40,0x60};

voidmain(void)

{uchari;

P2=0x01;

while

(1)

{P0=tab[i];

i++;

if(i==10)i=0;

4、实现最右边的一个LED数码管循环显示0~9十个数字的汇编语言程序如下:

ORG0000H

ORG0100H

MOVP1,#0DFH

MOVP2,#01H

MOVR1,#00H

LOOP:

MOVA,R1

MOVDPTR,#TAB

MOVCA,@A+DPTR

MOVP0,A

INCR1

MOVA,R1

CJNEA,#10,LOOP

CLRA

MOVR1,A

SJMPLOOP

MOVR7,#198

MOVR6,#50

MOVR5,#23

DJNZR5,$

DJNZR6,DEL2

DJNZR7,DEL1

RET

TAB:

DB48H,0EBH,52H,62H,0E1H,64H,44H,0EAH,40H,60H

END

1.分别写出

六个字母(用于显示十六进制数)的段代码,编写程序,在最右边数码管上实现0-F的循环显示。

2.能否交替点亮点8个LED数码管?

1.学习LED数码管的动态驱动编程。

2.学习使用定时/计数器、中断。

3.学习汇编语言的有关运算。

编写程序,使实验板上的8个LED数码管稳定显示8个不同的数字,并使这四位数从00000000开始,每0.5秒钟加1。

本实验有关的硬件见实验二。

1.在实验二中,我们已经能够让某一个LED数码管显示需要的数字,比如选让第一个LED显示“1”,隔一较短的时间(如2.5毫秒)后关闭第一个LED,让第二个LED显示“2”,如此周而复始,让8个LED依次显1、2、3、4、5、6、7、8,我们就能看到8个LED上稳定地显示8个不同的数字。

当然,每个瞬间只有一个LED被点亮,大家亮的时间相同,均为2.5毫秒,8个LED数码管点亮一遍需要20毫秒,一秒钟各亮50次,所以看上去不会有闪烁感,但亮度只是实验二中LED亮度的八分之一。

要实现每隔再隔2.5毫秒变换一个LED,最好的方法是使用定时器中断。

2.汇编语言参考程序为:

LED_PORTEQUP0;

笔划输出,低有效

SCN_PORTEQUP2;

段扫描输出,低有效(P2.4-P2.7)

DSEG

ORG10H

DISP_BUF:

DS8;

显示缓冲区

SCN_INX:

DS1;

扫描指针

SCN_COD:

扫描码

CNT:

中断计数,每2.5ms加1

CSEG

ORG00H

LJMPMAIN;

主程序入口,转初始化程序

ORG0BH;

定时中断0入口

LJMPINTP0;

每2.5ms中断一次,用于刷新显示

;

-----------初------始-----化---------------------------------

ORG30H

MOVSP,#50H;

初始化堆栈指针

CLRRS0;

选用第0组通用寄存器

CLRRS1

CLRP1.5

MOVCNT,A

MOVR1,#8

MOVR0,#DISP_BUF

LOOP1:

MOV@R0,A;

显示缓冲区清零

INCR0

DJNZR1,LOOP1

MOVSCN_INX,A;

扫描指针置0

MOVSCN_COD,#80H;

右边LED先点亮

MOVTMOD,#01H;

定时器0,方式1

MOVTH0,#0F7H;

计数初值,每次2.5ms(11.0592MHz晶振)

MOVTL0,#000H;

65536-(2.5ms/1.085us)=65536-2304=63232=0F700H

SETBTR0;

启动定时器0

SETBEA;

中断总允许

SETBET0;

允许定时器0中断

SJMP$;

主程序在此循环

-----------定时器0中断服务程序,间隔2.5ms--------------

INTP0:

PUSHACC

PUSHPSW

置计数初值

MOVTL0,#00H

SETBRS0;

选用第1组通用寄存器

MOVA,SCN_INX;

取扫描指针

ANLA,#07H;

清除高5位

ADDA,#DISP_BUF;

加显示缓冲区首地址

MOVA,@R1

MOVDPTR,#CODE_TAB;

DPTR指向笔划代码表

ANLA,#0FH

MOVCA,@A+DPTR;

取笔划代码

MOVLED_PORT,A;

笔划代码送LED口

MOVA,SCN_COD;

取扫描段代码

MOVP2,A

MOVA,SCN_COD

RRA;

扫描段代码循环右移一位

MOVSCN_COD,A

INCSCN_INX;

扫描指针+1

INCCNT

MOVA,CNT

CJNEA,#200,EN

MOVCNT,#0

INCDISP_BUF+7;

个位加一

MOVA,DISP_BUF+7

CJNEA,#10,EN;

不进位转移

MOVDISP_BUF+7,#0;

进位则个位清零

INCDISP_BUF+6;

十位加一

MOVA,DISP_BUF+6

CJNEA,#10,EN

MOVDISP_BUF+6,#0;

进位则十位清零

INCDISP_BUF+5;

百位加一

MOVA,DISP_BUF+5

MOVDISP_BUF+5,#0;

进位则百位清零

INCDISP_BUF+4;

千位加一

MOVA,DISP_BUF+4

MOVDISP_BUF+4,#0;

进位则千位清零

INCDISP_BUF+3;

万位加一

MOVA,DISP_BUF+3

MOVDISP_BUF+3,#0;

进位则万位清零

INCDISP_BUF+2;

十万位加一

MOVA,DISP_BUF+2

MOVDISP_BUF+2,#0;

进位则十万位清零

INCDISP_BUF+1;

百万位加一

MOVA,DISP_BUF+1

MOVDISP_BUF+1,#0;

进位则百万位清零

INCDISP_BUF+0;

千万位加一

MOVA,DISP_BUF+0

MOVDISP_BUF+0,#0;

进位则千万位清零

EN:

POPPSW

POPACC

RETI

----------笔划代码表-------------------------

CODE_TAB:

3.C语言参考程序为:

constucharcodetab1[]={0x48,0xeb,0x52,0x62,0xe1,0x64,0x44,0xea,0x40,0x60};

constucharcodetab2[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};

ucharbuf[8]={0,0,0,0,0,0,0,0};

//显示缓冲区,开机先显示"

00000000"

voidmain(void)

{P1=0xdf;

EA=1;

//允许中断

TMOD=0x01;

//设定时器0为模式1(16位)

ET0=1;

//定时器0中断允许

TH0=0xf7;

//晶振11.0592MHz,2.5ms

TL0=0;

TR0=1;

//开始计数

while

(1);

//死循环,等待中断

}

voidtimeint(void)interrupt1//定时器0中断服务程序

{staticuchark,count;

chari;

//设置定时器时间常数

k++;

k&

=0x07;

P0=tab1[buf[k]];

//笔划代码送P0口

P2=tab2[k];

//控制扫描码送P2口

if(++count==200)//计数200次为2.5msX200=0.5s

{count=0;

//到0.5秒钟,显示的数字加一

for(i=7;

i>

=0;

i--)

{buf[i]++;

if(buf[i]==10)buf[i]=0;

//加到10向前进位

elsebreak;

}

如何让8个LED数码管从00-00-00开始,每秒钟自动加1,前两位代表时,中间两位代表分,后两位代表秒?

(1)进一步熟悉89C51定时器/计数器的功能及应用;

(2)掌握其初始化与中断服务程序的编程方法;

(3)掌握用定时器/计数器发出不同音调的编程方法。

用单片机的定时器/计数器0作定时器使用,工作于模式1,中断产生方波发声,根据各个的频率,计算对应的定时时间常数,定时器中断后按此常数赋初值,从而发出对应的音调。

将歌曲的音调和节拍编成一个表,用音调作为定时器的初值,用节拍控制发音时间,就可以实现自动演奏。

本实验有关的硬件如右图所示。

声单定时初值常数计算方法:

根据下表的音阶频率,计算对应的音阶周期T,用T/2计算定时周期数(晶振11.0592MHz),填入下表中。

定时器的计数初值为65536-定时周期数,在程序计算产生。

定时周期数增加1倍,音阶降低八度,定时周期数降低1倍,音阶升高八度。

音阶(C调)

频率(Hz)

256

288

320

341

384

427

480

周期(μs)

3906

3472

3125

2932

2604

2342

2083

定时周期数

3600

3200

2880

2702

2400

2158

1920

 自动演奏《东方红》乐曲的C语言程序为:

REG51.h>

#defineuintunsignedint

sbitP15=P1^5;

codeuintcyc[]={3600,3200,2880,2702,2400,2158,1920};

//音阶1-7对应的计数周期数

codeuchartone[]={15,15,16,12,11,11,06,12,15,15,16,21,16,15,11,11,

06,12,15,12,11,7,6,5,15,12,13,12,11,11,6,12,

13,12,11,12,11,7,6,5,0};

//乐曲《东方红》的简谱表

codeuchartime[]={8,4,4,16,8,4,4,16,8,8,4,4,4,4,8,4,

4,16,8,8,8,4,4,8,8,8,4,4,8,4,4,4,

4,4,4,4,4,4,4,16,0};

//节拍表(8为1拍,约570mS)

ucharH0,L0,cnt;

voidcntint0(void)interrupt1//定时器0中断用于产生音调

{TH0=H0;

TL0=L0;

P15=~P15;

//P1.5是音乐信号输出脚

voidcntint1(void)interrupt3//定时器1中断用于产生节拍

{cnt++;

/

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

当前位置:首页 > 高等教育 > 理学

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

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