近来,在制造一些家用的小电器,又在搜集、学习智能家居和物联网方面的常识。紧接着网站又搬了一个新家,将近一个月没有码字了。这些如同都跟阿浩的干事功率有关,而这篇文章也是说功率的,但并不是说阿浩的功率怎么的低,而是怎样让单片机履行更高效的代码。
提到这儿,有人或许会辩驳我:用汇编不就行了嘛?答案是必定的。用汇编写程序,发生的代码精短,履行功率高,无可置疑。可是当你要写一个大型的程序,而对履行功率要求要高的话,挑选C言语来写,具有优势。这种优势,就不在这大费口舌了。而下面介绍的几个办法,对你写出高效的C程序有一些协助。
首要,有必要知道的,一个C言语程序,终究是要编译成机器码给单片机履行的。也便是说,C言语将被编译器,“翻译”成汇编代码,然后编译成单片机终究的代码。以上了解了就好办,咱们只需求让C言语写的代码,“翻译”成汇编代码会,代码行削减了,就说这种写法更高效。
一.高效的位移操作
咱们在许多模仿串行通信中需求用到移位操作。
例如,I%&&&&&%、SPI,1-Wire总线等等
这儿以1-Wire总线读一个字节为例
unsigned char read_byte(void)
{
unsigned char i;
unsigned char value = 0;
for (i = 0; i < 8; i++)
{
if(read_bit())
value| = 0 x 01< delay(10); //等候总线时隙
}
return(value);
}[c]
这段代码是正确的,但编译后履行功率并不高。
而其实只需深化了解C和汇编之间的联系,写出高效的C代码,既有C的便当,又有汇编的功率。
下面临代码进行修正剖析:
1.for(i=0;i 解释一下:由于CPU判别一个数是否为0,只需求一条指令。比判别一个数多大体履行得快(需求3个指令)。
2.value|=0x01<>=1; //先右移一位,value最高位一定是0
if(read_bit()){
value|=0x80; //判别总线状况,如果是高,就把value的最高方位1
}[c]
这样写出来的代码变得极端高效,编译后根本便是汇编级的代码了。
二.位移操作,让核算更高效
运用单片机AD收集信号方面,一般做法是接连收集N次,然后求平均值。
一般为了MCU核算更为“便利”,收集次数引荐用8,16,32,64,128,256等次数,你懂的,这些数比较特别。
这儿以采样128次,然后求平均值为例。注:sampling()为外部采样函数。
unsigned int total;
unsigned char i,val;
for(i=0;i<128;i++)
{
total+=sampling();
}
val=total/128;[c]
以上代码是一般的写法,可是功率并不高,浪费资源。
改造进行
1.首要剖析128这个数是0B10000000,发现其实第7位是1,其他位都为0,所以咱们就能够判别第7位的状况来判别128次采样是否到了。
2.val=total/128 运用了除法运算,浪费资源,彻底能够用右移的办法来替代(尽管有些编译器会将此类运算转换为位移运算,但写成移位的铁定没错)。
val=total/128等同于 val=(unsigned char)(total>>7);
但这并不彻底高效,还再优化一下:
total>>7 还能够变通成(total<<1)>>8,先左移动一位,再右移动8位,不就成了右移 7 位了么? 由于位移1,4,8位的操作只需求一个指令。
unsigned int total;
unsigned char i=0
unsigned char val;
while(!(i&0x80)){ //判别 i 第7位,只需求一个指令。
total+=sampling();
i++;
}
val=(unsigned char)((total<<1)>>8); //几个指令就替代了几十个指令的除法运算[c]
编译后的代码量竟然能够削减一半,而运算速度能够进步几倍,再回头,就能够了解为什么选用次数要用引荐的一些特别值了。