STM32:简单的 SPI 传输
Posted
技术标签:
【中文标题】STM32:简单的 SPI 传输【英文标题】:STM32: simple SPI transfer 【发布时间】:2020-12-05 06:41:12 【问题描述】:我正在使用 STM32F3DISCOVERY 开发板,我正在尝试更深入地研究 HAL 的抽象。我制作了一个通过 SPI 传输数据的函数的简单版本,遗憾的是它不起作用(至少我发送它的 DAC 不会改变状态)而且我不确定我在那里缺少什么。也许初始化代码中的某些内容不适用于我的简单版本。我很乐意提供任何可以查看的指导或参考资料。谢谢!
#include <stm32f3xx_hal.h>
#define PINS_SPI GPIO_PIN_5 | GPIO_PIN_7
#define GPIO_PORT GPIOA
/* This is the simplest function I could come up with to do the transfer but I'm clearly missing something here */
uint8_t SPI_SendReceive(SPI_HandleTypeDef *hspi, uint8_t data)
/* Loop while DR register in not empty */
while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET)
/* Send data through the SPI1 peripheral */
hspi->Instance->DR = data;
/* Wait to receive data */
while ((hspi->Instance->SR & SPI_FLAG_RXNE) == RESET)
return hspi->Instance->DR;
int main()
HAL_Init();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
static SPI_HandleTypeDef spi = .Instance = SPI1;
spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
spi.Init.Direction = SPI_DIRECTION_2LINES;
spi.Init.CLKPhase = SPI_PHASE_1EDGE;
spi.Init.CLKPolarity = SPI_POLARITY_LOW;
spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spi.Init.DataSize = SPI_DATASIZE_8BIT;
spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
spi.Init.NSS = SPI_NSS_HARD_OUTPUT;
spi.Init.TIMode = SPI_TIMODE_DISABLE;
spi.Init.Mode = SPI_MODE_MASTER;
HAL_SPI_Init(&spi);
__HAL_SPI_ENABLE(&spi);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = PINS_SPI;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* TI 8564 DAC Settings */
uint8_t cmd1 = 0b00010000;
/* DAC output value (16-bit) */
uint16_t cmd23 = 0;
uint8_t cmd2 = cmd23 >> 8;
uint8_t cmd3 = cmd23 & 0xff;
uint8_t command[3] = cmd1, cmd2, cmd3;
while (true)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
/* This does not work :( */
SPI_SendReceive(&spi, command[0]);
SPI_SendReceive(&spi, command[1]);
SPI_SendReceive(&spi, command[2]);
/* This works! When commenting in the lines above and commenting this out */
/* HAL_SPI_Transmit(&spi, command, 3, HAL_MAX_DELAY); */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
HAL_Delay(1000);
【问题讨论】:
如果HAL_SPI_Transmit
工作正常,外围设备已正确初始化,我会检查HAL_SPI_Transmit
在做什么以及与SPI_SendReceive
的区别
你没有说到底是什么不工作......你也在SPI上传输数据。但是为了什么?另一个板子?外围设备?
感谢你们两位的cmets!我正在尝试与TI 8564 DAC 交谈。很抱歉没有澄清这一点。现在我唯一能评估的是 DAC 中的电压变化。但是,我将尝试访问逻辑分析仪,然后提供更多信息!谢谢你! @Jose 我检查了HAL_SPI_Transmit
函数,它做了很多可能是强制性的,也可能不是强制性的。我有点搞砸了,试图注释掉我认为在我的情况下可能不需要但最终放弃的东西:(
是的,HAL 非常复杂,因为它试图支持所有可能的配置和用例。然而,在这个“可怕的很多事情”中,有一些是强制性的......特别是您必须设置要发送/接收的字节数,并在每次传输时启动/停止 SPI。 STM32的参考手册描述了你需要做什么。
谢谢你,@GuillaumePetitjean,一旦我有更好的调试方法,而不仅仅是开/关反馈,我会检查参考手册并四处寻找!
【参考方案1】:
检查 HAL_SPI_Init 的内容。这个函数很可能会调用另一个应该进行低级初始化的函数,而您有责任自己提供这个函数。更复杂的是,这个所谓的第二个函数已经定义了一个“虚拟”弱别名,因此工具链不会返回任何错误,而是构建一个无法执行任何操作的代码。
【讨论】:
以上是关于STM32:简单的 SPI 传输的主要内容,如果未能解决你的问题,请参考以下文章
梳理STM32F429之通信传输部分---NO.8 硬件SPI
是否可以在 STM32F3 上使用 DMA 通过 SPI 传输无限数据?