程序举例.docx

上传人:b****9 文档编号:25605628 上传时间:2023-06-10 格式:DOCX 页数:17 大小:20.72KB
下载 相关 举报
程序举例.docx_第1页
第1页 / 共17页
程序举例.docx_第2页
第2页 / 共17页
程序举例.docx_第3页
第3页 / 共17页
程序举例.docx_第4页
第4页 / 共17页
程序举例.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

程序举例.docx

《程序举例.docx》由会员分享,可在线阅读,更多相关《程序举例.docx(17页珍藏版)》请在冰豆网上搜索。

程序举例.docx

程序举例

例1:

将内部RAM40~4FH的16个数据送到外部RAM2000~200FH,再将外部2000~200FH数据送到内部RAM50~5FH中。

例2:

有一变量存放在片内RAM的20H单元,其取值范围为:

00H~05H。

要求编制一段程序,根据变量值求其平方值,并存入片内RAM的21H单元。

在程序存储器的一片存储单元中建立起该变量的平方表。

用数据指针DPTR指向平方表的首址,则变量与数据指针之和的地址单元中的内容就是变量的平方值。

采用MOVCA,@A+PC指令也可以实现查表功能,且不破坏DPTR的内容,从而可以减少保护DPTR的内容所需的开销。

但表格只能存放在MOVCA,@A+PC指令后的256字节内,即表格存放的地点和空间有一定限制。

例3:

(双字节无符号数加法)设被加数存放在内部RAM的51H、50H单元,加数存放在内部RAM的61H、60H单元,相加的结果存放在内部RAM的51H、50H单元,进位存放在位寻址区的00H位中。

程序段如下:

MOVR0,#50H;被加数的低字节地址

MOVR1,#60H;加数的低字节地址

MOVA,@R0;取被加数低字节

ADDA,@R1;加上加数低字节

MOV@R0,A;保存低字节相加结果

INCR0;指向被加数高字节

INCR1;指向加数高字节

MOVA,@R0;取被加数高字节

ADDCA,@R1;加上加数高字节(带进位加)

MOV@R0,A;存高字节相加结果

MOV00H,C;保存进位。

例4:

双字节BCD数加法

例5:

将给定的一个字节二进制码转换十进制码

RESULTEQU30H

ORG00H

LJMPSTART

START:

MOVSP,#40H

MOVA,#123

LCALLBINTOBAC

SJMP$

BINTOBAC:

MOVB,#100

DIVAB;除以100得百位数

MOVRESULT,A

MOVA,B

MOVB,#10

DIVAB;余数除以10得十位数

MOVRESULT+1,A

MOVRESULT+2,B;余数为个位数

RET

END

例6:

多分支程序跳转

ORG00H

START:

MOVA,#0

CALLFUNCENTER

MOVA,#1

MOVA,#2

CALLFUNCENTER

MOVA,#3

CALLFUNCENTER

LJMP$

FUNCENTER:

ADDA,ACC;AJMP为二字节指令,地址偏移量*2

MOVDPTR,#FUNCTAB;设置基址

JMP@A+DPTR;跳转到目标地址

FUNCTAB:

AJMPFUNC0

AJMPFUNC1

AJMPFUNC2

AJMPFUNC3

FUNC0:

MOV30H,#0

RET

FUNC1:

MOV31H,#1

RET

FUNC2:

MOV32H,#2

RET

FUNC3:

MOV33H,#3

RET

END

例7:

多字节BCD取补

ORG00H

MOV30H,#12H

MOV31H,#44H

MOV32H,#89H

MOVR7,#03H;设置操作数的字节数

MOVR0,#30H;设置指针

NEG:

MOVA,R7

DECA;取字节数减1至R2中

MOVR2,A

MOVA,R0;保护指针

MOVR3,A

NEG0:

CLRC

MOVA,#99H

SUBBA,@R0;按字节十进制取补

MOV@R0,A;存回以@R0开始的连续单元

INCR0;调整数据指针

DJNZR2,NEG0

MOVA,#9AH;最低字节单独取补

SUBBA,@R0

MOV@R0,A

MOVA,R3;恢复指针

MOVR0,A

SJMP$

END

