在 STM32 MCU 上使用低电平 (LL) api 通过 SPI 读取可变长度消息

Read variable length messages over SPI using Low Level (LL) api on STM32 MCU

我的系统由一块STM32NUCLEO板和一个通过SPI连接的从设备组成。从设备发送可变长度的命令:可能的长度为 4、8、10、14 位。

我正在尝试使用 LL API 和中断检测我的 nucleo 板上的这些消息。

我目前正在研究的解决方案是基于将 SPI 设置为 4 位数据宽度 (SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_4BIT)然后计算我收到的字数(1 个字 = 4 位)。这样,如果我收到 1 个字,则意味着我收到了一个 4 位命令,2 个字 --> 8 位命令。如果我收到了3个字,那应该意味着我收到了一个10bit的命令(应该丢弃2bit),以此类推。

不幸的是,我注意到 LL API 提供的函数一次只能读取 8 位或 16 位,目前我在接收 4 位命令时遇到问题,因为函数 LL_SPI_ReceiveData8 期望接收 8 位。

这是我对 IRQ 处理程序和回调的实现:

IRQ 处理程序:

void SPI1_IRQHandler(void)
{
  /* Check RXNE flag value in ISR register */
  if(LL_SPI_IsActiveFlag_RXNE(SPI1))
  {
    /* Call function Slave Reception Callback */
    SPI1_Rx_Callback();
  }
  /* Check STOP flag value in ISR register */
  else if(LL_SPI_IsActiveFlag_OVR(SPI1))
  {
    /* Call Error function */
    SPI1_TransferError_Callback();
  }
}

回调

void SPI1_Rx_Callback(void)
{
  /* Read character in Data register.
  RXNE flag is cleared by reading data in DR register */
  aRxBuffer[ubReceiveIndex++] = LL_SPI_ReceiveData8(SPI1);
}

正如我之前所说,问题似乎是我正在使用 LL_SPI_ReceiveData8 函数来读取,因为我找不到 LL_SPI_ReceiveData4.

你有什么建议吗?

此外,是否可以将 SPI 设置为使用 2 位数据宽度而不是 4 位?像 SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_2BIT 这样的东西:这样应该更容易检测命令,因为 4、8、10 和 14 是 2 的倍数。

谢谢。

最小可寻址数据块为字节。因此,即使您收到 4 位,读取的值也是 8 位。

顺便说一句,这个具有不同字长的秘密从属设备是什么?

关于所用控制器的新信息:

支持4到16位的SPI数据传输长度。所以你的拳头尝试似乎还不错。

你的"problem"是没有4位读取功能。这是由始终包含 16 位但只有 4 位有效数据的接收数据寄存器引起的。其他位为“0”。

你的回调函数

aRxBuffer[ubReceiveIndex++] = LL_SPI_ReceiveData8(SPI1);

会将值从 0..15 写入 aRxBuffer 而你不需要 ReceiveData4() 得到你的答案:-)

STM32L4 系列的参考手册 Reference Manual 第 1193ff 页也是如此。