单片机原理及其应用基础实验(汇编版)


实验一 简单程序设计实验


一、实验目的

掌握 uVision2 IDE单片机集成开发软件的应用,熟悉单片机仿真开发环境,掌握基本的单片机软件调试方法,为后续实验做好准备。
掌握单片机内部RAM之间、内外RAM之间、外部RAM之间的数据传送操作;掌握MCS-51汇编语言程序设计方法。


二、实验内容

按以下要求自行设计程序流程图,编写、调试程序。


1、置数程序
把2000H~20FFH的内容全部置成55H。

1
2
3
4
5
6
7
8
9
10
11
12
13
	ORG 0000H
LJMP MAIN
ORG 2000H
MAIN:
MOV R1,#00H
MOV DPTR,#2000H
MOV A,#55H
LOOP:
MOVX @DPTR,A
INC DPTR
DJNZ R1,LOOP
SJMP $
END


2、拆字程序
把2000H的内容拆开,高位送2001H低位,低位送2002H低位,2001H、2002H高位清零,一般本程序用于把数据送显示缓冲区时用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	ORG 0000H
LJMP MAIN
ORG 2000H
MAIN:
MOV DPTR,#2000H
MOV A,#17H
MOVX @DPTR,A
MOV R0,A
SWAP A ;高位送2001H
ANL A,#0FH
INC DPTR
MOVX @DPTR,A
MOV A,R0 ;低位送2002H
ANL A,#0FH
INC DPTR
MOVX @DPTR,A
SJMP $
END


3、内部、外部RAM数据传送程序
(1) 内部RAM之间数据传送;
将内部RAM 40H~4FH单元内容传送到内部RAM 60H~6FH单元中。
源数据(首址存放在R2单元中);目的数据(首址存放在R4单元中);数据字节数存放在R6单元中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	ORG 0000H
LJMP MAIN
MAIN:
MOV B,#00H
MOV R0,#40H
MOV R1,#60H
MOV R6,#10H
LOOP:
MOV @R0,B
MOV A,@R0
MOV @R1,A
INC B
INC R0
INC R1
DJNZ R6,LOOP
SJMP $
END


(2) 内外RAM之间数据传送;
将内部RAM 40H~4FH单元内容传送到外部RAM 2040H~204FH单元中。
源数据(首址存放在R2单元中);目的数据(首址存放在DPTR中);数据字节数存放在R6单元中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
	ORG 0000H
LJMP MAIN
ORG 2040H
MAIN:
MOV B,#00H
MOV R0,#40H
MOV DPTR,#2040H
MOV R6,#10H
LOOP:
MOV @R0,B
MOV A,@R0
MOVX @DPTR,A
INC B
INC R0
INC DPTR
DJNZ R6,LOOP
SJMP $
END


(3) 外RAM之间数据传送;
将外部RAM 1000H~1011H单元内容传送到外部RAM 2000H~2011H单元中。
源数据(首址存放在DPTR0中);目的数据(首址存放在DPTR1中);数据字节数存放在R7单元中。对0A2H(AUXR1)单元等于0或1。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
	ORG 0000H
LJMP MAIN
ORG 2000H
MAIN:
MOV B,#00H
MOV R0,#40H
MOV DPTR,#1000H
MOV R6,#10H
LOOP:
MOV A,B
MOVX @DPTR,A
MOVX A,@DPTR
MOV @R0,A
INC B
INC R0
INC DPTR
DJNZ R6,LOOP
NEXT:
MOV R0,#40H
MOV DPTR,#2000H
MOV R6,#10H
LOOP1:
MOV A,@R0
MOVX @DPTR,A
INC R0
INC DPTR
DJNZ R6,LOOP1
SJMP $
END


三、程序源文件及仿真

链接: https://pan.baidu.com/s/184uLLi-uVDaQi7IUPfGrtg
提取码: sq9m


实验二 I/O口实验


一、实验目的

(1)学习单片机I/O口的使用方法;
(2)学习延时子程序的编写;
(3)掌握基本的单片机硬件调试方法。


二、实验预备知识

(1)P1口为准双向口,每位都可独立地定义为输入或输出,在作输入使用前,必须向口锁存器相应位写入“1”,该位才能作为输入;
(2)本实验中延时子程序采用循环来实现,定时时间=机器周期时间*程序总机器周期数(本实验提供的仿真头晶振频率为11.0592 MHz)。


三、实验内容

