MPLAB-C18 C编译器的优化技巧

来源:本站
导读:目前正在解读《MPLAB-C18 C编译器的优化技巧》的相关信息,《MPLAB-C18 C编译器的优化技巧》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《MPLAB-C18 C编译器的优化技巧》的详细说明。
简介:Microchip推出的PIC18系列单片机由于采用改进型的哈佛结构及优化的硬件结构,内含三个间接寻址寄存器FSR0、FSR1和FSR2, RAM 和ROM 空间都比较大, 因此PIC18非常适合于采用C语言进行软件设计。C语言具有可读性强, 便于移植等优点。

虽然MPLAB-C18 C语言编译器的编译效率比较高, 但与汇编语言相比, C的效率终究差一些, 因此在某些应用场合, 如何优化C的效率, 减小代码, 提高执行速度, 是许多工程师们的追求目标。下面介绍MPLAB-C18 C编译器的一些优化技巧, 与大家共享。

1 使用静态型局部变量

局部变量的缺省存储类型为自动型,存取时使用软件堆栈,即使用直接寻址方式。如果声明为静态型,则静态型局部变量编译时将分配固定地址, 访问时将使用直接寻址。显然, 直接寻址比间接寻址存取速度快,占用的代码空间少。下面举例比较静态型与自动型局部变量生成汇编代码的差别。

源程序代码

void sub1(void) {

static unsigned char local1; //静态型

unsigned char local2; // 自动型

local1+=5; // 占用5个字

local2+=6; //仅占用3个字

} 生成的汇编代码

MOVF POSTINC1,F,ACCESS

MOVLW 0X05

MOVLB 0X0

ADDWF L1,F,BANKED

MOVF POSTDEC1,F,ACCESS

MOVLW 0X06

MOVLB 0X0

MOVWF LOCAL1,BANKED

注意:①静态型局部变量将占用更多的数据存储器空间;② 如果该函数是可重载的, 则局部变量不能声明为静态型。

2 使用全局变量传递函数参数

当有足够的数据存储空间且该函数不可重载时, 可使用全局变量传递函数参数, 优化你的代码。因为全局变量编译时将分配固定地址, 访问时将使用直接寻址方式。例如调用sub1子程序, 可采用下面使用全局变量传递函数参数的方法。

unsigned char sub1_var1,sub1_var2;

void sub1(void);

void main(void){

sub1_var1=1;

sub1_var2=2;

sub1();

}

替代如下传递函数参数的方法。

void sub1(unsigned char var1,unsigned char var2)

viod main(void)

{

sub1(1,2)

}

当然也可以把var1、var2声明为静态型存储类型, 达到相同优化代码的目的。即:void sub1(static unsigned char var1, static unsigned char var2)。

3 使用合适的数据类型

MPLAB C-18支持的数据类型及占用的字节数如下:

类型 最小值 最大值 字节数

unsigned char 0 255 1

signed char -128 127 1

unsigned int 0 655536 2

signed int -32768 32767 2

unsigned short long 0 16777215 4

signed short long -8388608 8388607 4

unsigned long 0 4294967295 8

signed long -2147483648 2147483647 8

不同数据类型占用的数据存储器字节数不同, 因此尽可能使用较短的数据类型。 另外如果是无符号数, 应声明为无符号型。 例如下例变量i、j加一立即数, 其中i为int型,j为char型, 可见它们生成的代码大小不一样。

源程序代码

int i;

unsigned char j;

void main(void) {

i+=5; //占用4个字

j+=6; // 仅占用3个字

}

生成的汇编代码

MOVLW 0X06

ADDWF I,F,BANKED

MOVLW 0

ADDWF 0XB8,F,BANKED

MOVLW 0X05

MOVLB 0X0

ADDWF J,F,BANKED

4 把变量分配于ACCESS RAM区

PIC18系列数据存储器分为16个存储器组(BANK 0~15), 每个存储器组为256个字节, 使用直接寻址方式访问数据存储器时, 先要选择存储器组(BANK)。 为了快速访问数据存储器, PIC18把BANK0的0x0~0x7F和BANK15的0x80~0xFF构成ACCESS RAM。 访问ACCESS RAM时, 不需要选择BANK, 从而达到快速访问的目的。 下面举例比较变量分配于ACCESS RAM区与不在ACCESS RAM的区别。

源程序代码

unsigned char var1 //不在Access RAM区

#pragma udata access mydata near unsigned char var2 //声明于Access RAM区

#pragma

void sub1(void){

var1+=5; // 占用3个字

var2+=6; //仅占用2个字

}

生成的汇编代码

MOVLW 0X05

MOVLB 0X01

ADDWF 0xvar1,F,BANKED

MOVLW 0X06

ADDWF 0xvar2,F, ACCESS

5 使用#pragma varlocate伪指令

#pragma varlocate 伪指令告诉编译器变量所属的存储器组位置, 从而使编译器更有效地执行存储器组切换。 例如在多模块编程中, 文件1把变量I、J分配在存储器组1。

#pragma udata bank1

unsigned char I,J

在文件2中要使用变量I、J, 用# pragma varlocate 声明变量I、J位于存储器组位置1, 这样编译时可省掉一条MOVLB 指令。

extern unsigned char I,J

#pragma varlocate 1 c1,c2

void main (void)

{

I+=5; // 此处编译时可省掉一条MOVLB 指令

J+=6;

}

6 使用指针

下面举例说明使用指针与不使用指针的区别,其中例子1使用指针,例子2不使用指针。编译后,可以发现例子1生成的代码比例子2 少很多。

struct mystruct

{

char a;

char b;

}

mystruct mydata [10];

mystruct *p=&(mydata[0]);

例子1

for(i=0; i<10; i++)

{

p->.a = i;

p->.b = 88;

p++;

}

例子2

for (i=0;i,10;i++)

{

mydata[i].a=i

mydata[i].b=88; }

7 嵌入汇编

因为汇编的效率最高, 因此在有些场合例如中断服务子程序使用嵌入汇编的方法。 MPLAB-C18支持C与汇编的混合编程。

8 使用最新版本的C编译器

MPLAB-C18编译器的版本不断更新,最新版本除了支持新型号的PIC18单片机之外,还对它的优化效率不断改善。因此尽量使用最新版本的C编译器。

9 使用优化命令行选项

在优化功能命令项的选项对话框中,选中表示使能。 但请注意有些优化选项将会影响源程序级调试。限于篇幅,各优化功能命令项的作用这里不一一介绍。

提醒:《MPLAB-C18 C编译器的优化技巧》最后刷新时间 2024-03-14 01:02:16,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《MPLAB-C18 C编译器的优化技巧》该内容的真实性请自行鉴别。