【问题标题】:How to convert uint32_t to double or float and print?如何将 uint32_t 转换为 double 或 float 并打印?
【发布时间】:2015-11-13 21:44:05
【问题描述】:

我正在使用模数转换器读取 0 到 3.3V 的电压值。 ADC 提供从 0x000x0FFF(0 到 4095)的输出。我想用两位小数打印电压读数。我已经阅读了许多答案,但我尝试过的都没有奏效。这是我的代码:

uint32_t pui32ADC0Value[1]; // ADC0 data value
double D0v;                 // Decimal value

// Read value from ADC
ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

// Convert to decimal
D0v = (double)pui32ADC0Value[0] / 4095 * 3.3;

// Print to console
UART0printf("\n\r> D0 = %.2d V", D0v);

我得到的输出是:D0 = ERROR2d V

pui32ADC0Value 打印没有任何问题并给出预期值,所以我知道它正在工作。

这个错误是什么意思?

注意:UART0printf 是我正在使用的 TIVA TM4C 微控制器上的预定义 UART 功能。

更新:我错误地认为UART0printfprintf 相同,因为我之前曾将它用于%u%s%x。但是对于数字,它只支持%c%i%u。我正在重新编写我的代码,如果我没有得到任何地方,我会更新。

更新 2: 我可以做这样的事情吗?我知道它会错误地四舍五入...

uint32_t pui32ADC0Value[1]; // ADC0 data value
uint32_t D0v[2];                 // Decimal value

// Read value from ADC
ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

// Convert to decimal
for ( int i = 0; i <= 2; i++){
    D0v[i] = (pui32ADC0Value[0]/10^i) / 4096 * 3.3;
}

// Display the AIN0 (PE0) digital value on the console.
UART0printf("\n\r> D0 = %d.%d%d V", D0v[0],D0v[1],D0v[2]);

【问题讨论】:

  • 什么是UART0printf?您确定它支持与 C 的 printf 相同的格式字符串语法吗?
  • 为什么 uint32_t pui32ADC0Value[1]; ?而不是 uint32_t pui32ADC0Value; ??
  • @Nandu:我会冒险假设ADCSequenceDataGet 需要一个指向uint32_t 的指针,所以uint32_t[1] 获得了免费的隐式转换。不过我认为这不是一个好主意。
  • 这是来自 ADC 制造商。对 ADCSequenceDataGet 的调用只会得到数组的一个元素,所以我这样定义它。
  • 好吧,我撒了谎,原来 UART0printf 与 printf 不同——它只支持 %d %i 和 %u... 这意味着我有一个不同的问题。我会关闭这个。

标签: c embedded stellaris


【解决方案1】:

如果此功能有效printf 喜欢:

UART0printf("\n\r> D0 = %.2f V\n", D0v);

如果您使用以下代码,您的代码可能会运行得更快一些:

D0v = (double)pui32ADC0Value[0] * (3.3 / 4095);

编译器将预先计算3.3 / 4095 并执行单次浮点乘法运算。否则,可能会先进行除法(这通常比乘法花费更多的 CPU 周期),然后再进行乘法 * 3.3

此外,由于您似乎只需要 2 位精度,您可以使用 float(单精度)而不是 double。它可能执行得更快(但可能更慢),这取决于平台。

问题中 UPDATE2 的更新:

试试这个:

uint32_t pui32ADC0Value[1]; // ADC0 data value
uint32_t D0v;               // Decimal value

// Read value from ADC
ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC0Value);

// Convert to millivolts
D0v = pui32ADC0Value[0] * (3300.0 / 4095);

// Display the AIN0 (PE0) digital value on the console.
UART0printf("\n\r> D0 = %d mV", D0v); // If it's OK for you to display in mV
UART0printf("\n\r> D0 = %d.%03d V", D0v / 1000, D0v % 1000); // Print in V

【讨论】:

  • @Dai 仍然需要进行整数除法,在特定平台上我已经看到单精度乘法(浮点数)比整数除法更快。
  • 我不认为float 通常比double 快,我很确定在大多数架构上它们的计算方式相同。唯一的区别是存储期间的准确性。
  • @MooingDuck 对,这可能取决于实际平台。但是在没有 FPU 的微控制器上(在 SW 中实现了 float div),我认为它会更快。
  • 我有FPU,这对它有什么影响?
  • @LShaver 那很好,我不能准确地说哪个更快(floatdouble)。您可以通过使用计时器来测量执行来确定(或查看 CPU 指令集架构以获取有关此的详细信息)。但如果操作不是那么频繁,也许就不要费心了。
【解决方案2】:

没有像printf这样的格式字符串

%.2d

格式化程序%d 表示整数,因此没有小数精度选项。 %. 被解析为错误(因为它不存在),2d 将其逐字输出到您的输出中。

The formatter for floating-point values is %f,所以:

%.2f

然而,所有这一切都是基于UART0printfprintf 相同的假设,您在问题中没有指出它与printf 相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2021-06-21
    • 2014-05-11
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多