【问题标题】:Float to string using PIC16F1824使用 PIC16F1824 浮点到字符串
【发布时间】:2020-09-18 14:27:08
【问题描述】:

我在使用 PIC16F1824 时遇到了一些问题。 我想转换从 ADC 转换器检索的值并将其传输到 UART。 我使用 MCC 来生成我的代码。 当我逐步调试代码时,电压值与我使用示波器获得的电压值相似。 但是当我想在串行接口上​​打印这个值时,printf 中的参数 %f(或 %.2f)出现错误。

C:\程序 文件\Microchip\xc8\v2.20\pic\sources\c99\common\nf_fputc.c:16:: 警告:(1498)表达式中的指针(未知)可能没有目标 C:\程序 Files\Microchip\xc8\v2.20\pic\sources\c99\common\doprnt.c:66:: 错误: (1250) 找不到用于变量 _dbuf (908) 退出的空间(80 字节) 状态 = 1

这是我的代码

#include "mcc_generated_files/mcc.h"

void main(void) {
    SYSTEM_Initialize();

    uint16_t convertedValue, convertedValue2;
    float voltage, voltage2;
    float temp = 0;
    volatile float sensorRH = 0;
    char buffer[5];
    
    while (1) {
        //                 ADC_SelectChannel(channel_AN0);
        //        ADC_StartConversion();
        //        while (!ADC_IsConversionDone());
        //        convertedValue = ADC_GetConversionResult();
        //        voltage = convertedValue * 0.0048875;
        //        temp = (voltage2 - 0.424) / 0.00625; // LM60

        ADC_SelectChannel(channel_AN2);
        ADC_StartConversion();
        while (!ADC_IsConversionDone());
        convertedValue2 = ADC_GetConversionResult();
        voltage2 = convertedValue2 * 0.0048875; // Tension 5V - Résolution 10 bits (5/1023)   
        sensorRH = (voltage2 - 0.852) / 0.031483; // HIH-4000
        
        printf("ADC converted value = %.2f\n", sensorRH);               
        sprintf(buffer, "%f",sensorRH);
        
    }
}

我也试过:

  • 包括标准输出库:#include <stdio.h>
  • 将浮点值更改为volatile float sensorRH;
  • 在主函数之外声明我的浮点数。这给了我另一个错误:

C:\程序 文件\Microchip\xc8\v2.20\pic\sources\c99\common\nf_fputc.c:16:: 警告:(1498)表达式中的指针(未知)可能没有目标 mcc_generated_files/eusart.c:64:: error: (1250) 找不到空间 (8 字节)变量 _eusartTxBuffer (908) 退出状态 = 1

  • 尝试使用不同大小的缓冲区(与第一个错误相同)的 sprintf 函数。

我正在使用带有 PIC4kit 调试器和 XC8 编译器的 PIC16F1824。 提前致谢

【问题讨论】:

  • char buffer[5];: 5 在我看来有点短,试试char buffer[20]; 并反馈。
  • 您确定要使用浮点数吗?您可以使用整数传输值并在另一台主机上进行计算,这样会更容易一些。或者以0.01°C左右计算温度。
  • 您没有足够的内存。尝试使程序更简单(不使用浮点数,因为浮点数在 PIC16 上很昂贵)。
  • 如果这是一个爱好项目,我建议带一个垃圾箱,将所有带有错误 xc8 编译器的 pic* 东西放在那里,并购买更便宜的 stm32 芯片。如果没有,我建议您删除代码中的所有 float 变量并仅使用整数运算,最好是 Q 数字格式的代码。打印花车既困难又昂贵——我不会在这么小的目标上打印花车。
  • 你几乎不想在嵌入式领域使用 sprintf/printf。奔跑需要一只胳膊和一条腿。手动编写 ftoa/itoa 代码更容易。

标签: c uart pic


【解决方案1】:

您收到的错误意味着您没有足够的 RAM 或闪存,或者换句话说,您使用了太多空间。一种减少少量空间的非常简单的方法是启用优化器。一种减少更多空间的方法是编写不需要太多空间的代码。 printf() 系列也占用了大量空间和浮点数。如果您不能使用 printf()sprintf() 并用整数运算替换浮点运算,这应该是可能的,但它可能会给您带来一些不太精确的计算,这无关紧要,因为您的 ADC 开始时不是很精确与。

