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字符串?(以前发生在我身上).
模除法和整数除法可能非常昂贵。我不知道你的特定架构,但我猜那里也很贵。
如果除法和取模两者都需要,则执行其中一项,然后通过乘法/差分得到另一项。
q =p/10;
r = p - q*10;
Run Code Online (Sandbox Code Playgroud)