STM32 SPI数据以相反的方式发送

STM32 SPI数据以相反的方式发送,stm32,spi,eeprom,stm32f1,Stm32,Spi,Eeprom,Stm32f1,我一直在尝试使用SPI向外部系统写入数据,我的成功率参差不齐。数据确实会以相反的方式移出。EEPROM需要一个起始位,然后是一个操作码,该操作码本质上是一个用于读取、写入和擦除的2位代码。基本上,起始位和操作码组合成一个字节。我创建一个32位无符号整数,然后将值进行位移位。当我传输这些数据时,我看到实际数据首先被看到,然后是SB+操作码,然后是内存地址。如何将其反转,首先查看操作码,然后查看内存地址,然后查看实际数据。如下图所示,数据为BCDE,SB+操作码为07,内存地址为3F。正确的顺序应该

我一直在尝试使用SPI向外部系统写入数据,我的成功率参差不齐。数据确实会以相反的方式移出。EEPROM需要一个起始位,然后是一个操作码,该操作码本质上是一个用于读取、写入和擦除的2位代码。基本上,起始位和操作码组合成一个字节。我创建一个32位无符号整数,然后将值进行位移位。当我传输这些数据时,我看到实际数据首先被看到,然后是SB+操作码,然后是内存地址。如何将其反转,首先查看操作码,然后查看内存地址,然后查看实际数据。如下图所示,数据为BCDE,SB+操作码为07,内存地址为3F。正确的顺序应该是07,3F,然后是BCDE(我想!)

代码如下:

uint8_t mem_addr = 0x3F;
uint16_t data = 0xBCDE;
uint32_t write_package = (ERASE << 24 | mem_addr << 16 | data);

while (1)
{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
  HAL_SPI_Transmit(&hspi1, &write_package, 2, HAL_MAX_DELAY);
  HAL_Delay(10);

}
/* USER CODE END 3 */
uint8\u t mem\u addr=0x3F;
uint16_t数据=0xBCDE;

uint32\u t write\u package=(擦除您正在将信息打包成一个32位整数,在代码的第3行,您可以决定将哪些数据位放在字中的位置。要更改顺序,您可以将该行替换为:


uint32\u t write\u package=((数据您正在将信息打包成一个32位整数,在代码的第3行,您可以决定将哪些数据位放在字中的位置。要更改顺序,您可以将该行替换为:

uint32\u t write\u package=((数据您的问题在于

默认情况下,STM32使用小edian,因此uint32的最低字节存储在第一个ADRESS

如果我是对的,这是您正在使用的传输函数的声明:

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
它需要一个指向uint8_t作为数据(而不是uint32_t)的指针,因此在编译代码时至少应该得到一个警告

如果您想编写独立于使用的endianess的代码,那么应该将数据存储到数组中,而不是一个“大”变量中

uint8_t write_package[4];

write_package[0] = ERASE;
write_package[1] = mem_addr;
write_package[2] = (data >> 8) & 0xFF;
write_package[3] = (data & 0xFF);
你的问题是这个问题

默认情况下,STM32使用小edian,因此uint32的最低字节存储在第一个ADRESS

如果我是对的,这是您正在使用的传输函数的声明:

HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
它需要一个指向uint8_t作为数据(而不是uint32_t)的指针,因此在编译代码时至少应该得到一个警告

如果您想编写独立于使用的endianess的代码,那么应该将数据存储到数组中,而不是一个“大”变量中

uint8_t write_package[4];

write_package[0] = ERASE;
write_package[1] = mem_addr;
write_package[2] = (data >> 8) & 0xFF;
write_package[3] = (data & 0xFF);

看起来您的SPI接口设置为一次处理16位半字。因此,将要发送的数据分解为16位半字也是有意义的。这将考虑排序问题

uint8_t mem_addr = 0x3F;
uint16_t data = 0xBCDE;
uint16_t write_package[2] = {
    (ERASE << 8) | mem_addr,
    data
};

HAL_SPI_Transmit(&hspi1, (uint8_t *)write_package, 2, HAL_MAX_DELAY);
uint8\u t mem\u addr=0x3F;
uint16_t数据=0xBCDE;
uint16_t write_包[2]={

(擦除看起来您的SPI接口设置为一次处理16位半字。因此,将要发送的数据分解为16位半字也是有意义的。这将考虑排序问题

uint8_t mem_addr = 0x3F;
uint16_t data = 0xBCDE;
uint16_t write_package[2] = {
    (ERASE << 8) | mem_addr,
    data
};

HAL_SPI_Transmit(&hspi1, (uint8_t *)write_package, 2, HAL_MAX_DELAY);
uint8\u t mem\u addr=0x3F;
uint16_t数据=0xBCDE;
uint16_t write_包[2]={

(擦除这只是问题的解决方案,而不是真正问题的解决方案。请查看并理解字节顺序不同的原因。这只是问题的解决方案,而不是真正问题的解决方案。请查看并理解字节顺序不同的原因。这应该是
数据>>8
说明第四行的ead为16。仍然错误,因为SPI显然设置为一次处理16位半字。你是对的,我忽略了数据长度的2。这应该是
data>>8,而不是第四行的16。仍然错误,因为SPI显然设置为一次处理16位半字。你是对的,我是对的忽略了数据长度的2。是的,它设置为处理16位字。这很有帮助。谢谢。如果他使用的是ST的HAL,这仍然很糟糕,因为HAL_SPI_传输()想要一个UTI8*T*用于数据,而你使用UTI1616T**。我的编译器不允许这个隐式类型化。如果你在一个大EDIN系统上运行你的例子,它就不起作用。因为数据字节被交换。C++编译器应该拒绝这个,C编译器应该编译警告。可以有明确的强制转换,是的。is是唯一可以在BE系统上工作的变体,因为当选择16位传输时,
HAL\u SPI\u Transmit()
实际上读取
uint16\u t
数据。请参阅实际代码:
if(hspi->Init.DataSize==SPI\u DataSize\u 16BIT){/*/hspi->Instance->DR=*((uint16\u t*)pData+=sizeof(uint16\u t)/*}
是的,设置为处理16位字。这很有帮助。谢谢。如果他使用的是ST的HAL,这仍然很糟糕,因为HAL\u SPI\u传输()想要一个UTI8*T*用于数据,而你使用UTI1616T**。我的编译器不允许这个隐式类型化。如果你在一个大EDIN系统上运行你的例子,它就不起作用。因为数据字节被交换。C++编译器应该拒绝这个,C编译器应该编译警告。可以有明确的强制转换,是的。is是唯一可以在BE系统上工作的变量,因为当选择16位传输时,
HAL\u SPI\u Transmit()
实际上读取
uint16\u t
数据。请参阅实际代码:
if(hspi->Init.DataSize==SPI\u DataSize\u 16BIT){/*…/hspi->Instance->DR=*((uint16\u t*)pData);/*}