STM32 SPI通讯
Posted
技术标签:
【中文标题】STM32 SPI通讯【英文标题】:STM32 SPI communication 【发布时间】:2019-04-06 22:56:21 【问题描述】:我正在尝试使用 STM32F411VE
进行 SPI 通信。我在 SPI 通信方面遇到了一些问题。我正在关注这个特定代码的传输和接收
http://www.handsonembedded.com/stm32f103-spl-tutorial-5/
我正在使用 SPI4。我的SPI初始化是这样的:
/* SPI4 init function */
void MX_SPI4_Init(void)
hspi4.Instance = SPI4;
hspi4.Init.Mode = SPI_MODE_MASTER;
hspi4.Init.Direction = SPI_DIRECTION_2LINES;
hspi4.Init.DataSize = SPI_DATASIZE_8BIT;
hspi4.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi4.Init.NSS = SPI_NSS_SOFT;
hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi4.Init.TIMode = SPI_TIMODE_DISABLE;
hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi4.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi4) != HAL_OK)
_Error_Handler(__FILE__, __LINE__);
代码如下:
uint8_t SPISend(uint8_t data)
SPI4->DR = data;
while (!(SPI4->SR & SPI_SR_TXE));
while (!(SPI4->SR & SPI_SR_RXNE));
while (!(SPI4->SR & SPI_SR_BSY));
return(SPI4->DR);
我这个特殊的SPISend()
方法控制永远不会到达终点。它卡在循环中while (!(SPI4->SR & SPI_SR_TXE));
。
我的函数调用是这样的:
void write8(char reg, unsigned char data)
uint8_t retVal;
enableChip;
reg|=0x80;
retVal = SPISend(reg);
retVal = SPISend(data);
disableChip;
任何建议。
【问题讨论】:
可能SPI4
应该用volatile
声明。否则编译器不知道它可以被外部原因改变。
SPI4
在stm32f411xe.h
中定义如下#define SPI4 ((SPI_TypeDef *) SPI4_BASE)
【参考方案1】:
在我的脑海中,SPI_CR1_SPE
和/或SPI_CR1_SSI
应该在SPI4->CR1
中启用。 HAL_SPI_Init()
没有设置,但是HAL SPI传输功能可以,如果你使用自己的传输代码,你应该自己做。
更新
如果您在enableChip
中启用SPE
和SSI
位,它将永远不会被调用,因为它不是没有括号的函数调用。
这两行
SPI4->DR = data;
while (!(SPI4->SR & SPI_SR_TXE));
顺序错误。你先等待TXE != 0
,表示发送队列已经准备好接收更多数据,然后再写入数据。
这里是第二行
while (!(SPI4->SR & SPI_SR_RXNE));
while (!(SPI4->SR & SPI_SR_BSY));
很可能是一个无限循环,因为当SPI_SR_RXNE
变为1
或此后不久,SPI_SR_BSY
将从1
变为0
。
【讨论】:
我用过这个初始化SPI4->CR1 |= SPI_CR1_SSM;
SPI4->CR1 |= SPI_CR1_SSI;
SPI4->CR1 |= SPI_CR1_SPE;
这是正确的初始化吗以上是关于STM32 SPI通讯的主要内容,如果未能解决你的问题,请参考以下文章