首页 > 解决方案 > 使用 SPI 将 16 位数组从 Raspberry Pi 传输到 STM32F4

问题描述

关于我的最终目标,我有两个主要问题,即能够在从模式下从 STM32F4 向主模式下的树莓派发送大小为 2000 的 16 位数组。

问题 1. 我不明白为什么从我的 STM 发送时我在我的 Pi 上读取/打印不正确的输出。我已经解释了我的编程和结果输出。

最初我正在测试传输一个 8 位整数,因为 HAL_SPI_Transmit 函数原型只允许 8 位传输(这是我的问题 2),所以我现在已经设置了 8 位传输并且我的 8 位传输不正确。我的 STM32F4 使用 CubeMX 配置为 8 位从机模式,生成以下代码块。

static void MX_SPI2_Init(void)
{

/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;

hspi2.Init.Mode = SPI_MODE_SLAVE;

hspi2.Init.Direction = SPI_DIRECTION_1LINE;

hspi2.Init.DataSize = SPI_DATASIZE_8BIT;

hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi2.Init.NSS = SPI_NSS_SOFT;

hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi2.Init.TIMode = SPI_TIMODE_DISABLE;

hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi2.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi2) != HAL_OK)

{

Error_Handler();

}


}

使用 HAL 库,我目前设置为使用 HAL_SPI_Transmit 函数传输一个 8 位数组(数组 spiDATA 的类型为 uint8_t),如以下代码段所示。在下面的段落中,我只是试图发送数组 spiDATA 的第一个条目。

while (1)

{

  spiDATA[0]=5;

  spiDATA[1]=7;

  HAL_SPI_Transmit(&hspi2, spiDATA, 1, 10);

 }

现在在 Pi 上,在 STM 上接收数据的代码看起来像

#initialise spiDEV

spi = spidev.SpiDev()

spi.open(0,0)

spi.max_speed_hz = 100000

TRUE = 1

while TRUE:

y = spi.readbytes(1)

print("Value tranferred by SPI is", y[0])

time.sleep(1)

现在运行它时,pi上的输出如图所示

("Value tranferred by SPI is", 80)

("Value tranferred by SPI is", 65)

("Value tranferred by SPI is", 5)

("Value tranferred by SPI is", 10) 

("Value tranferred by SPI is", 20)

("Value tranferred by SPI is", 40)

("Value tranferred by SPI is", 80)

("Value tranferred by SPI is", 65)

("Value tranferred by SPI is", 5)

("Value tranferred by SPI is", 10)
    

如果我将 HAL_SPI_Transmit 更改为发送 2 个字节,并将 readbytes 更改为 2 个字节,并同时打印 y[0] 和 y[1],它会打印两次相同的内容,例如它看起来像

("Value tranferred by SPI is", 80, 80)

("Value tranferred by SPI is", 65, 65)

("Value tranferred by SPI is", 5, 5)

etc    

现在,如果我将 HAL_SPI_Transmit 更改为传输 4 个字节并将 readbytes 更改为 2 个字节,我会得到以下信息,

("Value tranferred by SPI is", 5, 7)

("Value tranferred by SPI is", 0, 20)

("Value tranferred by SPI is", 56, 40)

("Value tranferred by SPI is", 112, 80)

("Value tranferred by SPI is", 224, 160)

("Value tranferred by SPI is", 193, 65)

("Value tranferred by SPI is", 130, 112)

("Value tranferred by SPI is", 5, 7)

问题 2:是否可以使用 HAL_SPI_Transmit 函数发送 16 位?在 HAL_SPI_Transmit 函数原型中,它说它需要一个指向数据的 8 位指针,如下所示。

HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)

我已经使用 cubeMX 重新配置了我的 pin 以进行 16 位传输,它重新生成前面显示的初始化代码并分配,

hspi2.Init.DataSize = SPI_DATASIZE_16BIT;

但是我仍然有一个问题,当我尝试发送 16 位时,当通过 SPI 与 Pi 通信时,它会将我的 16 位整数截断为 8 位整数。我已经看到这已发布在其他地方的论坛中,建议的答案是在原型中对 *pdata 进行类型转换,例如我的函数将更改为 HAL_SPI_Transmit 中的 (uint8_t*)spiData'。这不起作用,因为我需要 11 到 12 位来表示我范围内的整数,这些整数通过类型转换具有像 '2000' 和 '3000' 等值,我正在丢失这些信息,因为它正在截断这些位。

标签: pythonstm32spipistm32f4

解决方案


SPI 传输错误可能是由许多问题引起的。

  • 您需要确保您的内核时钟足够高以处理数据接收。如果您的 SPI 时钟频率总线低于 Raspberry Pi Spi 波特率。
  • 来自 SPI ST 演示文稿:用户可以通过强制控制它们来防止在备用功能模式下工作的相关输出上的任何故障。这意味着您需要在下拉电阻(或上拉)上配置和强制您的 GPIO SCK、MOSI、NSS
  • 在您的 stm32 配置中使用硬件 NSS。
  • 在您的 Raspberry pi 中启用 CS(禁用无 CS)。
  • 尝试发送长大小的缓冲区(例如:256)

推荐阅读