-1

我有这个“简单”的代码。

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);

当读取ADC_res(引脚上的电压,温度传感器)温度为 0 度或更低时,程序会写入“0.65500”而不是“-3.5”或类似的值。我应该将权利声明为已签名和未签名的 int。任何修复它的提示,或有其他转换方式。

4

2 回答 2

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时,小数部分被丢弃(即,该值被截断为 0)。如果整数部分的值不能用整数类型表示,则行为未定义。61)

61)将整数类型的值转换为无符号类型时执行的求余运算不需要在将实浮点类型的值转换为无符号类型时执行。因此,可移植实浮点值的范围是(−1, Utype_MAX+1)

但是将负值转换为unsigned int无论如何都会产生错误的结果,即使做了余数运算,你想要的是绝对值,所以你应该转换

rem = (unsigned int)fabsf(temprature * 1e1);

那里。

于 2013-01-20T15:58:49.583 回答
1

I think the problem may be coming from the call to the utoa() function.

The utoa() function prototype is generally as follow

char * utoa(unsigned int n, char * buffer, int radix);

In your code you have inverted the two first parameters. You are modifying the ADC structure through this call. I am curious how this could ever be compiled without any error? Any decent compiler would complain about passing an argument which is not a pointer type.

Try with the following

utoa(ADC.res, ADC_num, 10);
于 2013-01-20T14:31:09.643 回答