This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28379D:使用"strtod"函数进行的数字转换不正确

Guru**** 2540720 points
Other Parts Discussed in Thread: LAUNCHXL-F28379D, TMS320F28379D, C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1378703/tms320f28379d-incorrect-numerical-conversion-with-strtod-function

器件型号:TMS320F28379D
主题中讨论的其他器件:LAUNCHXL-F28379D、、 C2000WARE

工具与软件:

您好!  

我目前使用 LAUNCHXL-F28379D、特别是从 SD 卡读取数字数据。 我在使用 strtod 函数时会遇到问题。
下面、我将正在使用的代码和文本文件的内容包含在 SD 卡中。
在调试过程中、我观察到串形式的数据被正确读取并存储在变量"tok"中。 但是、在使用 strtod 函数后、无论输入字符串如何、存储在 Array 中的数值始终为10。

问题可能是什么?

谢谢你。


代码:

/*
* sd_Card.c
*/

#include "driverlib.h"
#include "device.h"
#include "board.h"
#include
#include

#include
#include

双 var1;
双 var2;
双 var3;
双 var4;
双 var5;


uint16_t SDFatFS_CONFIG_COUNT = 1;
SDFatFS_Object sdfatfsObject;

SDSPI_Object SDspiObject ={
spiHandle = mySDCardSPI_BASE、
.piCsGpioIndex = mySDCardCS
};

SDFatFS_Object* SDFatFS_CONFIG []={&sdfatfsObject};

sdspi_handle sdspiHandle = ssdspiObject;

/*字符串转换宏*/
#define STR_(n)#n
#define STR (n) STR_(n)

/*用于 FatFs 的驱动器编号*/
#define DRIVE_NUM 0

FRESULT fresult;
FIL src;

第400章:我是你的

char lettura [array_size];
双数组[20];

空 Lettura_sd (空)

board_init();

SDFatFS_init();
SDFatFS_Handle SDFatFS_Handle = SDFatFS_open (SDspiHandle、DRIVE_NUM);
如果(sdFatFs_Handle == NULL)

while (1);
}

// Lettura file con parametri

char inputfile[]= STR (DRIVE_NUM)":input.txt";

fresult = f_open (& src、inputfile、fa_read);

if (fresult != FR_OK){
while (1);
}

uint16_t bw;

f_read (&lettura src、40、&bw);

char* tok;
char* stopstring;

Tok = strtok (lettura、":");
tok = strtok (NULL、":");

int N_variables = atoi (tok);

内部 I;

对于(I = 0;I<N_variables;I++)

tok = strtok (NULL、":");
array[i]= strtod (tok、&stopstring);
}

fresult = f_close (& src);
if (fresult!= FR_OK)

while (1);
}

Var1 = Array [0];
Var2 = Array [1];
Var3 = Array [2];
var4 = Array[3];
var5 = Array[4];

}

int32_t fatfs_getFatTime (void)

返回0;
}



文本文件:

