我可以将 uint32_t 的四个字节转换为 uint8_t 指针吗

Can i cast the four bytes of a uint32_t to uint8_t pointers

一些背景:

我正在使用 STM32 接收和传输一个 24 位长信号,可以确定电池是否过度放电或过度充电,并通过 AFE 监控温度。

实际问题:

我需要在其中一个 STM 库中使用的函数接受一个 8 位指针的参数:HAL_SPI_Transmit(&hspi1, (uint8_t *)&buf_ptr, 1, 100); 以便与 24 位 AFE 接口。我的目标是编写一个可以对我需要的数据进行编码的 32 位信号,只需调用该函数 3 次并使用 8 位指针引用 32 位信号,但我想知道解决我的问题的最简单方法是什么是。

我的第一个希望是我可以用一个 8 位指针访问信息的第一个字节,然后每次将地址递增 1:

void MAX_Interface::MOSI_BufTransmit()
{
    uint8_t* buf_ptr = (uint8_t) &OBuf;

    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_RESET);
    for (int i = 0; i < 3; i++)
    {
        HAL_SPI_Transmit(&hspi1, (uint8_t *)&buf_ptr, 1, 100);
        buf_ptr++;
    }
    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_SET);
}

我的第二个想法是,也许我可以每次将输出缓冲区移位 8 位,然后将其转换为一个字节:

void MAX_Interface::MOSI_BufTransmit()
{
    uint8_t* buf_ptr

    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_RESET);
    for (int i = 0; i < 3; i++)
    {
        buf_ptr =(uint8_t*) OBuf>>8*i;
        HAL_SPI_Transmit(&hspi1, (uint8_t *)&buf_ptr, 1, 100);
    }
    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_SET);
}

我觉得这些可能是最优雅的解决方案,但它们都不起作用。

有没有人知道更多关于这个话题的信息?

访问 32 位整数的各个字节是可以的。

但是,您的两种方法都失败了,因为您将错误的内存地址传递给 HAL_SPI_Transmit()。您传递的是 buf_ptr 本身的地址,而不是 buf_ptr 指向的 OBuf 的地址。

此外,对于第二种方法,您甚至没有分配 buf_ptr 来指向有效的内存地址!您正在读取 OBuf 的各个字节的 values 并将它们转换为指针,而不是获取每个字节的 address

试试这个:

void MAX_Interface::MOSI_BufTransmit()
{
    uint8_t* buf_ptr = (uint8_t*) &OBuf;

    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_RESET);
    for (int i = 0; i < 3; ++i)
    {
        HAL_SPI_Transmit(&hspi1, buf_ptr+i, 1, 100); // or: &buf_ptr[i]
    }
    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_SET);
}

也就是说,HAL_SPI_Transmit() 的第 3 个参数是一个字节数,因此您可以尝试简单地要求 HAL_SPI_Transmit() 一次发送所有 3 个字节,而不是调用 HAL_SPI_Transmit() 3次每次发送1个字节,eg:

void MAX_Interface::MOSI_BufTransmit()
{
    uint8_t* buf_ptr = (uint8_t*) &OBuf;

    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_Transmit(&hspi1, buf_ptr, 3, 100);
    HAL_GPIO_WritePin(GPIOB, CS_Pin, GPIO_PIN_SET);
}