如何通过UART将多个浮点数从stm32f103发送到PC?

发布于 2025-01-13 13:11:11 字数 2481 浏览 5 评论 0原文

我希望我的电脑从微控制器接收浮点值,以便根据该值绘制图表。我已经可以让微控制器从PC接收值了。我正在使用联合将浮点数解码为字节。

我在微控制器和 PC 插座上的结合(我通过蓝牙、HC-06 将我的 PC 连接到微控制器,并使用 HC-06 通过 uart 连接到我的 stm32f103)

union
{
    float data;
    struct
    {
        uint8_t bytes[4];
    };
}Float[250];

如何将字节从 STM32F103 传输到 PC:我首先将我的值放入数组,然后在发送之前将元素放入联合字节中。 (该值不断更新,我之前尝试发送整个数组但似乎失败)。

for(int i = 0; i < 250; i++)
        {
            Float[i].F = data[i];
        }

        for(int i = 0; i < 250; i++)
        {
            for(int j = 0; j < 4; j++)
            {
                HAL_UART_Transmit(&huart1, (uint8_t* )&Float[i].bytes[j], 1, HAL_MAX_DELAY);

                while(USART1->SR != USART_SR_TC){};
            }
        }
        HAL_UART_Transmit(&huart2, (uint8_t*)"Transmitted to PC\n", 18, HAL_MAX_DELAY);

        value = 0;
        memset(data, 0, 250);
        counter = 0;

在我的电脑中,我通过 rfcomm 接收数据

status = recv(s, buffer, 1000, 0);

,然后将字节解码为浮点数:

for(int i = 0; i < 250; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            Float[i].bytes[j] = buffer[j + rcv_counter];
        }
        rcv_counter += 4;
        
    }

但是,当我收到从微控制器发送的字节并解码它们时,我得到的全部为零......我不确定原因是什么。我也很高兴人们提供了其他一些方法来做到这一点。 。我的主要目标只是通过 uart 将浮点值从微控制器传输到 PC。非常感谢。

只是更新我的进度:

现在我只能从 stm32f103 接收一次真正的浮点值,如果我继续请求 stm32f103 发送值,它只会发送零,我不太确定为什么会发生这种情况。

float test[5] = {1.0, 5.6, 4.5, 2.3, 8.9}; // float value to be send
HAL_UART_Transmit(&huart1, (uint8_t* )test, sizeof(test), HAL_MAX_DELAY); // Transmit from stm32f103 to PC

union
{
    float data;
    struct
    {
        uint8_t bytes[4];
    };
}Float[5]; // Union to decode bytes

if(recv(s, buffer, 20, 0) >= 0)
            {
                cout << "Message received from bluepill" << endl;
          

                for(int i = 0; i < 5; i++)
                {
                    for(int j = 0; j < 4; j++)
                    {
                        Float[i].bytes[j] = buffer[j + rcv_counter];
                    }
                    rcv_counter += 4;
                    
                }
                for(int i = 0; i < 5; i++)
                {
                    cout << Float[i].data << endl;
                }
            } // Way to receive 5 float value and print to console

当我尝试这个时,我只能成功一次,从第二次开始,我一直收到0,谢谢帮助

I want my PC to receive float value from the microcontroller so as to plot graph based on the value. I already can let microcontroller to receive value from PC. I am using union decode the float into bytes.

My union in both microcontroller and PC socket(I connect my PC to microcontroller through bluetooth, HC-06 and use HC-06 to connect to my stm32f103 through uart)

union
{
    float data;
    struct
    {
        uint8_t bytes[4];
    };
}Float[250];

How I transmit bytes from STM32F103 to PC: I first put my value in an array and then put the elements inside the union bytes before sending. (The value is keep updating, I tried to send the whole array before but seems failed).

for(int i = 0; i < 250; i++)
        {
            Float[i].F = data[i];
        }

        for(int i = 0; i < 250; i++)
        {
            for(int j = 0; j < 4; j++)
            {
                HAL_UART_Transmit(&huart1, (uint8_t* )&Float[i].bytes[j], 1, HAL_MAX_DELAY);

                while(USART1->SR != USART_SR_TC){};
            }
        }
        HAL_UART_Transmit(&huart2, (uint8_t*)"Transmitted to PC\n", 18, HAL_MAX_DELAY);

        value = 0;
        memset(data, 0, 250);
        counter = 0;

