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.

[参考译文] MSP430FR2355:浮点指针存在代码问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1116220/msp430fr2355-having-code-issues-with-pointer-to-float

器件型号:MSP430FR2355

有人能帮我解决这个问题吗...

我有  

float avg = 0;
uint16_t *pTx = &avg;

Avg 是一组 A/D 转换、在运行时看起来不错(例如 avg = 3834.0)

我将此值发送给函数:

UCA1TXBUF = itoa((((uint16_t)(avg)) >> (4 * lowByte)) & 0x0F);

它的传输很好…

我想使用指针、但是 bcz 我将调用各种数据的函数。  我遇到的问题是、当我调用函数时、我将传递一个浮点值(如上所示)、但是有时会调用该函数、而我将向该函数传递一个 volatile uint16_t。   我如何描述指针/对其进行拼写以解决此问题?

谢谢

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

    使用 UNION。

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

    我以前从未使用过联合体(负责固件的硬件人员)。

    我在 h 文件中具有以下内容:

    extern __vo uint16_t pwmDiv;
    union rtnVals
    {
        float avg;
        __vo uint16_t pwmDiv;
    };
    

    是的

    #pragma LOCATION (pwmDiv, 0x1800);
    #pragma PERSISTENT(pwmDiv);
    __vo uint16_t pwmDiv = 50;
    
    
    float avg = 0;
    
    
    rtnVals *prtvVals;
    

    c 文件中 UART 中的良性函数调用为:

              UCA1TXBUF = itoa((((uint16_t)(*pTx)) >> (4 * lowByte)) & 0x0F);
    

    不知怎么说、我需要让 PTX 指向 prtVals????  我不知道如何操作?

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

    为了便于阅读、我尝试将代码放入单个文件中...

    //IN H FILE
    extern __vo uint16_t pwmDiv;
    union rtnVals
    {
        float avg;
        __vo uint16_t pwmDiv;
    };
    
    
    //IN C FILE
    
    #pragma LOCATION (pwmDiv, 0x1800);
    #pragma PERSISTENT(pwmDiv);
    __vo uint16_t pwmDiv = 50;
    
    
    uint16_t *pTx;
    
    union rtnVals *prtnVals;
    
    
    prtnVals->avg = (float)sum / numberADSamples;
    pTx = (uint16_t*)(&prtnVals);
    UCA1IE |= UCTXIE;
    
    //ISR piece
          case USCI_UART_UCTXIFG:
    //          UCA1TXBUF = itoa((((uint16_t)(*pTx)) >> (4 * lowByte)) & 0x0F);
              UCA1TXBUF = itoa((((*pTx)) >> (4 * lowByte)) & 0x0F);
              while (!(UCA1IFG & UCTXIFG)); //wait until buffer empty
    
    

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

    您希望将联合值指针而不是值:

    UNION rtnVals

       floatp * avg;
       __vo uint16_t *pwmDiv;
    };

    联合值 rvals;

    rvals.floatp =&floatToSave;

    但这都是基本的 C

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

    我很抱歉,但 C 中的指针并不是“基本”的。您的回复很简洁,尽管对那些每天都有正确固件的人来说可能是很好的,但对那些试图学习的人没有太多帮助。

    我的问题在这方面有点复杂、我觉得我没有完全传达...

    简而言之,我有一个 UART,想要将数据发送到 PC ...该数据是配置数据还是实时 A/D 数据。  配置数据将根据请求转储5个位置。  我希望 UCA1TXBUF 指向一个部分、最好是 ISR 内的一个指针。 在启用 ISR 以发送之前、我将在 main 内每次更新指针。   

    根据您上次的评论、我已将此内容介绍得更详细、但现在您建议使用 pointers...please。请参阅下面我的尝试、因为我即将结束(或我认为如此)

    我有一个 union、它包含两个声明、一个 float 和一个 uint16_t:

    union rtnVals
    {
        uint16_t memRecall;
        float liveData;
    };
    

    我创建了一个此示例以及指向它的指针:

    union rtnVals t_rtnVals = {0};
    union rtnVals *prtnVals = &t_rtnVals;
    

    在代码的不同部分、我初始化 prtnVals:

    情况1:(pFRAM 是一个易失性 uint16_t;它指向存储器中的区域)

                            prtnVals->memRecall = *pFRAM;
    

    案例2:

                        prtnVals->liveData = (float)sum / numberADSamples;
    

    使用 UART、我想使用以下公式将此数据发送回 PC:

    UCA1TXBUF = itoa((((*pTx)) >> (4 * lowByte)) & 0x0F);

    其中 PTX 已定义为 uint16_t 并采用 prtnVals 的值:

    pTx = (uint16_t*)(prtnVals);

    当我调试 prtnVals 时、prtnVals 看起来总是正确的。 ptx 仅在 prtnVals -> memRecall 时看起来是正确的。  如果我在下面尝试交换联合体中的元素、但它没有影响。  如果浮点值必须是4字节,但这也不起作用,我还尝试添加+4至 prnVals。。。有人能告诉我如何解决这个问题吗?

    您可能会问为什么 PTX……这是因为我想固定 UCA1TXBUF 的公式,并且不想每次都更改它,因为调用 pFRAM 时将提前返回最多5个配置值。  因此,如果代码要读取实时数据,它将读取 A/D,如果要读取配置,它将读取多达5个 uint16_t 的值....

    感谢您的任何帮助

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

    您的问题似乎是、您希望使用单个位置存储浮点值或整数、但中断服务例程无法告知该位置当前存储的内容。

    实际上、更糟糕的是、您的代码似乎对整数和浮点值的处理是相同的。

    或者尝试更简单的方法。  通过将两个样本的幂相加、将变量"SUM "设为定点值。 (2、4、8)。 使用少量样本时、不会使整数溢出。

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

    非常感谢。。。我仍然有点模糊,但我做了我认为你所建议的,现在我似乎至少能够获得实时数据和内存配置返回的正确值。  我进行了以下代码更改:

    1. liveData 不再是浮点值

    union rtnVals
    {
        uint16_t liveData;
        uint16_t memRecall;
    };
    

    2.删除了(浮动)的排印

    prtnVals->liveData = sum / numberADSamples;

    3.将 PTX 更改为:(找到正确的&和*组合是一场斗争)

    pTx = (uint16_t *)(*(&prtnVals));

     ISR 公式现在超级基本:

    UCA1TXBUF = itoa((*pTx >> (4 * lowByte)) & 0x0F);

    手指交叉我不会溢出或任何东西、而且我也可以将 PTX 更改为其他配置数据!

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

    只是为了帮助一点、因为您提到的您更多的是硬件人员。 如果您的代码现在可以正常工作,我会保留它,但为了将来在 UNION 上参考,我会检查此文件(不是 TI 站点) https://www.tutorialspoint.com/cprogramming/c_unions.htm 。 它应该对联合的概念提供更多帮助。

    它可能是我们未看到的其他代码部分、但如果您要使用相同的数据类型、则不再需要 UNION、因为 UNION 的特殊用途是在同一存储器地址上具有不同的数据类型。 不过、您可以保留 union 以将这些值组合在一起、或保留它以使代码正常工作。  

    对于指针、&用于获取存储器地址(参考)、而*用于获取该存储器地址处的值(参考)。 *(&V)与执行 val 相同、因此可以删除任何一对*&。

    因为您的 prtnVals 是一个指针

     

    pTx = (uint16_t*)(prtnVals);

    将是等效的、但这是因为 prtnVals 是 union、当前可以键入 casted 到 uint16_t 在旧代码中、如果最后一次更改是浮点、则此类型转换将不起作用。  

    此致、

    Luke

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

    感谢您的回答!  我会回到代码进行这些更改并测试它们...我相信我尝试了你显示的线路,但没有运气...会再试一次

    是的,就两个数据点而言是相同的...我想把一个作为浮点,但在我按照 David 的建议将其更改为定点之前,它无法工作

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

    是的、David 的建议是解决您看到的问题的方法、更改我提到的行只能起作用、因为所有数据都是相同的类型。 类型转换指针的工作方式与类型转换数据类型不同。  

    此致、

    Luke