什么是单片机的子程序设计
扫描二维码
随时随地手机看文章
子程序是模块化程序设计的一种常用技巧,将完成某种特定任务的指令整合在一起,可以被重复使用,能提高编程效率。
子程序分为中断服务处理子程序和普通功能性子程序两种,其中:
(1)中断服务处理子程序
中断服务处理子程序可简称为中断服务处理程序或中断程序,用于处理单片机的中断事件,只能被单片机硬件调用执行,而不能通过子程序调用指令(ACALL或LCALL)调用执行。中断服务处理程序只能通过RETI指令返回。
(2)普通功能性子程序
普通功能性子程序必须通过子程序调用指令(ACALL或LCALL)调用执行,并且只能通过RET指令返回。
子程序设计过程中需要注意:
1)RET指令和RETI指令分别用于功能性子程序和中断服务处理程序的返回,不能相互替换使用。
2)子程序可能会与主程序共用一些资源(如寄存器和存储器等),这些资源通常被称为“现场”。为了不干扰主程序运行,子程序执行前后应保证“现场”不变。为此,进入子程序后需进行现场保护,子程序返回之前需进行现场恢复。现场保护的常用方法是通过堆栈操作指令PUSH将现场存入堆栈中,而恢复时用POP指令将现场从堆栈中取出。
3)主程序调用子程序时,需要将入口参数传递给子程序,而子程序返回前需要将出口参数(执行结果)传回主程序。
4)子程序的出口参数不能被当作现场进行保护。
5)子程序还可以调用其他子程序,即子程序嵌套。子程序嵌套时,同样也存在现场保护和参数传递的问题。
本节将通过实例介绍普通功能性子程序的设计方法,中断服务处理程序的设计方法将在下一章介绍。
1.延时类子程序
【例3-72】将例3-69中的延时程序改写为子程序,并进行一次调用。
解:参考程序如下,其中DEALAY为由例3-69延时程序改写的延时子程序。其中,RET指令的机器周期数为2,因此子程序DEALAY比例3-69程序的延时时间多两个机器周期,即2μs。另外,子程序DEALAY没有入口和出口参数。
2.数值计算类子程序
【例3-73】计算X2+Y2。要求:X和Y均为0~10的整数,并分别存放于片内RAM的40H和41H单元中,二次方和存于42H单元中;由子程序完成数据二次方的计算。
分析:本例的设计任务与例3-57基本一致,不同仅在于本例必须用子程序计算二次方;因此,本例的程序可以由例3-57的参考程序改编而得。
解:本例的参考程序及其说明如图3-12所示。子程序SQRT通过查表法计算数据的二次方,其入口和出口参数均为累加器A。通过累加器或特殊功能寄存器在主程序和子程序之间传递参数,是一种比较常用的参数传递方法,另外,也可以通过存储单元或堆栈进行参数传递。SQRT子程序中对DPTR进行了保护,以免干扰主程序中其他与DPTR有关的操作,
而累加器A作为出口参数不能被保护,否则子程序结束后累加器的值将恢复为进入子程序之前的值。另外,特别需要注意的是,利用堆栈进行现场保护时必须遵守堆栈“先入后出,后入先出”的使用原则,即先“PUSH”的数据应该后“POP”,反之亦然。
图3-12例3-73参考程序及说明
3.码制转换类子程序
单片机中常用的码制有ASCII码和BCD码,而单片机仅能识别和处理二进制数,因此需要进行二进制数与ASCII码和BCD码转换之间的转换。
【例3-74】编写将一位十六进制数转换成ASCII码的子程序,利用该子程序将字节型数09AH的高、低半字节转换为ASCII码,并分别存入片内RAM的31H和30H单元。
解:本例参考程序如下。在HASC子程序中,累加器A既是入口参数,也是出口参数,即该子程序执行后累加器A的值被改变。