分支结构程序是根据判断条件的满足与否,产生一个或多个程序分支,以实现不同的程序流向的程序结构。在一些实际的应用程序中,程序不可能始终是按顺序直线执行的。要使用单片机解决一些实际的问题,通常要求单片机能够做出一些判断,从而实现分支结构程序。
分支程序可以分为双分支结构和多分支结构两种,分别如图5-1和图5-2所示。下面分别介绍这两种分支结构的程序设计。
图5-1 双分支结构
图5-2 多分支结构
双分支结构主要采用条件转移指令来实现分支转移,当给定的条件成立时,执行分支程序1,否则执行分支程序2。
编写分支程序的关键是进行分支条件的判断。在51系列单片机中,主要有位条件转移指令JC、JB等,比较条件转移指令CJNE等和累加器A判断指令JZ等,这些指令的详细介绍参阅本书第16章指令系统部分。合理使用这些指令可以完成各种各样的条件判断。
下面仍以前面的16位二进制数求补的汇编程序为例。这个程序也可以用分支结构的程序设计,这里仍假定带操作的这个双字节数存放在R3、R4中,程序将求补以后的结果存放于地址20H、21H中。程序的流程图如图5-3所示。程序示例如下:
在该段程序中,首先对低字节数取补,然后判断其结果是否为0,如果为0,则对高字节数进行取补,即取反加1,否则直接取反就可以了。这个算法和前面的算法,结果是一样的。
有些简单的多分支结构的程序,也可以用双分支来分步实现。例如,符号函数Y=sign(X)。当X>0时,Y=1;当X=0时,Y=0;当X<0时,Y=-1。下面采用汇编语言来实现这个函数,假定变量X已经存放在20H单元,将函数值Y存放于21H单元。程序的流程如图5-4所示。
图5-3 16位二进制数求补流程图
图5-4 符号函数流程图
程序示例代码如下:
该程序中,相当于分别运用了两个双分支结构来实现运算。
多分支结构是指根据运算的结果在多个分支中选择一个执行的程序结构。双分支是比较简单的情况,在实际的应用中,往往需要多分支跳转,又称为散转。51系列单片机的指令集中有散转指令JMP,详细的介绍可以参阅后面的指令系统介绍。散转指令JMP的使用格式如下:
JMP @A+DPTR
其中数据指针DPTR为存放转移指令串(S0~Sn)的首地址,由累加器A的内容动态选择对应的转移指令。这样,便可以产生多达256个分支程序。
51系列单片机的指令系统中,有两个无条件转移指令,即AJMP和LJMP。前者为双字节指令,后者为三字节指令。这将直接影响散转指令中对累加器A的处理。即如果选择AJMP,则应该将累加器A值变换成偶数值;如果选择LJMP指令,则应该对累加器A值进行乘3的变换。
汇编语言程序中,每个分支程序都有各自的程序段,分别位于程序存储器的不同区段。判断语句根据判断结果,使程序转向不同的分支程序段,这个无条件转移指令串的首地址由DPTR指示。这里以AJMP为例,介绍散转指令的应用。示例代码如下:
在该段程序中,由于AJMP为双字节绝对转移指令,因此,要求累加器A中的内容必须换算成偶数。换算方式可以乘2,即相当于左移一位。如果n的值等于或大于128,则左移一位将产生高位进位,将进位值加到DPH中,这相当于将转移指令串的首地址延伸256个存储单元,所以在程序中对C进行测判。这样可以保证分支程序在0~255个中任意选择。
如果汇编程序中使用了三字节的长调用LJMP指令,在进行累加器A值换算时应该乘3,将积的高字节值加到DPH中去。
注意 :DPTR+A的最终值一般不超过64KB。