PIC 单片机 C 语言编程简介(4)
C 和汇编混合编程
有两个原因决定了用 C
机的一些特殊指令操作在标准的 C 语言语法中没有直接对应的描述,例如 PIC 单片机的清
看门狗指令“clrwdt”和休眠指令“sleep”;单片机系统强调的是控制的实时性,为了实现这
一要求,有时必须用汇编指令实现部分代码以提高程序运行的效率。这样,一个项目中就会
出现 C 和汇编混合编程的情形,我们在此讨论一些混合编程的基本方法和技巧。
11.9.1
在
汇编指令,PICC 提供了一个类似于函数的语句:
asm(“clrwdt”);
双引号中可以编写任何一条 PIC 的标准汇编指令。例如:
for (;;) {
}
//休眠
//空操作延时
例 11-8
如果需要编写一段连续的汇编指令,PICC 支持另外一种语法描述:用“#asm”开始汇
编指令段,用“#endasm”结束。例如下面的一段嵌入汇编指令实现了将
RAM 全部清零:
#asm
#endasm
例 11-9
11.9.2
C 语言中定义的全局或静态变量寻址是最容易的,因为这些变量的地址已知且固定。按
C 语言的语法标准,所有 C 中定义的符号在编译后将自动在前面添加一下划线符“_”,因
此,若要在汇编指令中寻址 C 语言定义的各类变量,一定要在变量前加上一“_”符号,我
们在上面例 11-9 中已经体现了这一变量引用的法则,因为 FSR 和 INDF 等所有特殊寄存器
是以 C 语言语法定义的,因此汇编中需要对其寻址时前面必须添加下划线。
对于 C 语言中用户自定义的全局变量,用行内汇编指令寻址时也同样必须加上“_”
下面的例 11-10 说明了具体的引用方法:
volatile unsigned char tmp;
void Test(void)
{
clrf
#endasm
}
}
//测试程序
//开始行内汇编
//选择 bank0
//设定初值
//tmp=0x10
//结束行内汇编
//开始 C 语言程序
例 11-10
上面的例子说明了汇编指令中寻址 C 语言所定义变量的基本方法。PICC 在编译处理嵌
入的行内汇编指令时将会原封不动地把这些指令复制成最后的机器码。所有对 C 编译器所
作的优化设定对这些行内汇编指令而言将不起任何作用。编程员必须自己负责编写最高效的
汇编代码,同时处理变量所在的 bank 设定。对于定义在其它 bank 中的变量,还必须在汇编
指令中加以明确指示,见例 11-11 的代码范例。
volatile bank1 unsigned char tmpBank1;
volatile bank2 unsigned char tmpBank2;
volatile bank3 unsigned char tmpBank3;
void Test(void)
{
bcf
bsf
movlw
movwf
bsf
bcf
movlw
//测试程序
//开始行内汇编
//选择 bank1
//设定初值
//tmpBank1=0x10
//选择 bank2
//设定初值
movwf
bsf
bsf
movlw
//选择 bank3
//设定初值
movwf
}
#endasm
//结束行内汇编
例 11-11
通过上面的代码实例,我们可以掌握这样一个规律:在行内汇编指令中寻址 C
义的全局变量时,除了在寻址前设定正确的 bank 外,在指令描述时还必须在变量上异或其
所在 bank 的起始地址,实际上位于 bank0 的变量在汇编指令中寻址时也可以这样理解,只
是异或的是 0x00,可以省略。如果你了解 PIC 单片机的汇编指令编码格式,上面异或的 bank
起始地址是无法在真正的汇编指令中体现的,其目的纯粹是为了告诉 PICC 连接器变量所在
的 bank,以便连接器进行 bank 类别检查。
11.9.3
前面已经提到,PICC 对自动型局部变量(包括函数调用时的入口参数)采用一种“静
态覆盖”技术对每一个变量确定一个固定地址(位于
址时只需采用数据寄存器的直接寻址方式即可,唯一要考虑的是
PIC单片机C语言编 相关文章:
- PIC单片机C语言编程教程(1)(11-22)
- PIC 单片机 C 语言编程简介(2)(11-22)
- PIC 单片机 C 语言编程简介(3)(11-22)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)