例8(无符号数排序程序)在片内RAM中,起始地址为30H的8个单元中存放有8个无符号数。

试对这些无符号数进行升序排序。

(先执行后判断)

数据排序常用的方法是冒泡排序法。

执行时从前向后进行相邻数的比较,如数据的大小次序与要求的顺序不符就将这两个数互换,否则不互换。

对于升序排序,通过这种相邻数的互换,使小数向前移动,大数向后移动。

从前向后进行一次冒泡(相邻数的互换),就会把最大的数换到最后。

再进行一次冒泡,就会把次大的数排在倒数第二的位置。

设R7为比较次数计数器,初始值为07H,位地址00H为数据互换标志位。

START:

CLR00H;互换标志清0

MOVR7,#07H;各次冒泡比较次数

MOVR0,#30H;数据区首址

LOOP:

MOVA,@R0;取前数

MOV2BH,A;暂存

INCR0

MOV2AH,@R0;取后数

CLRC

SUBBA,@R0;前数减后数

JCNEXT;前数小于后数,不互换

MOV@R0,2BH

DECR0

MOV@R0,2AH;两数交换

INCR0;准备下一次比较

SETB00H;置互换标志

NEXT:

DJNZR7,LOOP;进行下一次比较

JB00H,START;进行下一轮冒泡

SJMP$

例9:

将内部RAM中起始地址为data的数据串传送到外部RAM中起始地址为buffer的存储区域内,直到发现‘$’字符停止传送。

由于循环次数事先不知道,但循环条件可以测试到。

所以,采用先判断后执行的结构比较适宜。

(先判断后执行)

程序段如下:

MOVR0,#data

MOVDPTR,#buffer

LOOP0:

MOVA,@R0

CJNEA,#24H,LOOP1;判断是否为‘$’字符

SJMPLOOP2;是‘$’字符,转结束

LOOP1:

MOVX@DPTR,A;不是‘$’字符,执行传送

INCR0

INCDPTR

SJMPLOOP0;传送下一数据

LOOP2:

……

例10:

(利用累加器或寄存器)编写程序,实现c=a2+b2。

设a,b,c分别存于内部RAM的30H,31H,32H三个单元中。

程序段如下:

START:

MOVA,30H;取a

ACALLSQR;调用查平方表

MOVR1,A;a2暂存于R1中

MOVA,31H;取b

ACALLSQR;调用查平方表

ADDA,R1;a2+b2存于A中

MOV32H,A;存结果

SJMP$

SQR:

MOVDPTR,#TAB;子程序

MOVCA,@A+DPTR;

RET

TAB:

DB0,1,4,9,16,25,36,49,64,81

例11:

(利用存储器)将R0和R1指向的内部RAM中两个3字节无符号整数相加,结果送到由R0指向的内部RAM中。

入口时,R0和R1分别指向加数和被加数的低位字节;出口时,R0指向结果的高位字节。

低字节在高地址,高字节在低地址。

实现程序:

NADD:

MOVR7,#3;三字节加法

CLRC;

NADD1:

MOVA,@R0;取加数低字节

ADDCA,@R1;被加数低字节加A

MOV@R0,A;

DECR0

DECR1

DJNZR7,NADD1

INCR0

RET

例12:

(利用堆栈)把内部RAM中20H单元中的1个字节十六进制数转换为2位ASCII码,存放在R0指示的两个单元中。

MAIN:

MOVA,20H;

SWAPA

PUSHACC;参数入栈

ACALLHEASC

POPACC

MOV@R0,A;存高位十六进制数转换结果

INCR0;修改指针

PUSH20H;参数入栈

ACALLHEASC

POPACC

MOV@R0,A;存低位十六进制数转换结果

SJMP$

HEASC:

MOVR1,SP;借用R1为堆栈指针

DECR1

DECR1;R1指向被转换数据

XCHA,@R1;取被转换数据

ANLA,#0FH;取一位十六进制数

ADDA,#2;所加值为MOVC与DB间字节数

MOVCA,@A+PC;查表

XCHA,@R1;1字节指令,存结果于堆栈

RET;1字节指令

ASCTAB:

DB30H,31H,32H,33H,34H,35H,36H,37H