P1口做输出口,接八只发光二极管,编写程序,使发光二极管循环点亮。
(1)左移点亮1只发光二极管;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ORG 0000H;程序定位到地址0000H
AJMP MAIN;程序跳转到MAIN函数
ORG 0100H;程序重新定位到地址0100H
MAIN:
MOV A, #0FFH;因为51IO管脚的驱动能力较弱,一般led负端接IO管脚
MOV P1,A;8个管脚全部送高电平,LED保持全灭
MOV A,#11111110B;
LOOP:
MOV P1,A;仅亮一个LED,假设是最左边的一个LED
ACALL DELAY_1S;延时一秒钟
RL A;对累加器A的数据进行一次循环左移
AJMP LOOP;

DELAY_1S:
DEL1: MOV R5,#10;1us
DEL2: MOV R6,#200;10*1us
DEL3: MOV R7,#249;200*10*1us
DEL4: DJNZ R7,DEL4;249*200*10*2us
DJNZ R6,DEL3;200*10*2us
DJNZ R5,DEL2;10*2us
RET;2us(加起来正好1s,实在是太难凑,不知道有没有什么技巧)
END


(2)右移点亮1只发光二极管;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ORG 0000H;程序定位到地址0000H
AJMP MAIN;程序跳转到MAIN函数
ORG 0100H;程序重新定位到地址0030H
MAIN:
MOV A, #0FFH;因为51IO管脚的驱动能力较弱,一般led负端接IO管脚
MOV P1,A;8个管脚全部送高电平,LED保持全灭
MOV A,#11111110B
LOOP:
MOV P1,A;仅亮一个LED,假设是最左边的一个LED
ACALL DELAY_1S;延时一秒钟
RR A;对累加器A的数据进行一次循环左移
AJMP LOOP;

DELAY_1S:
DEL1: MOV R5,#10;1us
DEL2: MOV R6,#200;10*1us
DEL3: MOV R7,#249;200*10*1us
DEL4: DJNZ R7,DEL4;249*200*10*2us
DJNZ R6,DEL3;200*10*2us
DJNZ R5,DEL2;10*2us
RET;2us(加起来正好1s,实在是太难凑,不知道有没有什么技巧)
END


(3)左移点亮2只相邻发光二极管;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ORG 0000H;程序定位到地址0000H
AJMP MAIN;程序跳转到MAIN函数
ORG 0100H;程序重新定位到地址0030H
MAIN:
MOV A, #0FFH;因为51IO管脚的驱动能力较弱,一般led负端接IO管脚
MOV P1,A;8个管脚全部送高电平,LED保持全灭
MOV A,#11111100B;
LOOP:
MOV P1,A;仅亮一个LED,假设是最左边的一个LED
ACALL DELAY_1S;延时一秒钟
RL A;对累加器A的数据进行一次循环左移
RL A;对累加器A的数据进行一次循环左移
AJMP LOOP;

DELAY_1S:
DEL1: MOV R5,#10;1us
DEL2: MOV R6,#200;10*1us
DEL3: MOV R7,#249;200*10*1us
DEL4: DJNZ R7,DEL4;249*200*10*2us
DJNZ R6,DEL3;200*10*2us
DJNZ R5,DEL2;10*2us
RET;2us(加起来正好1s,实在是太难凑,不知道有没有什么技巧)
END


(4)右移点亮2只相邻发光二极管。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ORG 0000H;程序定位到地址0000H
AJMP MAIN;程序跳转到MAIN函数
ORG 0100H;程序重新定位到地址0030H
MAIN:
MOV A, #0FFH;因为51IO管脚的驱动能力较弱,一般led负端接IO管脚
MOV P1,A;8个管脚全部送高电平,LED保持全灭
MOV A,#11111100B;
LOOP:
MOV P1,A;仅亮一个LED,假设是最左边的一个LED
ACALL DELAY_1S;延时一秒钟
RR A;对累加器A的数据进行一次循环右移
RR A;对累加器A的数据进行一次循环右移
AJMP LOOP;

DELAY_1S:
DEL1: MOV R5,#10;1us
DEL2: MOV R6,#200;10*1us
DEL3: MOV R7,#249;200*10*1us
DEL4: DJNZ R7,DEL4;249*200*10*2us
DJNZ R6,DEL3;200*10*2us
DJNZ R5,DEL2;10*2us
RET;2us(加起来正好1s,实在是太难凑,不知道有没有什么技巧)
END


四、程序源文件及仿真

链接: https://pan.baidu.com/s/12TX9werL4YWazEwp3_4D8w
提取码: xf5a


