【发布时间】:2012-05-14 21:12:57
【问题描述】:
这是我第一次在 C 语言中使用宏,我试图用宏替换我通常放入函数中的大部分代码。这是一个经常使用的中断的一部分,因此我需要尽可能地优化它。看了文档,发现编译器不支持函数内联,想避免函数调用开销。
代码本身将数据发送到串行输入并行输出移位寄存器,据我所知,没有更短的方法可以编写我需要的代码。
我正在使用 C18 编译器版本 3.41 和 MPLAB X IDE。
这是我在函数形式中使用的代码:
void first_one(void)
{
//3 invisible zeroes
LATBbits.LATB1=0; //data set to zero
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//third clock
LATBbits.LATB0=0;
//end of invisible zeroes
//two visible zeroes
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
//end of two visible zeroes
LATBbits.LATB1=1;//Data is now one
LATBbits.LATB0=1;
LATBbits.LATB0=0;
//one
LATBbits.LATB1=0;//Data is now zero
LATBbits.LATB0=1;//first clock
LATBbits.LATB0=0;
LATBbits.LATB0=1;//second clock
LATBbits.LATB0=0;
//after this, everything should be in place
LATBbits.LATB0=1;
LATBbits.LATB0=0;
}
我已经把函数变成了这个宏:
#define first_one() { \
\
LATBbits.LATB1=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB1=1;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB1=0;\
^^^ The syntax error is here!
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
LATBbits.LATB0=1;\
LATBbits.LATB0=0;\
\
}
那我做错了什么?
更新:我删除了 cmets,现在在其他位置出现语法错误。
【问题讨论】:
-
为什么你甚至认为你需要把函数变成一个宏?如果函数调用开销很大,只需将其设为内联函数即可。
-
@Paul R 正如我在问题中所说,编译器不支持函数内联。
-
... 但正如 Paul 所说,你真的认为这里的函数调用开销很重要 - 毕竟这不是一个单行函数。对我来说看起来像 premature optimisation。
-
@Clifford 是的,我很清楚“万恶之源”。是的,函数调用开销是个问题。在微控制器当前的工作频率下,我几乎没有足够的空间来足够快地为中断服务,而且微控制器应该做的其他事情也没有多少时间。是的,我考虑过增加频率,是的,这是一个大问题,所以最好不要增加频率。不,我无法转向更高效的架构。话虽如此,我相信我为优化这一点所做的努力是合理的。
-
@AndrejaKo:如果您无法满足实时截止日期,那么对这种微优化的需求表明您已经用尽了想法或能力。如果是后者,那么你的尝试也许是英勇的,但最终可能注定要失败。如果是前者,那么就有希望,但由于显而易见的原因,认识到这个问题很困难;如果一个解决方案是可能的,它将是在设计级别而不是编码级别。例如,除了 18 针 PIC18 部件外,所有部件都有一个 SPI 端口,可以在硬件中执行串行输出,从而减少代码空间和 CPU 开销。