ASM5无参数化调用C51函数的实现
示出来。设计任务很简单,编程中的最大难度就在于车速的计算程序。由于轮径值要求精确到mm(最大值超过了1000),车速的计算结果要保留到小数点后一位,因此需要进行浮点数运算,期间还要完成数的各种进制间的换算。虽然算法简单,但实际用汇编语言实现起来经常考虑不周,调试起来费时费力(笔者调试通过的这段汇编代码长达近 400行)。这样,自然就想到调用C51函数了,充发发挥两种语言的优势。先用汇编语言设计好各个模块,包括循环显示车速和轮径值的主程序模块,响应采样转速值和键盘输入两个中断模块,代码如下所示。
EXTRN CODE(CALL1) ;声明外部C51函数
ORG 0000H
LJMP MAIN
ORG 0003H
AJMP KEYINPUT ;键盘输入中断
ORG 000BH
AJMP SETTIME ;采样时间到,采样转速值中断
ORG 0100H
KEYINPUT:…… ;键盘输入中断
…… ;将键盘输入信号保存在
;70h~73h的地址空间中
RETI
ORG 0600H
SETTIME:…… ;采样时间到,采样转速值中断
…… ;将转速值放置在地址为3Ah的空间中
;紧接着调用外部C51函数CALL1()进
;行车速的计算
LCALL CALL1
RETI
ORG 2000H ;主程序模块
MAIN:…… ;首先进行初始化操作
……
;直接从地址空间70h~77h中读取显示数据,循环显示车速和轮径值
END
这些小模块用汇编实现起来不仅容易,而且程序员可以清楚地了解到各个模块的出入口及其相应的功能,实现对程序空间的充分配置。最后用C51语言来实现车速的计算模块CALL1()。以前用汇编编写的近400行代码,一下子被压缩到20~30行(真正的计算代码仅9行),不仅简短易懂,而且几乎就不需要调试了。
下面的代码是计算模块CALL1()及其需要的绝对地址定义。
#pragma code small
#include absacc.h>
#include math.h>
#define PI 3.1415926
#define NCIRCLE DBYTE[0x3A] ;定义放置转速的绝对地址
#define DIRECT1 DBYTE[0x70] ;定义放置轮径千位的绝对地址
#define DIRECT2 DBYTE[0x71] ;定义放置轮径百位的绝对地址
#define DIRECT3 DBYTE[0x72] ;定义放置轮径十位的绝对地址
#define DIRECT4 DBYTE[0x73] ;定义放置轮径个位的绝对地址
#define VELOCITY1 DBYTE[0x74] ;定义返回车速的千位绝对地址
#define VELOCITY2 DBYTE[0x75] ;定义返回车速的百位绝对地址
#define VELOCITY3 DBYTE[0x76] ;定义返回车速的十位绝对地址
#define VELOCITY4 DBYTE[0x77] ;定义返回车速的个位绝对地址
void call1()
{
float data result;
int data DIRECT;
DIRECT=DIRECT1*1000+DIRECT2*100+DIRECT3*10+DIRECT4;
result=(DIRECT/1000.0)*PI*NCIRCLE*3.6;
VELOCITY1=result/100;
Result=result-VELOCITY1*100;
VELOCITY2=result/10;
result=result-CELOCITY 2*10;
VELOCITY3=result;
result=result-VELOCITY3;
VELOCITY4=result*10;
}
在本例中定义了绝对地址空间70h~77H和3AH。其中3AH存放采样转速值输入模块输入的转速;70H~73H的地址空间中存放键盘输入中断模块中键盘输入的轮径值;而地址为74H~77H的空间中则存放计算模块中的车速计算返回值。尽管需要传递和返回的参数比较多,但通过这些绝对地址的定义,完全解决了原来复杂的汇编与C51之间的调用接口配置。计算模块中需要使用转速和轮径值时,将自动从绝对地址3AH和70H~73H中取值;在循环显示车速和轮径值的主程序模块中则直接读取绝对地址空间70H~77H的各个数据进行循环显示。当然,程序员可以根据自己的空间配置另外定义这些绝对地址。
以上程序代码均已在Dais-52.196P仿真器上顺利调试通过。
由上面的简单程序可以看出这种无参数化调用方法的优越性和有效:从程序代码看,无论是编写C51子程序还是汇编主程序,都与编写纯C51函数或者纯汇编主程序的格式完全一样,从根本上简化了C51与汇编函数之间的接口编程,提高了程序调用的效率;充分利用了汇编与高测验C51语言各自的优点,开发、调试快速方便,通用性强,尤其适合于初学者。对于复杂程序,同样可以利用无参数化方法来帮助实现。这对于提高单片机应用程序的开发效率很有意义。
无参数化调用实质上在C51函数中定义了几个全局变量(绝对地址),依靠它们直接完成参数值的传递和返回值的调用,相当于一种程序员自定义的传递方式,抛弃了传统C与汇编之间的接口约定。只要程序员安排得当,还可以进一步人工实现C51中的动态覆盖重用,提高RAM区的利用效率。由上也可看出:无参数化调用方法要在ASM汇编调用C51函数时才分依速无参数化思想,就违背了利用C51编程,过衷,得不偿失。当然,如果开发人员已经对C51与汇编函数之间的参数传递
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)