实验三 定时器实验


一、实验目的

(1)学习单片机定时器的使用方法;
(2)掌握单片机长定时方法;
(3)掌握基本的单片机定时器调试方法。


二、实验预备知识

本实验提供的仿真头晶振频率为11.0592 MHz,定时器工作方式1下最长定时时间为65536*12 /11.0592 = 71111us,如果要求定时时间大于此值,则可采用多次定时方法来实现长定时。


三、实验内容

编写程序,使定时器按一定间隔(500 ms~1s)对内部RAM某单元的内容加1,然后用8只发光二极管显示RAM单元中的二进制数值。


四、实验思考

1、修改定时时间,改变数值显示速度;
2、设置数值变化方向控制功能,使RAM单元按定时间隔加1或减1。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/***************************定时器实验**********************************/
/***********************************************************************
定时器初值计算:
fosc=11.0592M
Tosc=1/11.0592us
T(机器周期)=12/11.0592us(也就是计数器每次加1花费的时间)
工作方式1为16位计数器
T(最长定时时间)=2^16*(12/11.0592)=71111.11us=71ms
(2^16-X)*((12/11.0592)*10^(-6))s=0.05s
--->X=19456=4C00H
--->TH0=4CH,TL0=00H
*************************************************************************
说明:
我们使用TO定时器的工作方式1,每隔50ms中断一次,中断20次,正好1s
我们使用的按键用的是外部中断1,接在P3.3
*************************************************************************
实验接线:
8个P1口的LED顺次连接
52单片机的P3.3口接到一个接地的轻触按键上
*************************************************************************
实验现象:
Proteus直接运行,也就是执行默认方式MODE0,因为我给R0的初值是00H,也就是从全亮
然后从低位慢慢开始熄灭,熄灭为1;
当按键触发后,反方向运行,可以看到慢慢恢复到原来的全亮,说明实验是成功的;
********************************预编译部分********************************/
ORG 0000H /*程序入口*/
LJMP MAIN /*跳向主程序入口MAIN*/

ORG 000BH /*程序定位到000BH,也就是TO的中断入口*/
LJMP ITOP /*转T0中断处理子程序ITOP*/

ORG 0013H ;/*外部中断1的地址*/
LJMP INT ;/*跳转到INT执行*/

ORG 1000H ;/*主程序的起始地址*/
/************************主程序部分*********************************/
MAIN:
MOV A,#00H /*累加器A我们用于判断当前是模式几,设置初值为0*/
MOV R0,#00H /*我们不妨给定R0一个中间值,便于我们观察寄存器变化*/
MOV SP,#60H /*设置堆栈指针*/
MOV B,#14H /*设循环次数为20次,应该等价于MOV B,#20*/
MOV TMOD,#01H /*设置T0工作在方式1定时*/
MOV TL0,#00H /*给T0低八位设初值*/
MOV TH0,#4CH /*给T0高八位设初值*/
SETB ET0 /*允许T0中断*/
SETB IT1 /*外部中断1上升沿触发方式*/
SETB EX1 /*外部中断1开中断*/
SETB EA /*总中断允许*/
SETB TR0 /*启动T0计数*/
/**************************循环等待*******************************/
HERE:
SJMP HERE /*原地循环等待定时器0中断发生*/
/*********************定时器中断服务子程序*************************/
ITOP:
MOV TL0,#00H /*单片机在这种工作方式下不能自动重新装载初值,所以每次进入中断要重新赋初值*/
MOV TH0,#4CH ;
DJNZ B,RETURN /*B为中断次数计数器,B减1非0则中断返回*/
MOV B,#14H
;CLR TR0 /*1s定时时间到,停止T0工作,这里不需要,因为要一直循环*/
;SETB F0 /*1s定时时间到标志F0置1,以备后用,实际上没有用到*/
MOV P1,R0 /*这样的话灭是1,亮是0*/

MODE0:
CJNE A,#00H,MODE1 /*如果A不等于FFH则跳转到模式1执行,默认为模式0,因为R0初值为0*/
INC R0 /*R0里面的内容加1*/
LJMP RETURN

MODE1:
CJNE A,#0FFH,MODE0 /*如果A不等于00H则跳转到模式0执行*/
DEC R0 /*R0里面的内容减1*/
LJMP RETURN

RETURN:
RETI /*中断返回*/

INT:
CPL A
RETI

END

五、程序源文件及仿真

链接: https://pan.baidu.com/s/1LwLKLp1GcQtBbIpJOXKxRA
提取码: 692p