下面介绍单片机汇编语言里的一个概念“子程序”
先打个比方,如果你做一顿饭,要做汤,炒菜,炖鱼,汆丸子,奥,忘了还有炒小螃蟹,期间有一个动作在我看来不断的重复,这个动作就是放盐,放盐的过程描述是这样的:
放盐: 用一把小勺子深入盐罐
舀出氯化钠适量。
把小勺子里的氯化钠
均匀洒在锅里。
完毕
如果我们把做饭定义为主任务,那么放盐这个动作就叫做子任务。
这样定义的一个好处就是描述主任务的时候比较方便,当你用语言文字描述主任务的时候,无论哪一道菜,到了该加盐的时候不必细说用一把小勺子深入盐罐......,因为很多菜都有同样的这个过程,所以,你用 “放盐” 两个字就可以了。但是在你使用 放盐 这个词之前或者之后,你应该解释一下放盐这个词的具体过程是什么。
我们单片机的程序也是一样的,如果你设计一个电视机的自动搜索频道的程序,程序要求电视机每搜索成功一个频道,它面板上的发光二极管就眨一次眼睛,也就说,先熄灭一段时间然后再点亮。这样就会遇到很多这样的眨眼动作,为了简化主程序我们可以把眨眼这样一个过程定义为一段子程序,以后每次遇到需要眨眼的时候就调用一次子程序就可以了。
子程序的定义是这样的:
Zhayan: bcf GPIO,GP1 '管脚GP1输出低电平关闭LED灯,标号是必须有的,标号就是子程序的名字
nop
nop
nop
nop
nop
... .
bsf GPIO,GP1 '管脚GP1输出高电平点亮LED灯
nop
nop
nop
nop
...
return '这个命令表示子程序的结束 是必需的 否则这个子程序没有结束
这样,子程序就定义完了,如果想在程序的某个位置需要led灯熄灭以下(眨眼一次),只需在那个程序位置调用一下子程序就可以了。调用的方法是用 call 命令。
主程序:
.... '这些点点表示主程序里的语句
....
......
...... '这个位置搜所成功一个台 需要“眨眼”一次
call Zhayan
...... '继续搜索下一个台的命令行
......
......
......
...... '这个位置搜所成功一个台 需要“眨眼”一次
call Zhayan
...... '继续搜索下一个台的命令行
......
......
...... '这个位置搜所成功一个台 需要“眨眼”一次
call Zhayan
...... '继续搜索下一个台的命令行
......
疑问1 我在一个主程序里固然可以调用另一个子程序,而我在一个子程序里能不能调用另一个子程序?
答: 可以的,这叫子程序嵌套,甚至还可以在另一个子程序中再继续调用别的子程序。
疑问2 嗯,那继续往下调用下去,有限制么?
答:有,这叫允许嵌套的层数 每个品牌 型号的单片机允许的嵌套层数都是有规定的 例如pic16f74 允许8层 pic12e519允许两层,也就是说pic12e519的主程序里可以调用子程序,子程序里海可以再调用子程序,到此为止不要再往下调用了,否则程序报错或者超出你预计的结果。
疑问3 在同一层程序空间里,例如在我的某个子程序之中,调用另一个子程序的次数有限制么?
回答: 没有限制,只要你的程序寄存器装得下你的程序。
疑问4 我听说单片机在调用子程序以前,好像需要程序“堆栈”访问什么的,要进行一些程序计数器的保存保护,以保证子程序返回来得时候,程序能够正确回到原来位置和环境。是这样的么?
答: pic单片机不用管这些问题,它是硬件自动完成这些堆栈的事情,我们的指令里不用关心这些。尽管如此,中档pic单片机的例如 pic16等系列,它们的程序存储器地址是分页的,尽量调用本页的子程序,如果子程序不在本页,而是在另一个页面里存放,你还是要告诉单片机你的子程序所在的页面数据的,具体操作指令可以查相关指令说明。我们的pic12c519的程序存储器,没有分页,不用关心这事。