310 likes | 460 Views
一. 顺序程序. 顺序程序是指按顺序依次执行的程序,顺序程序结构虽然比较简单,但它是构成复杂程序的基础。. CONT: MOV A,R0 ; 读低8位 CPL A ; 取反 ADD A,#1 ; 加1 MOV R2,A ; 存低8位 MOV A,R1 ; 读高8位 CPL A ; 取反 ADDC A,#80H ; 加进位及符号位 MOV R3,A ; 存高8位 RET ;. 注意;这里不能用 INC 指令,因为 INC 指令不影响标志 位。.
E N D
一. 顺序程序 顺序程序是指按顺序依次执行的程序,顺序程序结构虽然比较简单,但它是构成复杂程序的基础。
CONT: MOV A,R0 ;读低8位 CPL A ;取反 ADD A,#1 ;加1 MOV R2,A ;存低8位 MOV A,R1 ;读高8位 CPL A ;取反 ADDC A,#80H ;加进位及符号位 MOV R3,A ;存高8位 RET ; 注意;这里不能用INC指令,因为INC指令不影响标志位。
【例4-3】 :将R2中BCD码数转为二进制数存进R2。 方法:将十位取出,乘10,加上个位(设R2中存放的数是19) ORG 2000H BCD2:MOV A, R2 ;取入口数据 ANL A, #0F0H ;取出十位 SWAP A ;高4位 低4位 MOV B, #0AH
MUL AB ;十位乘10(A)=0AH MOV R3,A ;积暂存进R3 MOV A, R2 ;再取入口数据 ANL A, #0FH ;取出个位 ADD A, R3 ;(A)=12H MOV R2,A ;结果R2 END ;
二.分支程序 根据不同条件转向不同的处理程序,这种结构的程序称为分支程序。 80C51指令系统中的条件转移指令、比较转移指令和位转移指令,可以实现分支程序。
【例4-4】 已知X、Y均为8位二进制有符号数,分别存在30H,31H中,试编制能实现下列符号函数的程序:
【例4-5】将ASCII码转换为十六进制数。设ASCII码放在累加器A中,转换结果放到B中。【例4-5】将ASCII码转换为十六进制数。设ASCII码放在累加器A中,转换结果放到B中。 解: 0~9的ASCII码30H~39H为,将ASCII码减30H(0~9)。 A~F的ASCII码41H~46H为,37H(A~F)就可获得对应的十六进制数。
散转程序是一种并行多分支程序。 见前面学过的内容:按0、1、2、3发生三角波、方波、锯齿波、正弦波。
三. 循环程序 循环程序一般包括以下几个部分: ⑴ 循环初值; ⑵ 循环体; ⑶ 循环修改; ⑷ 循环控制; 以上四部分可以有两种组织形式,其结构如图4-6所示。
【例4-10】设Xi均为单字节数,并按顺序存放在以50H为首地址的内RAM存储单元中,数据长度(个数)N存在R2中,试编程求和S=X1+X2+‥‥+XN,并将S(双字节)存放在R3R4中,(设S<65536)。【例4-10】设Xi均为单字节数,并按顺序存放在以50H为首地址的内RAM存储单元中,数据长度(个数)N存在R2中,试编程求和S=X1+X2+‥‥+XN,并将S(双字节)存放在R3R4中,(设S<65536)。 R0-----放置数据的首地址 R2----放置数据的长度 R3----放置数据和的低8位 R4----放置数据和的高8位
解:程序如下: SXN: MOV R2,#N ;置数据长度(循环次数) MOV R4,#00H ;和单元(高8位)清0 MOV R3,#00H ;和单元(低8位)清0 MOV R0,#50H ;求和数据区首址 LOOP:MOV A,R3 ;读入前次的第8位的和 ADD A,@R0 ;低8位累加 MOV R3,A ;存低8位和 CLR A ; ADDC A,R4 ;高8位加进位 MOV R4,A ;存高8位和 INC R0 ;指向下一数据,循环修改 DJNZ R2,LOOP ;判N个数据累加完否? 循环控制 RET ;退出循环 置循环初值 循环体
【例4.11】 设在内RAM 40H开始的存储区有若干个字符和数,已知最后一个为字符“$”(并且只有惟一一个),试统计这些字符和数字的个数,统计结果存人30H单元。 解:程序如下:
【例4-12】 内部RAM 20H单元开始存有8个数,试找出其中最大的数,送入MAX单元。 方法:比较和交换 操作; ①先取第一个数和第二个数进行比较,且将前一个数作为基准; ②如果前一个数大则不作交换,再取下一个数作比较; ③如果后一个数大则用较大的数来代替原来的基准数,再拿基准数和下一个数进行比较 ; ④ 基准数中总是存着最大值。
编写无符号数排序程序: 【例4-13】 假设在内部RAM中,起始地址为40H的10个单元中存放有 十个无符号数。试进行升序排序 ①冒泡法:从前向后进行相邻数据的比较,如数据的大小次序与要求的顺序不符就将这两个数据进行互换否则不互换。 ②对升序排列:从前到后进行一次置换就可以将最大的数值找到!以次类推 --。
试用冒泡法升序排列各数: 78,81,18,13,84,83 ,16 第一轮 78,18,13,81,83,16,84 (7个数比较6次) 第二轮 18,13,78,81,16,83,84 (7个数比较5次即可) 第三轮 13,18,78,16,81,83,84 (7个数比较4次即可) 第四轮 13,18,16,78,81,83,84 (7个数比较4次即可) R7--作比较次数计数器,其初始值为09H, F0--作为互换标志位,只要某轮有一次交换该位置一。 N个数最多需要N-1轮, 用标志位来标识! 比较次数最多为N-1次;
程序如下: ORG 0400H START: MOV R0,#40H;起始地址 MOV R7,#09H;每轮比较9次 CLR F0;清零标志位 LOOP: MOV A,@R0;取前一个数 MOV 2AH,A;暂存前数 INC R0;准备后一个数的地址 MOV 2BH,@R0;暂存后数 CLR C ;清零CY
SUBB A,@R0 ;两个数进行比较 JC NEXT ;前数小 ,则跳转 MOV @R0,2AH ;前数大则将此数后移 DEC R0 ;准备前数的地址 MOV @R0,2BH ;将后数前移 INC R0 ;恢复后数的地址 SETB F0 ;作完交换置标志位 NEXT:DJNZ R7 ,LOOP;判断每轮的比较次数 JB F0,START ;是否进行下一轮 END
【例4-14】编写延时10ms子程序,fosc=12MHz。fosc=12MHz,一个机器周期为1s。【例4-14】编写延时10ms子程序,fosc=12MHz。fosc=12MHz,一个机器周期为1s。 说明:MOV Rn指令为1个机器周期; DJNZ指令为2个机器周期; RET指令为2个机器周期;
DY10ms: MOV R6,#20 ; 置外循环次数 DLP1: MOV R7,#250 ; 置内循环次数 DLP2: DJNZ R7,DLP2 ; 2机周×250 =500机周 DJNZ R6,DLP1 ; 500机周×20= 10000机周 RET ;2个机器周期 {[(2机周×250)+1+2]×20+1+2}×1s/机周=10063s≈10ms
【例4.15】 :软件循环延时100mS(晶振12MHz) ☆ 1个机器周期 =1uS 100mS = 100000 uS ☆ MOV Rn #data 和 NOP 是单机器周期指令 ☆ DJNZ Rn,rel 是双机器周期指令 ☆ 200 = 0C8H ;248 = 0F8H ORG 1000H DELAY:MOV R6,#200 ; 1Tm LOOP1: MOV R7,#248 ; 1Tm NOP ; 1Tm LOOP2: DJNZ R7,LOOP2 ; 2Tm DJNZ R6,LOOP1 ; 2Tm RET ; 2Tm 1+1+ 248x2 =498 (498+2)x200
【例4.16】 :软件循环延时1S(晶振12MHz) ☆ 机器周期 =1uS 1S = 1000000 uS ☆ MOV Rn #data 是单机器周期指令 ☆ DJNZ Rn,rel 是双机器周期指令 ORG 1000H DL1S:MOV R7,#10 DL1:MOV R6,#200 DL2:MOV R5, #250DL3:DJNZ R5, DL3 DJNZ R6,DL2 DJNZ R7,DL1 RET 1+[(1+250x2+2) x200+2]x10= 1+ [(1+250x2) +2)]x200 1+ 250x2
【例4.17】 编制一个循环闪烁灯的程序。 设80C51单片机的P1口作为输出口,经驱动电路74LS240(8反相三态缓冲/驱动器)接8只发光二极管,如图4-8所示。当输出位为“1”时,发光二极管点亮,输出位为“0”时为暗。试编程实现:每个灯闪烁点亮10次,再转移到下一个灯闪烁点亮10次,循环不止。
解:程序如下: FLASH:MOV A,#01H ;置灯亮初值 FSH0: MOV R2,#0AH ;置闪烁次数 FLOP: MOV P1,A ;点亮 LCALL DY1s ;延时1s MOV P1,#00H ;熄灭 LCALL DY1s ;延时1s DJNZ R2,FLOP ;闪烁10次 RL A ;左移一位 SJMP FSH0 ;循环 RET ; 延时子程序可根据延时长短,自行编写。
【课堂练习题】 根据图4-8电路,设计灯亮移位程序,要求8只发光二极管每次点亮一个,点亮时间为250ms,顺序是从下到上一个一个地循环点亮。设fosc=12MHz。
【课堂练习题】 已知某单片机系统每隔20ms测一次温度,8位温度A/D值存在特殊功能寄存器SBUF中,试分别求其1s和1分内的平均值, 分别存30H和31H。