Psi*_*Psi 7 c floating-point microchip truncation integer-division
下面是我在C中编写的主要功能(对于PIC18F8722微处理器),试图以unsigned int函数设置的特定频率驱动2个多路复用7段显示get_ADC_value().显示屏还显示当前的多路复用频率.该频率范围设置#define在LAB_Fmin和LAB_Fmax范围内,并且必须get_ADC_value()随着从0增加或减少到255 而缩放.
但是这段代码不起作用,因为我认为有隐式转换int为floatat freq =.
挑战是使用浮点数修复此错误,并仅使用整数类型(int,char...)查找替代方法.
while (1) {
unsigned int x, y, z;
float freq, delay;
x = get_ADC_value();
y = x & 0b00001111;
z = (x & 0b11110000) >> 4 ;
freq = LAB_Fmin + (((LAB_Fmax) - (LAB_Fmin))/ 255)*x ;
delay = 1/(freq*1000); // convert hZ to ms delay accurately
LATF = int_to_SSD(y);
LATH = 0b11111110; //enable 7seg U1
for (unsigned int i = 0; i<(delay) ; i++){
Delay10TCYx(250); //1ms delay
}
LATF = int_to_SSD(z);
LATH = 0b11111101; //enable 7seg U2
for (unsigned int j = 0; j<(delay) ; j++){
Delay10TCYx(250); //1ms delay
}
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*ger 16
C被定义为int使用整数除法来划分s,并且只有当存在浮点时才首先将其他ints "提升" 为floats.请注意,如果将其分配给float- 如果右侧全部为ints,则除法将全部为整数,并且仅在最终赋值时将C转换为int结果float.
所以,用你的线:
freq = LAB_Fmin + (((LAB_Fmax) - (LAB_Fmin))/ 255)*x ;
Run Code Online (Sandbox Code Playgroud)
这一切都取决于什么LAB_Fmax和LAB_Fmin是什么.什么freq或者什么都没关系x,因为由于括号迫使分裂成为第一个,所以已经完成了"损害".
如果这些LAB_F变量是ints,那么使用浮点除法的最简单方法是通过使用小数点简单地告诉C你想要通过使常量255成为浮点数而不是整数:( 255.或者255.0不那么微妙).
如果你只想使用整数运算,那么通常的建议是在任何除法之前进行所有乘法运算.当然,这种运行四溢的中间结果的风险-帮助是,你可以使用的类型long.将您的LAB_F或x变量定义为long,并最后进行除法:
freq = LAB_Fmin + (((LAB_Fmax) - (LAB_Fmin)) * x / 255);
Run Code Online (Sandbox Code Playgroud)
Lun*_*din 10
代码审查:
unsigned int x, y, z;避免在嵌入式系统上使用原始整数类型.应始终使用stdint.h中的精确宽度类型,以便准确了解所使用的大小.如果您无权访问stdint.h,请自行键入dede这些类型.
float freq, delay;通常应避免在大多数嵌入式系统上使用浮点数.特别是在没有FPU的8位MCU上!这将导致软件定义的浮点数非常慢且占用大量内存.你似乎没有理由在这个程序中使用浮点数,看起来你应该能够用uint16_t或更小的方式编写这个算法,除非你有极高的精度要求.
x = get_ADC_value(); 由于您似乎只对8位ADC读取感兴趣,为什么不使用8位类型?
请注意,二进制数字文字不是标准C.
((LAB_Fmax) - (LAB_Fmin))/ 255这看起来很可疑.首先,这些是整数还是浮点数?它们的大小是多少?你的问题的答案取决于那个.通过将文字交换到255.0f您可以强制转换为浮动.但你确定分裂应该是255吗?而不是256?
i<(delay).您应该始终避免在循环条件中使用浮点表达式,因为它会使循环不必要地变慢并且可能导致浮点不准确错误.而且,括号没有任何意义.
总的来说,你的程序遭受"草率打字",这意味着程序员没有考虑每个表达式中使用的类型.请注意,文字也有类型.隐式转换可能会导致很多这些表达式在太大的类型上计算,这对PIC来说是个坏消息.我建议阅读"平衡",即通常的算术转换.
这种"邋typing的打字"会让你的程序变得非常臃肿和缓慢,因为没有任何好处.您必须记住,PIC可能是仍然制造的代码效率最低的MCU.为任何8位MCU编写C代码时,应避免使用大于8位的类型.特别是,你应该避免像瘟疫一样的32位整数和浮点数.
您的程序会将所有数据重新调整为可以简化程序员思考的类型.这是一个常见的设计错误 - 相反,您的程序应该使用易于处理器使用的类型.例如,您可以使用计时器滴答作为单位,而不是毫秒.
你对整数除法是正确的.改成
freq = LAB_Fmin + (((LAB_Fmax) - (LAB_Fmin)) / 255.0)*x;
^^
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3322 次 |
| 最近记录: |