In my PC, i receive the data through rfcomm

status = recv(s, buffer, 1000, 0);

Then decode the bytes into floats:

for(int i = 0; i < 250; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            Float[i].bytes[j] = buffer[j + rcv_counter];
        }
        rcv_counter += 4;
        
    }

However, when i received the bytes send from microcontroller and decode them, i got all zero... I am not sure what is the reason. I also glad people provide some other way to do this. . My main goal is just to transmit float values from microconttroller to PC through uart. Thx very much.

Just to update my progress:

Now I can receive true float value from stm32f103 only once, if I continue requesting stm32f103 to send value, it will send only zero, I not so sure why is this happening.

float test[5] = {1.0, 5.6, 4.5, 2.3, 8.9}; // float value to be send
HAL_UART_Transmit(&huart1, (uint8_t* )test, sizeof(test), HAL_MAX_DELAY); // Transmit from stm32f103 to PC

union
{
    float data;
    struct
    {
        uint8_t bytes[4];
    };
}Float[5]; // Union to decode bytes

if(recv(s, buffer, 20, 0) >= 0)
            {
                cout << "Message received from bluepill" << endl;
          

                for(int i = 0; i < 5; i++)
                {
                    for(int j = 0; j < 4; j++)
                    {
                        Float[i].bytes[j] = buffer[j + rcv_counter];
                    }
                    rcv_counter += 4;
                    
                }
                for(int i = 0; i < 5; i++)
                {
                    cout << Float[i].data << endl;
                }
            } // Way to receive 5 float value and print to console

When i try this, i can only success one time, start from second time, i keep receiving 0, thx for helping

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深海少女心 2025-01-20 13:11:12

创建一个 TX 缓冲区:

#define TXBUFSIZE nn
#define FARRAYSIZE mm
uint8_t TXBuffer[TXBUFSIZE] = {0};
float myArray[FARRAYSIZE] = {0,};

其中 nn 是您需要发送的字节数。如果你想在一个包中发送 250 个浮点值,这将是 250 * sizeof(float)

在 while 循环中填充缓冲区:

uint16_t size = FARRAYSIZE * sizeof(float);
uint16_t i = size;  
uint8_t *pSrc = (uint8_t*)myArray;
uint8_t *pDst = TXBuffer;

while(i--) *pDst++ = *pSrc++;

HAL_UART_Transmit(&huart2, TXBuffer, size, HAL_MAX_DELAY);

或者你可以简单地将浮点数组类型转换为字节数组并将其发送出去:

uint16_t size = FARRAYSIZE * sizeof(float);
uint8_t* pSrc = (uint8_t*)myArray;
HAL_UART_Transmit(&huart2, TXBuffer, size, HAL_MAX_DELAY);

然后你可以省略创建单独的 TxBuffer 并节省内存使用量。
唉,我的建议是对如此长的字节流使用 HAL_UART_Transmit_DMA(...) 。在这种情况下,我强烈建议使用单独的 TX 缓冲区,因为这样您就可以更改原始浮点数组中的值,而 DMA 使用 TX 缓冲区发送数据。

Create a TX-Buffer:

#define TXBUFSIZE nn
#define FARRAYSIZE mm
uint8_t TXBuffer[TXBUFSIZE] = {0};
float myArray[FARRAYSIZE] = {0,};

where nn is the number of bytes you need to send. If you want to send 250 float values in one package this would be 250 * sizeof(float)

fill the buffer in a while loop:

uint16_t size = FARRAYSIZE * sizeof(float);
uint16_t i = size;  
uint8_t *pSrc = (uint8_t*)myArray;
uint8_t *pDst = TXBuffer;

while(i--) *pDst++ = *pSrc++;

HAL_UART_Transmit(&huart2, TXBuffer, size, HAL_MAX_DELAY);

or you could simply typecast the float array into a byte array and send it out:

uint16_t size = FARRAYSIZE * sizeof(float);
uint8_t* pSrc = (uint8_t*)myArray;
HAL_UART_Transmit(&huart2, TXBuffer, size, HAL_MAX_DELAY);

Then you could omit the creation of a separate TxBuffer and save memory usage.
Alas my recommendation would be to use HAL_UART_Transmit_DMA(...) for such long byte streams. In this case I'd strongly recommend to use a separate TX buffer, because then you can change the values in the original float array, while the DMA uses the TX Buffer to send out your data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文