我有这个“简单”的代码。
union
{
unsigned int res;
char bytes[2];
} ADC;
char ADC_num[5];
float temprature;
void vis_temp (void) // Show temp..
{
signed int l, length;
unsigned int rem;
GO_nDONE=1; // initiate conversion on the channel 0
while (GO_nDONE) continue;
ADC.bytes[0]=ADRESL;
ADC.bytes[1]=ADRESH;
utoa(ADC_num, ADC.res, 10);
temprature = (float) ADC.res * 478.1 / 1024;
temprature = temprature - 50.0;
l = (signed int) temprature;
temprature -= (float) l;
rem = (unsigned int)(temprature* 1e1);
sprintf(&ADC_num, "%i.%u", l, rem);
当读取温度为0度或更低的ADC_res
(引脚电压,温度传感器)时,程序会写入“0.65500”而不是“-3.5”或类似值。
我应该将右边声明为signed和unsigned int。
任何修复它的提示,或者有另一种方法来修改它。
答案 0 :(得分:2)
temprature = (float) ADC.res * 478.1 / 1024;
temprature = temprature - 50.0;
假设现在temprature
的值为-x.yz
。
l = (signed int) temprature;
现在l = -x
和
temprature -= (float) l;
temprature = -x.yz - (-x) = -0.yz
。
rem = (unsigned int)(temprature* 1e1);
与10相乘,并转换为unsigned int
。通常,这会导致未定义的行为(6.3.1.4(1)):
当实数浮动类型的有限值被转换为除
_Bool
以外的整数类型时,小数部分被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为是未定义的。 61)61)当将实数浮点类型的值转换为无符号类型时,无需执行将整数类型的值转换为无符号类型时执行的剩余操作。因此,便携式实际浮动值的范围是
(−1, Utype_MAX+1)
。
但是将负值转换为unsigned int
无论如何都会产生错误的结果,即使剩余的操作已经完成,你想要的是绝对值,所以你应该转换
rem = (unsigned int)fabsf(temprature * 1e1);
那里。
答案 1 :(得分:1)
我认为问题可能来自对utoa()
功能的调用。
utoa()
函数原型通常如下
char * utoa(unsigned int n, char * buffer, int radix);
在您的代码中,您已经反转了两个第一个参数。您正在通过此调用修改ADC结构。我很好奇如何在没有任何错误的情况下编译它?任何体面的编译器都会抱怨传递一个不是指针类型的参数。
尝试使用以下
utoa(ADC.res, ADC_num, 10);