首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取STM32单片机的SPI数据寄存器的值

读取STM32单片机的SPI数据寄存器的值
EN

Stack Overflow用户
提问于 2018-08-02 21:14:58
回答 1查看 4.6K关注 0票数 3

有相当多类似的问题,但似乎没有一个有完全相同的问题。我正在将一个STML4单片机连接到一个6轴传感器(LSM6DS3)。我已经成功地用I2C实现了所有的东西,但是我想要SPI的额外速度(和DMA,如果我能让这些第一步工作的话…)。因此,第一步,我尝试读取设备的WHO_AM_I寄存器(0x0F),它应该以0x69响应。代码如下:

代码语言:javascript
复制
uint8_t who = 0;

// Sanity check/debugging aid should get 0x5D
who = 0x43 + 0x1A;

// Set SS low
GPIO_WritePin (GPIOB, LL_GPIO_PIN_7, GPIO_PIN_RESET);

// while tx buffer is in use, wait
while (!LL_SPI_IsActiveFlag_TXE(SPI1));

// Send READ command to the WHO_AM_I register
(SPI1->DR) = 0x8F;

// while rx buffer is in use, wait
while (!LL_SPI_IsActiveFlag_RXNE(SPI1));

// Get data off the register
who = (SPI1->DR);

// Wait for everything to wrap up before setting SS high again
while (LL_SPI_IsActiveFlag_BSY(SPI1));

// OK, now we can set SS high
GPIO_WritePin (GPIOB, LL_GPIO_PIN_7, GPIO_PIN_SET);

在示波器/分析器上,我看到一切都按预期运行,包括发送回0x69的传感器。但是,当我在代码块的另一侧设置一个中断符时,我看到who0转到0x5D,再转到0xFF。它从不读取0x69。我查看了其他代码示例,有些人使用设置为某个虚拟值(通常是0xFF0x0)的数据进行第二次传输,所以我也尝试了一下,但传感器似乎在第二次尝试期间感到困惑,who最终为0x48。为了让变量正确读取SPI1数据寄存器,我尝试了等待RXNE/TXE/BSY标志的各种方法,包括从传感器读取其他寄存器,但都无济于事。

那么问题是,如何正确地从这个寄存器中读取值?

我还应该提到,我可以成功地写入设备的寄存器。我可以发送我想要的命令,然后读回它,看到它在作用域上工作,即使我永远不能在代码中获得赋给变量的值。我总是得到0xFF

我在分析器上显示了一个屏幕,显示传感器从单个读请求发回0x69,以及如果我尝试“虚拟传输”方法,它发送的乱码。

EN

回答 1

Stack Overflow用户

发布于 2018-08-02 22:11:07

当您传输时,SPI始终(如果接收器已启用)接收数据。

这就是库的问题所在,你不知道那里有什么。使用寄存器对SPI进行编程要容易得多。

我假设你的数据是8位的。

在SPI初始化期间,您需要通过以下方式设置1/4 (一个字节) FIFO阈值:

代码语言:javascript
复制
 SPI1 -> CR2 |= SPI_CR2_FRXTH;

接下来,您需要在每次写入后从FIFO读取数据(您还需要强制编译器使用正确的大小(在本例中为8位)加载和存储指令):

代码语言:javascript
复制
*(volatile uint8_t *)&SPI1->DR = 0x8F;  // write exactly 8 bits to the FIFO
while (!LL_SPI_IsActiveFlag_RXNE(SPI1));
dummy = *(volatile uint8_t *)&SPI-> DR;
*(volatile uint8_t *)&SPI1->DR = 0;  // dummy write
while (!LL_SPI_IsActiveFlag_RXNE(SPI1));
who = *(volatile uint8_t *)&(SPI1->DR);

我不知道使用LL库有什么意义。

而不是

代码语言:javascript
复制
while (!LL_SPI_IsActiveFlag_RXNE(SPI1));

使用寄存器

代码语言:javascript
复制
while (!(SPI1 -> SR & SPI_SR_RNE));

您也可以将其封装到函数中:

代码语言:javascript
复制
uint8_t SPI_ReadWrite8(SPI_TypeDef *spi, uint8_t data)
{
    while(!(spi -> SR & SPI_SR_TXE));
    *(volatile uint8_t *)&spi->DR = data; 
    while (!(spi -> SR & SPI_SR_RNE));
    return *(volatile uint8_t *)&spi-> DR;
}

代码语言:javascript
复制
SPI_ReadWrite8(SPI1, 0x8f);
who = SPI_ReadWrite8(SPI1, 0);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51654627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档