如何将读取的ADC值转换为浮点数?

3

我想将ADC值转换为浮点数。这是我的代码:

uint32_t ADCValue;
char str[15];

          ADCValue = HAL_ADC_GetValue(&hadc1);
          ADCValue=ADCValue*3.3/4095;
          sprintf(str, "%d", Voltage);
          HAL_UART_Transmit(&huart2, (uint8_t*)(&str), 6, 100);
          HAL_UART_Transmit(&huart2, (uint8_t*) "\n\r", 2, 100);
          HAL_Delay(500);

我正在读取3.3V下的4095数值,但我要将3传输到缓冲区。我想要传输精确的电压数值。

2
ADCValue=ADCValue*3.3/4095 --> ADCValue=(ADCValue*10)*33/40950 - LPs
1
什么是“电压”? - Jabberwocky
@Lps,我读到的是33而不是3.3。我认为这不是精确的解决方案。 - coollime
1
@Dummy,你发送了33,但你知道如何在从设备上“解码”。 - LPs
既然您似乎没有进行任何高级数学计算,为什么需要使用浮点数呢?您的MCU甚至有FPU吗? - Lundin
显示剩余9条评论
4个回答

6

在这里似乎没有必要使用浮点数,它们会使代码变得不必要的缓慢。可以简单地这样做:

uint32_t millivolts = ADCValue*3300/4095.

输入4095,你将得到结果3299毫伏。这可能比使用浮点数更准确,因为存在浮点误差。


虽然我同意在这里不需要使用浮点数,但是没有理由认为它们在这里会更不准确。除非你有依据,否则最好不要加上这样的评论。 - user694733
如果使用CMSIS DSP浮点函数,我们必须将ADC输出转换为浮点数。这很糟糕,使ADC DMA无用,如果硬件可以直接输出浮点数会怎样呢? - mohammadsdtmnd

5
您可能需要这个:
ADCValue = HAL_ADC_GetValue(&hadc1);
float fADCValue = (float)ADCValue*3.3 / 4095.0;
int txlength = sprintf(str, "%.2f", fADCValue);
HAL_UART_Transmit(&huart2, (uint8_t*)(&str), txlength, 100);
HAL_UART_Transmit(&huart2, (uint8_t*) "\n\r", 2, 100);
HAL_Delay(500);

注意:仅当您的平台上可用float类型时,此方法才有效。

若浮点型不可用,您可以使用以下方法:

ADCValue = HAL_ADC_GetValue(&hadc1);
ADCValue = ADCValue * 330 / 4095;
int len = sprintf(str, "%d.%02d", ADCValue / 100, ADCValue % 100);
HAL_UART_Transmit(&huart2, (uint8_t*)(&str), leb, 100);
HAL_UART_Transmit(&huart2, (uint8_t*) "\n\r", 2, 100);

这只是一个快捷的技巧,肯定还有改进的空间。
演示在这里

我的平台可能不支持浮点类型。 - coollime
1
@Dummy,请查看我的更新答案。现在有一种解决方案,适用于您的平台上没有浮点数运算的情况。 - Jabberwocky
@MichaelWalz,它起作用了。现在我正在读取浮点数。谢谢你。 - coollime
@4386427 不错的想法,回答已更新。但仍然无法发现其他与小数有关的问题。 - Jabberwocky
1
你需要在格式字符串中加入“02”以表示小数部分:http://ideone.com/RBJCmn - user694733
@Dummy 程序之前不太正确,现在已经修正了答案。 - Jabberwocky

0

这应该能解决问题

float Adcvalue_f;
uint32_t ADCValue;
char str[15];
....
ADCValue = HAL_ADC_GetValue(&hadc1); 
ADCValue_f =ADCValue*3.3/4095;
sprintf(str, "%2.2f", AdcValue_f);   //Adjust the .2 as per required precision
HAL_UART_Transmit(&huart2, (uint8_t*)(&str), 6, 100);
HAL_UART_Transmit(&huart2, (uint8_t*) "\n\r", 2, 100);

用这段代码,我只读取到了空数据 :) 我做错了什么? - coollime
在其他UART或str处出现空数据。 - Rishikesh Raje

0
除其他优秀的答案外,请考虑:
整数除法截断了数学商的小数部分。
相反,执行四舍五入的整数除法。对于无符号整数运算,在除法之前添加一半的除数。
// ADCValue=ADCValue*3.3/4095;

unsigned Voltage = // millivolts
Voltage = (ADCValue*3300 + 4095/2)/4095.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接