这个C函数写得不好吗?

Nat*_*ate 5 c embedded floating-point microcontroller pointers

char byte_to_ascii(char value_to_convert, volatile char *converted_value) {

 if (value_to_convert < 10) {
  return (value_to_convert + 48);
 } else {
  char a = value_to_convert / 10;
  double x = fmod((double)value_to_convert, 10.0);
  char b = (char)x;
  a = a + 48;
  b = b + 48;
  *converted_value = a;
  *(converted_value+1) = b;
  return 0;
 }
}
Run Code Online (Sandbox Code Playgroud)

此函数的目的是获取0到99的unsigned char值,并返回它在0-9的情况下的ascii等效值,或者操作一个小的全局字符数组,该数组可以在函数完成后从调用代码引用.

我问这个问题是因为同一供应商的两个编译器以不同的方式解释这个代码.

编写此代码是为了将通过RS485发送的地址字节解析为可以轻松传递给send-lcd-string函数的字符串.

该代码是为PIC18架构(8位uC)编写的.

问题是特定编译器的免费/评估版本生成了完美的汇编代码,但在遭受性能损失的情况下工作,但是付费且假设优越的编译器能够更高效地生成代码,代价是能够引用我所有字节数组的地址用于驱动我的液晶显示器上的图形.

我知道我通过使用专有的编译器为一个不太典型的架构在水中放了很多泥,但我希望那里的人有一些建议.

谢谢.

小智 7

我肯定会避免在PIC上使用任何浮点数.而且我会 - 不要 - 使用任何分歧.你有多少次看到将非ascii字符发送到LCD?你可以将它保存到LCD的内存中,然后通过它的内存位置调用吗?

这是我的代码中除以10的结果,注意它需要完成的17个周期.想想需要多长时间,并确保没有其他等待.

61:                         q = d2 / 10;
 01520  90482E     mov.b [0x001c+10],0x0000
 01522  FB8000     ze 0x0000,0x0000
 01524  2000A2     mov.w #0xa,0x0004
 01526  090011     repeat #17
 01528  D88002     div.uw 0x0000,0x0004
 0152A  984F00     mov.b 0x0000,[0x001c+8]
Run Code Online (Sandbox Code Playgroud)

如果在代码中执行任何浮点操作,请在编译后查看程序存储器,在符号选项卡上查找(这样您就可以实际读取它)并查找需要包含的浮点代码.您会在_reset标签后很快(ish)找到它靠近顶部(取决于您的代码).

我的第223行开始,内存地址为001BC,_ floatsisf,继续通过几个附加标签(_fpack,_divsf3等),以_funpack结束,最后一行为535,内存地址为0042C.如果你可以处理(42C-1BC = 0x270 =)624字节的丢失程序空间,那很好,但有些芯片只有2k的空间而且这不是一个选择.

如果可能的话,而不是浮点,尝试在基数2中使用定点算术.

至于无法引用LCD中的所有字节数组,你是否检查过以确保你没有尝试发送空(这是一个很好的地址),但它通过代码检查结束一个ascii字符串?(以前发生在我身上).

  • 哇,这是很多非常好的见解.我做了检查,我的浮点代码确实嚼了很多空间.检查null是好的,但不幸的是,这似乎不是问题.我能够轻松地放弃我之前的代码并使用:q = p/10; r = p - q*10; 正如别人所说.我真的让它变得比必要的困难得多.在嵌入式开发方面,我有点绿色,并且来自windows dev背景,我常常忘记尽可能地记忆.我确信随着我的程序规模的增长,这将会改变. (2认同)

Any*_*orn 4

模除法和整数除法可能非常昂贵。我不知道你的特定架构,但我猜那里也很贵。

如果除法和取模两者都需要,则执行其中一项,然后通过乘法/差分得到另一项。

q =p/10;
r = p - q*10;
Run Code Online (Sandbox Code Playgroud)

  • 如果您无论如何都要进行除法,则在大多数体系结构中您可以“免费”获得余数。您甚至可能不必使用内联汇编,因为任何具有优化头脑的 C 编译器都会自动使用它。 (3认同)