循环程序设计示例总结
扫描二维码
随时随地手机看文章
当需要清0操作的字节单元的个数增加时,程序中MOV指令的个数也会随之增加。为了降低程序中重复代码的数量,缩短程序的长度,可以采用循环程序结构进行程序设计。
【例3-64】编写程序,将片内RAM中地址为40H~7EH的存储单元清0。
参考程序
由例3-64可知,如图3-10所示,循环结构程序由循环变量初始化、循环体、循环变量修改和循环结束控制等部分构成。例3-64中两个参考程序的主要差别是循环结束控制方式不同,参考程序1通过已知的循环次数控制程序结束,而参考程序2则通过循环结束条件控制循环次数。
图3-10例3-64源程序的结构划分
另外,根据循环结束控制所处的位置,可以将循环程序分为直到型循环和当型循环。直到型循环先执行循环体后进行循环结束条件的判断,当型循环则与之相反,如图3-11所示。
图3-11直到型和当型循环结构程序流程图
a)直到型循环b)当型循环
若循环中嵌入循环则为多重循环,否则为单重循环,如例3-64的两个参考程序均属于单重循环程序。下面举例说明单重循环和多重循环程序的设计方法。
1.单重循环程序
【例3-65】将片内RAM中地址从60H开始的20H个单字节数据相加。要求:和为双字节数据,并按照由高字节到低字节的顺序存放于片内RAM的41H和40H单元中。
解:参考程序如下:
在该参考程序中,数据低字节加法不需要考虑进位,因此使用ADD指令;而低字节加法可能产生进位,且该进位必须加入到高字节的运算结果中,所以高字节加法应使用带进位的加法指令ADDC。
【例3-66】将片外RAM中地址从1234H开始的20H个单字节分别存入片内RAM中地址从50H开始的20H个字节单元中。
解:参考程序如下:
【例3-67】计算下面这段延时程序执行一遍所需的时间,假设单片机晶振频率为12MHz。
解:
1)单片机的机器周期是晶振周期的12倍,可得机器周期T=12/(12MHz)=1μs。
2)这是一个单重循环程序,第一条指令将0FFH送入R7后,第二条指令DJNZ将重复执行R7次,即0FFH次,因此这段程序的执行时间是所有指令的机器周期数乘以执行次数再相加的和,即:1μs×1+2μs×0FFH=511μs=0.511ms。
3)被称为延时程序是因为这样的程序仅对所涉及的寄存器(或存储单元)数据产生影响,并且执行用时是可以计算的,在单片机系统程序中仅用于消耗时间。
4)若第一条指令将0送入R7,则该程序的执行时间将达到最长,即:1μs×1+2μs×(0FFH+1)=513μs=0.513ms。
5)如果单片机晶振周期改为6MHz,则机器周期T=12/6MHz=2μs,该延时程序的执行时间将加倍。
2.多重循环程序
【例3-70】计算下面这段延时程序执行一遍所需的时间,假设单片机晶振频率为12MHz。
解:
1)在此段程序中,例3-69的程序作为内循环被嵌入另一个外循环中,外循环的次数为R6=14H。因此,内循环指令将与外循环控制指令“DJNZ R6,DL”一起执行14H次。
2)本程序为双重循环程序,执行的时间为:1μs×1+(511μs+2μs)×14H=10261μs。
【例3-71】片内RAM中50H单元开始存有一个长度为N的字节型无符号数据块,请将该数据块中的数据按照由小到大的顺序(即升序)重新排序。
解:参考程序如下:
该参考程序使用了“冒泡法”排序,该排序方法每次仅比较相邻的两个数(即第一个数与第二个数比较,第二个数与第三个数比较,依此类推),若不符合排序规则(本例中要求按从小到大排序),则交换这两个数据。每轮排序将所有相邻的数比较一遍后,最大数将被存入参与本轮排序的地址最大的存储单元中,而且该存储单元中的数将不参与下一轮排序。另外,本参考程序使用了两条DJNZ指令,属于双重循环程序,内、外循环次数分别由R6和R7控制。
特别需要注意,在设计循环程序时,为避免出现“死循环”(即循环体执行无限次),必须遵循以下设计原则:
1)不能从循环体外直接跳入循环体内。
2)不能从外循环直接跳入内循环。
3)内、外循环不能相互交叉。