【讨论】:

  • you a bit less precise 我认为更准确。浮点数并不精确,它们会根据指数失去精度。整数尽可能精确,您可以轻松准确地预测所有值范围并选择足够大的整数来准确表示您想要表示的内容。
  • @KamilCuk floatint 都完全符合规范/如何对其进行编程。但是当我用int(或longuin32_t,无论如何)替换float时,我大部分时间都不使用几个最高位,所以我确信我永远不会溢出我浪费空间并且丢失了更多信息,因为没有使用所有信息,这与 float 不同。
【解决方案2】:

解决来自编译器的诊断消息:

C:\Program Files\Microchip\xc8\v2.20\pic\sources\c99\common\nf_fputc.c:16:: warning: (1498) pointer (unknown) in expression may have no targets 
 
C:\Program Files\Microchip\xc8\v2.20\pic\sources\c99\common\doprnt.c:66:: error: (1250) could not find space (80 bytes) for variable _dbuf (908) exit status = 1

第一个“警告:(1498)”是生成的,因为 XC8 编译器在处理有时称为不透明指针的东西时很愚蠢。但由于这是参考 Microchip 库代码,您不应更改并且代码实际上是正确的,请忽略此警告。

第二个“错误:(1250)”是您的代码中的错误。您声明的对象数量超过了可用 RAM 的数量。

这是我刚刚为您创建的仅使用整数数学的代码:

#include "mcc_generated_files/mcc.h"

/*
                         Main application
 */
void main(void)
{
#define VREF_VALUE (500)   // ADC VREF voltage in 1/100 of a volt
    uint32_t convertedValue2;
    uint16_t voltage2;
    
    // initialize the device
    SYSTEM_Initialize();

    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts
    //INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();

    while (1)
    {
        // Add your application code
        ADC_SelectChannel(channel_AN2);
        __delay_ms(1000);
        ADC_StartConversion();
        while (!ADC_IsConversionDone());
        convertedValue2 = ADC_GetConversionResult();
        voltage2 = (uint16_t)( (convertedValue2 * VREF_VALUE + 0x8000ul) >> 16 );
        printf("ADC voltage = %1u.%02u\r\n", voltage2/100, voltage2%100);
    }
}

由于您没有提供有关您正在使用的传感器的任何详细信息,因此我无法向您展示整数数学来执行特定于您的传感器的缩放和偏移。

完整的 MPLABX v5.40 项目可以在我的 git hub 存储库here 中找到。

【讨论】:

    【解决方案3】:

    最后,我通过 UART 发送以毫伏为单位的 ADC 值,并在 PC 软件上进行转换。 它不是很干净,但它可以完成工作...... 谢谢

     int i = 0;
     int j = 0;
     while (1) {
            ADC_SelectChannel(channel_AN2);
            ADC_StartConversion();
            while (!ADC_IsConversionDone());
            convertedValue = ADC_GetConversionResult();
            voltage = convertedValue * 0.0048875;
            i = voltage * 100;
           
            __delay_ms(500);                    
            
            ADC_SelectChannel(channel_AN3);     
            ADC_StartConversion();
            while (!ADC_IsConversionDone());
            convertedValue2 = ADC_GetConversionResult();
            voltage2 = convertedValue2 * 0.0048875; 
            j = voltage2 * 100;
                
            printf("ADC voltage = %1u - %1u\r\n", i, j);
    }
    

    【讨论】:

      【解决方案4】:

      非常感谢您的回答。 我想我理解了建议,将值转换为整数,然后将其除以在串行接口中获得浮点值。 我只是对这条线有问题

      voltage2 = (uint16_t)( (convertedValue2 * VREF_VALUE + 0x8000ul) >> 16 );
      

      它给了我一些错误

      我正在使用传感器

      LM60 HIH-4000

      我已使用此代码进行了转换

      voltage = convertedValue * 0.0048875; // VREF : 5V / 10 bits ADC    
      temp = (voltage - 0.424) / 0.00625; // LM60   
      sensorRH = (voltage - 0.852) / 0.031483; // HIH-4000
      

      感谢您的帮助

      【讨论】:

      • “它给了我一些错误”它给了你什么?在计算 voltage2 之前,您的调试器会暂停。后面的值是多少?
      • 我有电压 2 的 0x0003,我将调试器放在 printf 之后一步。我的电压值通常是2.18V(我的convertedValue2是0x000001BF)
      猜你喜欢
      • 2016-01-03
      • 2021-10-09
      • 1970-01-01
      • 2012-06-04
      • 2019-11-28
      • 2019-04-19
      • 2011-06-19
      • 2015-12-17
      • 2013-10-03
      相关资源
      最近更新 更多