C等式返回的值不同于我的计算值

时间:2015-03-29 18:20:00

标签: c

我有这个等式来解决温度传感器的温度问题。

变量是:

unsigned char AD_DATA; values is usually 100- 110;
int TEMP;

原始等式:

TEMP = 50 - (AD_DATA * 175) / 1000;

我把它改为:

TEMP = 500 - (AD_DATA * 1750) / 1000;

原因是因为TEMP是一个整数,因此在第一个等式中,当计算出有小数时,它会自动舍入,所以我改变了它,以便小数将包含在数字中。 / p>

我之所以不使用float,是因为在我使用的MCU中,每当我在ISR(中断服务程序)中声明一个浮点变量时,它都会返回一个错误,因此我需要在使用INT时才有创意, double也会返回错误。

  

现在使用AD_DATA值100

第一个等式将导致: 32.5 ,但由于它是一个int,现在是33。

第二个等式应输出325,但在我的输出中 521

我需要在显示中包含小数,因此将它包含在等式中非常重要。

我的ISR例程:

__interrupt void ADC_int(void){
IO_ADCSH.bit.INT = 0;
AD_DATA = IO_ADCRLH.DATA8;
TEMP = 500 - (AD_DATA * 1750) / 1000;
}

MCU规格

int 2bytes
long 4bytes
unsigned char 1byte

2 个答案:

答案 0 :(得分:5)

作为快速黑客,您可以将(AD_DATA * 1750) / 1000替换为(AD_DATA * 7) / 4

如需更多想法,请阅读以下内容。


请注意,通过更改

TEMP = 50 - (AD_DATA * 175) / 1000;

TEMP = 500 - (AD_DATA * 1750) / 1000;

您更改了TEMP变量的含义。假设它意味着“温度”(并不重要),它意味着“以度为单位的温度”,现在它意味着“温度以1/10度为单位”。但是,为什么你乘以10?为方便起见,我想 - 您没有义务为您的单位使用10的幂。您可以使用任何其他数字,只要您记住它是什么,并相应地处理结果TEMP(例如,将其打印出来时除以10)。因此,使用的最佳数字是40:它消除了一个除法(或者更确切地说,将它推迟到后面的代码行),因此避免了精度的损失。

TEMP_MULTIPLIED_BY_40 = 2000 - AD_DATA * 7;

答案 1 :(得分:3)

根据您提供的信息我的第一个猜测, 当AD_DATA乘以1000时,寄存器长度为16位,导致操作数溢出。

int可以容纳的最大值是32762(从我的头顶开始,更像是0x7FFF),甚至无符号它不足以保持AD_DATA * 1000(在你的情况下将是18 * 1000 = 18000),值将被截断为16位,在此过程中给出一个负数。

您可以通过在表达式中指定运算符的长度并将AD_DATA转换为32位字来解决此问题。