《单片机程序设计(经典实用)》由会员分享,可在线阅读,更多相关《单片机程序设计(经典实用)(48页珍藏版)》请在金锄头文库上搜索。
1、汇编语言设计,顺序结构 分支结构 循环结构,单片机程序设计,3.1汇编语言程序设计方法,汇编语言程序设计同高级语言程序设计一样,是有章可循 的,只要按照一定的方法步骤去做,程序设计就会变成一 件轻松愉快的事情,设计的程序也会规范、清晰、易读、 易懂。使用汇编语言设计程序大致上可分为以下几个步骤。 1. 分析题意,明确要求。 2. 确定算法。 3. 画程序流程图。 4. 分配内存工作单元。 5. 编写源程序。 6. 程序优化。 7. 上机调试。,单片机程序设计,3.2 顺序程序设计,【例】程序初始化。初始化就是为变量、寄存器、存储单元 赋一初值,是最简单、最常用的操作。如将R0-R3,P1, 3
2、0H,40H单元初始化为00H,把R4,R5初始化为0FFH。 参考程序如下: ORG 0000H ;PC起始地址 LJMP START;转主程序 ORG 0100H;主程序起始地址 START:MOV R0,#00H ;初始化 MOV R1,#00H MOV R2,#00H MOV R3,#00H MOV P1,#00H,单片机程序设计,MOV R4,#0FFH MOV R5,#0FFH MOV 30H,#00H MOV 40H,#00H HERE:SJMP HERE;反复执行该指令,相当于等待 END 用立即数比较直观,但用MOV A,#00H ,MOV R0, A 指 令赋值,效果更好。
3、,单片机程序设计,【例】 逻辑运算。逻辑操作是控制过程中经常使用的,掌握逻辑运算的特点是提高程序效率的重要途径。在逻辑运算中,进位标标志CY的地位很特殊,它是逻辑累加器,大多数逻辑操作要通过CY来完成。用程序实现图4-2所示的逻辑电路功能。,图3-2 逻辑电路,单片机程序设计,参考程序如下: ORG 0000H LJMP START ORG 0100H MOV P1,#0FFH ;P1口初始化 LOOP:MOV C,P1.1 ORL C, P1.2 ;P1.1与P1.2逻辑或运算 CPL C ;取反 ANL C,P1.0 ;C与P1.0逻辑与运算 CPL C MOV 07H,C ;暂存于07H
4、单元中 MOV C,P1.3 ANL C,/P1.4 ;P1.3与P1.4的反逻辑与运算 CPL C ORL C,07H MOV P1.5,C ;把结果在P1.5口输出 SJMP $ END,单片机程序设计,3.3 分支程序设计,分支程序的主要特点是程序包含有判断环节,不同的条件对应不同的执行路径。编程的关键任务是合理选用具有逻辑判断功能的指令。由于选择结构程序的走向不再是单一的,因此,在程序设计时,应该借助程序框图(判断框)来明确程序的走向,避免犯逻辑错误。一般情况下,每个选择分支均需单独一段程序,并有特定的名字,以便当条件满足时实现转移。 1单分支选择结构 当程序的判断是二选一时,称为单分
5、支选择结构。通常用条件转移指令实现判断及转移。单分支选择结构有三种典型表现形式。,单片机程序设计,图3-3 单分支选择结构,单片机程序设计,(a)当条件满足时执行分支程序1,否则执行分支程序2。 (b)当条件满足时跳过程序段1,从程序段2顺序执行;否则,顺序执行程序段1和程序段2。 (c)当条件满足时程序顺序执行程序段2;否则,重复执行程序段1,直到条件满足为止。 由于条件转移指令均属相对寻址方式,其相对偏移量rel是个 带符号的8位二进制数,可正可负。因此,它可向高地址方向 转移,也可向低地址方向转移。 对于第三种形式,可用程序段1重复执行的次数作为判断条 件,当重复次数达到某一数值时,停止
6、重复,程序顺序往下 执行。这是分支结构的一种特殊情况,这实际是循环结构程 序。用这种方式可方便实现状态检测。 【例】:LOOP: JB P1.1,LOOP 单分支程序一般要使用状态标志,应注意标志位的建立。,单片机程序设计,【例】设a存放在累加器A中,b存放在寄存器B中,若a0, Y=ab;若a0,则Y=ab。 这里的关键是判a是正数,还是负数;可通过判断ACC.7确定。 ORG 0000H LJMP BR ORG 0100H BR: JB ACC.7,MINUS;负数,转到MINUS CLR C ;清进位位 SUBB A,B;A-B SJMP DONE MINUS:ADD A,B;A+B D
7、ONE:SJMP $;等待 END,单片机程序设计,2双向分支程序设计举例 【例4.3】 设X存在30H单元中,根据下式 X+2X0 Y = 100X=0 XX0 求出Y值,将Y值存入 31H单元。 解:根据数据的符号位判别该数的正负,若最高位为0,再判别该数是否为0。程序流程如图4-4所示。,单片机程序设计,单片机程序设计,参考程序如下:ORG1000H MOVA,30H ;取数 JBACC.7,NEG ;负数,转NEG JZZER0 ;为零,转ZER0 ADDA,#02H ;为正数,求X+2 AJMP SAVE ;转到SAVE,保存数据 ZER0:MOVA,# 64H;数据为零,Y=100
8、 AJMP SAVE ;转到SAVE,保存数据 NEG:DEC A CPLA ;求X SAVE:MOV31H,A;保存数据 SJMP;暂停,单片机程序设计,2多分支选择结构 当程序的判别输出有两个以上的出口流向时,称为多分支选 择结构。8051的多分支结构程序还允许嵌套,即分支程序中 又有另一个分支程序。汇编语言本身并不限制这种嵌套的层 次数,但过多的嵌套层次将使程序的结构变得十分复杂和臃 肿,以致造成逻辑上的混乱。多分支选择结构通常有两种形 式,如图4-4所示。,图4-4 多分支选择结构,单片机程序设计,8051的散转指令和比较指令均可以实现多分支转移。 散转指令 JMP A+DPTR 比较
9、指令 CJNE A,direct,rel (共有4条) 使用散转指令前,先将各分支程序编写好,存放在程序存储器中,并将各分支程序的入口地址组成一个表格放在一起,把表首地址送入DPTR,把子程序的序号放入A中。 在8051指令中,还有4条功能极强的比较转移指令: CJNE A,direct,rel CJNE A,#data,rel CJNE Rn,#data,rel CJNE Ri,#data,rel 这4条指令对指定单元内容进行比较,当不相等时程序作相对转移,并指出其大小,以备作第二次判断;若两者相等,则程序顺序执行。,单片机程序设计,【例】散转程序。编写程序,根据20H单元中的内容转入相应的
10、分支,执行指定的操作,将结果存入指定存储器单元。程序流程框图 如图4-5所示,图3-5 散转程序流程,单片机程序设计,参考程序 ORG 0000H LJMP MEMS RESULT EQU 0050H ORG 0100H MEMS:MOV A,20H MOV DPTR,#KKKK;散转程序入口地 址表首址 RL A ;分支号乘2,每个入口地址均为2字节 JMP A+DPTR ;转移 END1:SJMP $ KKKK:AJMP MEMSP0 ;A=0加法 AJMP MEMSP1 ;A=1减法 AJMP MEMSP2 ;A=2乘法 SJMP MEMSP3 ;A=3除法 SJMP MEMSP4 ;A
11、=4逻辑与 SJMP MEMSP5 ;A=5逻辑或,单片机程序设计,MEMSP0:MOV A,R0 ;相加分支 CLR C ADD A,R1 MOV RESULT,A LJMP END1 MEMSP1:MOV A,R0 ;相减分支 CLR C SUBB A, R1 MOV RESULT,A LJMP END1 MEMSP2:MOV A,R0 ;乘法分支 MOV B,R1 CLR C MUL AB MOV RESULT,A MOV RESULT+1,B LJMP END1,单片机程序设计,MEMSP3:MOV A,R0 ;除法分支 MOV B,R1 CLR C DIV AB MOV RESULT
12、,A MOV RESULT+1,B LJMP END1 MEMSP4:MOV A,R0 ;逻辑与分支 ANL A,R1 MOV RESULT,A LJMP END1 MEMSP5:MOV A,R0 ;逻辑或分支 ORL A,R1 MOV RESULT,A LJMP END1 END,单片机程序设计,【例】 两个无符号数比较大小。设外部RAM单元ST1和ST2中存放两个无符号二进制数,要找出其中的大数存入ST3单元中。程序流程框图如图3-6所示。,图3-6 求大数程序流程,单片机程序设计,参考程序如下: ORG 0000H LJMP START ORG 0100H START:MOV A,add
13、r1 ;将addr1中内容送A CJNE A,addr2,LOOP1 ;两数比较,不相等则 转LOOP1 LOOP3:AJMP $ ;结束 LOOP1:JC LOOP2 ;当CY1,转LOOP2 MOV addr3,A ;CY0,(A)(addr2) SJMP LOOP3 ;转结束 LOOP2:MOV addr3,addr2 ;CY1,(addr2)(A) SJMP LOOP3 END,单片机程序设计,3.4 循环程序设计,在实际应用中经常会遇到功能相同,需要多次重复执行某段 程序的情况,这时可把这段程序设计成循环结构,这有助于 节省程序的存储空间,提高程序的质量。循环程序一般由4部 分组成。
14、 1. 初始化。即设置循环过程中有关工作单元的初始值,如置循环次数、地址指针及工作单元清零等。 2. 循环体。即循环处理部分,完成主要的计算或操作任务,是重复执行的程序段。 3. 循环控制。每循环一次,就要修改循环次数、数据及地址指针等循环变量。并根据循环结束条件,判断是否结束循环。 4. 循环结束处理。对结果进行分析、处理、保存。,单片机程序设计,循环程序结构有两种,如图3-7所示。,图3-7 循环程序结构,单片机程序设计,图(a)是“先执行后判断”结构,适用于循环次数已知的情况。其特点是进入循环后,先执行循环处理部分,然后根据循环次数判断是否结束循环。 图(b)是“先判断后执行”结构,适用
15、于循环次数未知的情况。其特点是将循环控制部分放在循环的入口处,先根据循环控制条件判断是否结束循环,若不结束,则执行循环操作;若结束,则退出循环。,单片机程序设计,【例】50 ms软件延时程序。 软件延时程序一般都是由DJNZ Rn,rel指令构成。执行一条DJNZ指令需要两个机器周期。软件延时程序的延时时间主要与机器周期和延时程序中的循环次数有关,在使用12 MHz晶振时,一个机器周期为1s,执行一条DJNZ指令需要两个机器周期,即2s。适当设置循环次数,即可实现延时功能。 参考程序如下: ORG 0000H LJMP MEMS ORG 0100H MEMS: DEL: MOV R7,#125
16、 ;外循环次数,该指令为一个机器周期 DEL1:MOV R6,#200 ;内循环次数 DEL2:DJNZ R6,DEL2 ;2002400s (内循环时间) DJNZ R7,DEL1 ;0.4 ms12550 ms(外循环时间) SJMP $ END,单片机程序设计,例2循环程序设计举例 【例】有一数据块从片内RAM的30H单元开始存入,设数据块长度为10个单元。根据下式: X+2 X0 Y= 100 X=0 求出Y值,并将Y值放回原处。 X X0 解:设置一个计数器控制循环次数,每处理完一个数据,计数器减1。程序流程如图4-8所示。,单片机程序设计,图4-8 例4.5的程序流程图,返回本节,单片机程序设计,参考源程序如下: ORG2000H MOVR0,#10 MOVR1,#30H START:MOVA,R1;取数 JBACC.7,NEG;若为负数,转NEG JZZER0;若为零,转ZER0 ADDA,#02H;若为正数,求X+2 AJMPSAVE;转到SAVE,保存数据 ZER0: MOVA,# 64H;数据为零,Y=100,单片机程序设计,AJMPSAVE;转到SAVE,保存数据