无变量:5
Var1:17
VAR2:53.4
Var3:0.003
var4:101232
var5:1.30467




  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!  

    我们正在对其进行调查、并将在6月28日(星期五)之前给出回复。  

    谢谢。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已将该线程提请编译器专家的注意。

    请注意,美国度假期间,回复将延迟。  

    感谢您的耐心。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    总之,你是说,对于这个代码...

    tok = "17";
    val = strtod(tok, &stopstring);

    返回的值  strtod 是10.0。  是这样吗?

    谢谢。此致、

    -George.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    是、返回的值strtod为10.0。 此外、尽管进行了后续迭代、其中的值tok会与文本文件中的其他值更新、但返回的值strtod仍为10.0。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我无法重现该结果。  您使用的编译器版本(不是 CCS)是什么?  请显示编译器构建选项。  复制并粘贴选项的文本、而不使用屏幕截图。

    谢谢。此致、

    -George.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很抱歉响应延迟。 我们使用的编译器版本是 TI v22.6.0.1.LTS。 关于编译器构建选项、我附上了工程属性的屏幕截图。 很抱歉、我不确定您需要哪些具体选项。 您能否指导我如何找到您需要的信息?
    谢谢你。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这里是另外一个获得构建选项的方法。   请重新编译整个项目。  方法之一是右键点击工程名称并选择 重新编译工程 .  然后将"Console"(不是问题)视图的内容保存到文本文件。  使用命名的图标 复制构建日志 (较早版本的 CCS)或 将构建日志保存到文件中 (CCS 的较新版本)。  为日志文件命名时、请确保使用文件扩展名 .txt .  请 在下一篇文章中附加该文本文件。

    另一个实验,你可以尝试...尽量增加堆栈。  这有什么用吗?

    谢谢。此致、

    -George.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我尝试增加堆栈、但问题仍然存在。  
    请在下面找到请求的文本文件。

    e2e.ti.com/.../SD_5F00_card.txt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您提交构建选项。  不幸的是、我仍然无法重现问题。

    此时、我对编译器或 RTS 例程感到怀疑 strtod 以及导致问题的原因。  其他方面肯定出错了。  我已经将此线程的责任更改为可以帮助您调试问题的团队。

    谢谢。此致、

    -George.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Giampiero:

    很抱歉耽误你的时间。 您能否举个例子说明 lettura 数组将包含什么内容、以便我能够了解预期的和实际的行为?

    此致、

    Delaney

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!  
    "lettura"数组应包含文本文件中的各个字符(如我附加代码的前一条消息所示、也包括在下面以供参考)。 具体而言,数组中的第一个元素'lettura'是'N',第二个元素是'.',第三个元素是'v',依此类推。 我已经使用断点验证了"lettura"数组是否正确填充了文本文件中的字符。 此外、我检查了断点的"stortok"用法、并且在这种情况下数组"lettura"也已正确分段。

    尝试使用"trtod"将"tok"变量转换为数字时会出现问题。 例如、如果第一个值为-17-尽管"tok"包含一系列字符、其中第一个字符对应于"1"和"7"、则转换为 double 后保存在数组中的值为10.0。 其他值也会出现同样的情况:无论"tok"中存在什么数字、通过"stortod"存储在数组"Array"中的值始终为10.0。
    如果不是转换双精度型字符串、而是使用"trtof"转换为浮点型、则不会出现此问题。  
    我希望这可以澄清问题、并作出令人满意的解释。  
    提前感谢您的答复。  



    文本文件:

    无变量:5
    Var1:17
    VAR2:53.4
    Var3:0.003
    var4:101232
    var5:1.30467


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Giampiero:

    我很抱歉这么晚才答复。 感谢您对问题的解释。 不幸的是、我也无法自行重现这一问题。 我将进入 SPI SD 卡专家、看看他们是否可以使用您提供的完整代码(因为我不熟悉该库)来帮助重现问题。

    此致、

    Delaney

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!  
    我已经进行了进一步的测试、似乎该问题可能与  strtod 函数本身没有直接关系。
    由于没有用于读取我所使用的微控制器(tms320f28379d)的 SD 卡的具体示例、因此我之前向此论坛寻求指导。 建议我执行以下步骤:

    • 在"库资源"中添加与我的微控制器相关的 fatfs.lib 库;
    • 在 C2000编译器中包含路径->包含选项->.../C2000Ware_5_01_00_00/libraries/fatfs
    • 完成此操作后、我 根据论坛中的建议从以下路径 C2000Ware_5_01_00_00\driverlib\f2838x\examples\c28x\sdspi 查看示例文件、该文件适用于与我正在使用的电路板不同的电路板。 我将该示例中的 board.h 和 board.c 文件添加到了我的项目中。
    • 最后、我创建了一个.h 和.c 文件、其中我以另一种类型的电路板为例来读取我的 SD 卡中的数据。

    这是我观察到的情况:只要我使用 strtod 来转换直接在代码中定义的字符串并执行上述所有步骤(添加 SD_card.h 和 sd_card.c (处理 SD 卡读取)除外)、转换就会正常运行。  
    但是、由于我添加了 SD_card.h 和 sd_card.c 文件、代码将无法正常运行。 具体来说、如果我将 C2000 Compiler -> Processor Options->float_support 设置为 fpu32、则 num 中存储的值仍为0.00。 如果我将其设置为 fpu64、它将始终存储10.00。

    我在下面附上了用于测试的代码。

    以下是有效的文件版本:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "driverlib.h"
    #include "device.h"
    
    double num;
    char* stringa = "12.54fd";
    
    //
    // Main
    //
    void main(void)
    {
        Device_init();
        Device_initGPIO();
    
        while(1)
        {
            char* stopstring;
            num = strtod(stringa, &stopstring);
        }
    }



    下面的版本不起作用:

    empty_driverlib_main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "driverlib.h"
    #include "device.h"
    
    #include "SD_card.h"
    
    double num;
    char* stringa = "12.54fd";
    
    //
    // Main
    //
    void main(void)
    {
        Device_init();
        Device_initGPIO();
    
        Lettura_SD();
    
        while(1)
        {
            char* stopstring;
            num = strtod(stringa, &stopstring);
        }
    }


    sd_card.c:

    #include "driverlib.h"
    #include "device.h"
    #include "board.h"
    
    #include <sdspi/sdspi.h>
    #include <sdspi/SDFatFS.h>
    
    uint16_t SDFatFS_config_count = 1;
    SDFatFS_Object sdfatfsObject;
    
    SDSPI_Object sdspiObject = {
            .spiHandle = mySDCardSPI_BASE,
            .spiCsGpioIndex = mySDCardCS
    };
    
    SDFatFS_Object* SDFatFS_config [] = {&sdfatfsObject};
    
    SDSPI_Handle sdspiHandle = &sdspiObject;
    
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    FRESULT fresult;
    FIL src;
    
    #define ARRAY_SIZE 400
    
    void Lettura_SD ()
    {
        Board_init();
    
        SDFatFS_init();
        SDFatFS_Handle sdFatFs_handle = SDFatFS_open(sdspiHandle, DRIVE_NUM);
        if (sdFatFs_handle == NULL)
        {
            while(1);
        }
    
        // Lettura file con parametri
    
        char inputfile[] = STR(DRIVE_NUM)":input.txt";
    
        fresult = f_open(&src, inputfile, FA_READ);
    
        if (fresult != FR_OK) {
            while(1);
        }
    
        fresult = f_close(&src);
        if (fresult != FR_OK)
        {
            while(1);
        }
    }
    
    int32_t fatfs_getFatTime(void)
    {
        return 0;
    }



    我希望这能为解决问题提供更多的见解。

    提前感谢您的帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Giampiero:

    感谢您在后续和调试方面所做的详细工作。 我们将重新创建问题、并在几天内回复您。 再次对拖延表示歉意、并感谢答复。

    此致、

    Arnav