DB38H,39H,41H,42H,43H,44H,45H,46H

例13:

做单一的左移/右移,八个二极管接在P1端口上。

输出”0“时,发光二极管亮。

先从P1.0到P1.7,然后从P1.7到P1.0。

ORG00H

START:

MOVA,#0FEH;设置输出初值

SETBC;进位标志置1

S1:

MOVP1,A;输出A值

LCALLDELAY

RLCA;A带进位右移

JCS1;若移位次数达到8次,重设输出初值

MOVA,#7FH

SETBC

S2:

MOVP1,A;将新的A值输出

LCALLDELAY

RRCA

JCS2

LJMPSTART

DELAY:

MOVR5,#20;延时子程序

D1:

MOVR6,#20

D2:

MOVR7,#248

DJNZR7,$

DJNZR6,D2

DJNZR5,D1

RET

END

例14:

AT89C51单片机的P1.0到P1.3端口接四个发光二极管D1到D4,P1.4到P1.7端口接了四个开关,编程将开关的状态反映到发光二极管上.(每个开关相对应不同的发光二极管)

ORG00H

START:

MOVA,P1;读取P1口数据

SWAPA;交换A中高四位与低四位的位置

ORLA,#0F0H;与0F0H进行或运算

MOVP1,A;将开关状态送LED显示

SJMPSTART

END

例15:

AT89C51单片机的P3.2/INT0引脚接一个开关,模拟外部中断源,编写程序,当外部中断发生时,对其作出响应(以发光二极管的灯的状态来显示)

LEDBITP1.0

LEDBUFEQU30H

ORG00H

LJMPSTART

ORG03H;外部中断入口

LJMPINTERRUPT

START:

CLRLEDBUF

CLRLED

MOVTCON,#01H;外部中断0下降沿触发

MOVIE,#81H;打开外部中断允许围(EX0)及总中断允许位(EA)

LJMP$;等待中断

INTERRUPT:

PUSHPSW;保护现场

CPLLEDBUF;取反LED

MOVC,LEDBUF

MOVLED,C

POPPSW;恢复现场

RETI

END

例16:

定时/计数器可以用来实现定时,计数,频率测量,脉冲宽度测量,产生信号,等。

用AT89C51单片机定时/计数器0的定时功能可构成一简单的方波发生器,实现周期为400us的方波输出。

若改变定时/计数器0的初值可得到不同周期的方波输出。

ORG00H

SJMPSTAR

ORG0BH

SJMPT0F

STAR:

MOVTMOD,#0;T0工作方式0

MOVP3,#03FH

MOVTH0,#0F9H;赋初值高位

MOVTL0,#18H;赋初值低位

MOVIE,#0FFH;中断允许设置

SETBTR0;启动T0

SJMP$

T0F:

CPLP3.5;输出信号取反

CPLP3.7

MOVTH0,#0F9H;重装初值

MOVTL0,#18H

CPLP3.0

RETI

END

例17:

AT89C51的定时/计数器T0产生2s的定时。

每当2s定时到来时,更换指示灯闪亮。

每个指示灯闪亮时间位0.2s。

如此的循环下去。

0.2s的闪亮时间也由定时/计数器T0来完成。

COUNTEQU30H

FLASHEQU31H

ORG00H

SJMPSTART

ORG0BH;定时器0中断入口

LJMPINT_T0

START:

MOVCOUNT,#00H

MOVFLASH,#00H

MOVTMOD,#01H;定时器工作方式1

MOVTH0,#(65536-50000)/256;定时器初值

MOVTL0,#(65536-50000)MOD256

MOVIE,#82H;开中断

SETBTR0;启动定时器

SJMP$;等待中断

INT_T0:

MOVA,COUNT

CJNEA,#00H,I1;D1闪亮

CPLP1.0

INCFLASH

MOVA,FLASH

CJNEA,#40,RETUNE;达到2s?

MOVFLASH,#00H

INCCOUNT

LJMPRETUNE;D2闪亮

I1:

CJNEA,#01H,I2

CPLP1.1

INCFLASH

MOVA,FLASH

CJNEA,#40,RETUNE;达到2s?

