嵌入式技术
C中的以下简单技巧专门用于程序内存空间优化. 这些对于处理具有有限闪存的低成本 8 位微控制器的嵌入式系统程序员特别有用。虽然在这种情况下汇编语言是最好的选择,但(几乎所有年轻的)硬件工程师现在更喜欢使用 C 语言,即使程序是一个相对较短的控制程序。这 10 个技巧已使用 XC8 编译器(v1.42,免费版)进行了测试,以显示在增强型中档 8 位 XLP PICmicro(PIC16F1824)上应用每个代码片段之前和之后所涉及的程序存储器字节量。这些代码片段除了提供概念证明之外没有什么特别之处。可以在本文末尾列出的参考资料中找到更聪明(和复杂)的技巧。
技巧#1: 尽可能使用简短的数学表达式。
示例 1: | 改用: |
void main(void) { int a, b ; a = (b – 1) * 3 ; } |
void main(void) { int a, b ; a = (b – 1) ; 一 = 一 + 一 + 一 ; } |
使用的程序存储器字节 = 50 | 使用的程序存储器字节 = 25 |
技巧 #2: 使用多个 if 指令(没有 else)来替换 switch 指令。switch 指令的每个 case(没有默认 case)都被替换为 if 指令(没有 else)。但是,如果 switch 指令以默认情况终止,则此技巧无关紧要。
示例 2: | 改用: |
void main(void) { int a, b ; 开关 (a) { 案例 0: b = a + 5 ; 休息 ; 案例 1: b = a * 5 ;休息 ; 情况 2: b = a – 5 ;休息 ; } } |
void main(void) { int a, b ; 如果 (a == 0) b = a + 5 ; 如果 (a == 1) b = a * 5 ; 如果 (a == 2) b = a – 5 ; } |
使用的程序存储器字节 = 79 | 使用的程序存储器字节 = 74 |
技巧 #3: 假设我们要扫描一组特定的键盘触摸(仅按字母顺序排列,不区分大小写):
示例 3: |
改用:( 这 也使代码运行得更快) |
void main(void) { char chx ; if (chx == 'a' || chx == 'A') b = a + 5 ; if (chx == 'm' || chx == 'M') b = a – 10 ; if (chx == 't' || chx == 'T') b = a * 25 ; } |
void main(void) { char chx ; //小写, // 注意,仅按字母顺序 chx = chx | 0x20 ; if (chx == 'a') b = a + 5 ; if (chx == 'm') b = a – 10 ; if (chx == 't') b = a * 25 ; } |
使用的程序存储器字节 = 84 | 使用的程序存储器字节 = 77 |
技巧 #4: 尽可能使用 if 指令而不使用 else。在此代码中,我们假设条件 (a == 0) 更频繁地发生(在现实世界中使用设计时)。因此,我们首先提出: b = 0 ; 然后,我们用一个简单的 if 指令(没有 else)来考虑备用状态(不太频繁)。
示例 4: | 改用: |
void main(void) { int a, b, c ; 如果 (a == 0) b = 0 ; 否则 b = (a – c) * 100 ; } |
void main(void) { int a, b, c ; b = 0 ; 如果 (a) b = (a – c) * 100 ; } |
使用的程序存储器字节 = 64 |
使用的程序内存字节 = 63 (可以忽略不计,但通常,代码源包含许多 if/else 指令 |
技巧 #5: 使用一维表,而不是二维表。将二维表(行索引 i 和列索引 j)转换为一维表(索引 k)相对容易,假设索引计算如下: k = i * N + j ;其中 N 是总列数。(所有索引都是从零开始的)
示例 5: | 改用: |
void main(void) { const char *TabMois[] = {“一月”,“二月”,“三月”,“四月”,“五月”,“六月”, “七月”,“八月”,“九月”, “十月”、“十一月”、“十二月”} ; char ch1 = TabMois[0][0],ch2 = TabMois[0][1], ch3 = TabMois[0][2]; } |
void main(void) { const char TabMois[] = “JanFebMarAprMayJunJulAugSepOctNovDec” ; char ch1 = TabMois[0],ch2 = TabMois[1], ch3 = TabMois[2]; } |
使用的程序存储器字节 = 149 | 使用的程序存储器字节 = 68 |
技巧 #6: 在计算表达式时,尽可能使用整数值而不是浮点值。假设一个电池电压的值在 10.5 到 14.2 伏之间变化,步长为 0.1 伏。我们要计算每分钟的平均值(对于 1s 数据采集系统)。将 10 位数字计数测量值累积为整数变量,而不将其(每秒)转换为有意义的电压测量值(浮点值)。此转换仅在最后一步中进行一次。
示例 6: | 改用: |
int Measure (unsigned int canal) { //这里涉及更多代码来配置运河 //... return ((ADRESH<<8) + ADRESL) ; } void main(void) { float Vbat, Vmean=0 ; 整数一,cnt = 60; while (cnt) { if (TMR1IF) { Vbat = Measure(a) * 4.88 ; Vmean += Vbat ; cnt-; TMR1IF = 0 ; } } Vmean /= 60 ; } |
int Measure (unsigned int canal) { //这里涉及更多代码来配置运河 //... return ((ADRESH<<8) + ADRESL) ; } void main(void) { float Vmean ; int a,cnt,Vbat,Vbat60=0; while (cnt) { if (TMR1IF) { Vbat = Measure(a) ; Vbat60 += Vbat ; cnt-; TMR1IF = 0 ; } } Vmean = (Vbat60 * 4.88) / 60 ; } |
使用的程序存储器字节 = 841 | 使用的程序存储器字节 = 570 |
技巧#7: 指令可以用多种方式编写。看看这个结构:
示例 7: | 改用: |
void main(void) { for (a = 10 ; a > 0 ; a–) b = c + a ; } |
void main(void) { for (a = 10 ; a– ; ) b = c + a ; } |
使用的程序存储器字节 = 43 | 使用的程序存储器字节 = 27 |
技巧 #8: 修改包含乘法与常数 k 的数学表达式,并修改它以使用除以 1/k
示例 8: | 改用: |
void main(void) { float a, b, c ; a = (b + c) * 0.1 ; } |
void main(void) { float a, b, c ; a = (b + c) / 10.0 ; } |
使用的程序存储器字节 = 570 | 使用的程序存储器字节 = 559 |
技巧 #9: 尽可能对 int 或 long 类型 使用无符号值。注意将数字保持在区间 {0, ..., INT_MAX} 或 {0, ..., LONG_MAX}
示例 9: | 改用: |
void main(void) { int Vbat ; // 1, 2, ..., 1023 Vbat = 1023 / Vbat ; //案例 1 Vbat = (2048L * 15) / Vbat ; //案例 2 } |
void main(void) { int Vbat ; // 1, 2, ..., 1023 Vbat = 1023U / Vbat ; //案例 1 Vbat = (2048UL * 15) / Vbat ; //案例 2 } |
情况 1:使用的程序存储器字节 = 102
情况 2:使用的程序存储器字节 = 160 |
情况 1:使用的程序存储器字节 = 73
情况 2:使用的程序存储器字节 = 114 |
技巧 #10: 在 if 指令中重新安排测试:
例 10: | 改用: |
void main(void) { int a, b ; 如果 (a – b) b = (a – 5) * 100 ; //情况 1 if (b > a) b = (a – 5) * 100 ; //情况 2 if (b – a > 0) b = (a – 5) * 100 ; //案例 3 } |
void main(void) { int a, b ; 如果 (a != b) b = (a – 5) * 100 ; //情况 1 if (a < b) b = (a - 5) * 100 ; //情况 2 if (a – b < 0) b = (a - 5) * 100 ; //案例 3 } |
情况 1:使用的程序存储器字节 = 67
情况 2:使用的程序存储器字节 = 62 情况 3:使用的程序存储器字节 = 77 |
情况 1:使用的程序存储器字节 = 58
情况 2:使用的程序存储器字节 = 62 情况 3:使用的程序存储器字节 = 65 |
全部0条评论
快来发表一下你的评论吧 !