MOVFLASH,#00H

INCCOUNT

LJMPRETUNE

I2:

CJNEA,#02H,I3;D3闪亮

CPLP1.2

INCFLASH

MOVA,FLASH

CJNEA,#40,RETUNE;达到2s?

MOVFLASH,#00H

INCCOUNT

LJMPRETUNE

I3:

;D4闪亮

CJNEA,#03H,RETUNE

CPLP1.3

INCFLASH

MOVA,FLASH

CJNEA,#40,RETUNE;达到2秒?

MOVFLASH,#00H

MOVCOUNT,#00H

LJMPRETUNE

RETUNE:

MOVTH0,#(65536-50000)/256

MOVTL0,#(65536-50000)MOD256

RETI

END

例18:

P2口接动态数码管的字形码笔端,P3.2和P3.3接动态数码管的数位选择端,P3.7接一个开关,编写程序,使得开关接低电平时,在两位数码管上滚动显示'12345'字样,开关接低电平时,在两位数码管滚动显示“HELLO”字样。

KEYBITP3.7;按键位

HBBITP3.2;数码管高位

LBBITP3.3;数码管低位

FLAGBIT00H:

;标志位

ORG00H

START:

JBKEY,S1;判断按键是高电平还是低电平

MOVDPTR,#TABLE1;如果是低电平,为'12345‘显示码首地址

CLRFLAG

LJMPS2

S1:

MOVDPTR,#TABLE2;如果是高电平,为“HELLO"显示码首地址

SETBFLAG

S2:

MOVR0,#00H;数码管偏移地址高位显示码

MOVR1,#01H;数码管偏移地址低位显示码

K1:

MOVR7,#100;延时常数

L1:

SETBLB

CLRHB

MOVA,R0

MOVCA,@A+DPTR;查高位段码

MOVP2,A

LCALLDELAY;数码管高位显示

SETBHB

CLRlB

MOVA,R1

MOVCA,@A+DPTR;查低位段码

MOVP2,A

LCALLDELAY;数码管低位显示

DJNZR7,L1

JBFLAG,J1;扫描一次后,判断按键电平是否变化

JBKEY,START

LJMPJ2

J1:

JNBKEY,START

J2:

INCR0

INCR1

CJNER0,#06H,K1;判断是否循环完一次

LJMPSTART

DELAY:

MOVR5,#5;延时

D1:

MOVR6,#250

DJNZR6,$

DJNZR5,D1

RET

TABLE1:

DB00H,06H,5BH,4FH,66H,6DH,00H

TABLE2:

DB00H,76H,79H,38H,38H,3FH,00H

END

例19:

采用74LS164驱动七段数码管,单片机串行移位的输出作为74LS164的输入,74LS164的输出作为段码驱动7段数码管。

编写程序,在2位独立的数码管上显示“51"字样。

DBUF0EQU30H;存储区首地址

TEMPEQU40H

DINBIT0B0H;串行口输出

CLKBIT0B1H;时钟输出口

ORG00H

MOV30H,#1H

MOV31H,#5H

DISP:

MOVR0,#DBUF0;存入显示数据

MOVR1,#TEMP

MOVR2,#2

DP10:

MOVDPTR,#SEGTAB;表头地址

MOVA,@R0

MOVCA,@A+DPTR;查表指令

MOV@R1,A

INCR1

INCR0

DJNZR2,DP10

MOVR0,#TEMP;段码地址指针

MOVR1,#2;段码字节数

DP12:

;输出子程序

MOVR2,#8

MOVA,@R0;取段码

DP13:

RLCA;段码左移

MOVDIN,C;输出一位段码

CLRCLK;发送移位脉冲

SETBCLK

DJNZR2,DP13

INCR0

DJNZR1,DP12

SJMP$

SEGTAB:

DB3FH,06H,5BH,4FH,66H;0,1,2,3,4

DB6DH,7DH,07H,7FH,6FH;5,6,7,8,9

DELAY:

;延时子程序

MOVR4,#03H

AA1:

MOVR5,#0FFH

AA:

DJNZR5,AA

DJNZR4,AA1

RET

END

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

当前位置:首页 > 医药卫生 > 中医中药

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

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