簡體   English   中英

讀取STM32 MCU的SPI數據寄存器的值

[英]Reading values of SPI data register of STM32 MCU

有很多類似的問題,但似乎都沒有相同的問題。 我正在將STML4 MCU連接到6軸傳感器(LSM6DS3)。 我已經成功地在I2C中實現了所有功能,但是想要SPI的額外速度(以及DMA,如果我能讓這些第一步工作......)。 因此,對於第一步,我試圖讀取設備的WHO_AM_I寄存器( 0x0F ),該寄存器應以0x69回復。 這是代碼:

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 但是,當我在這個代碼塊的另一端設置一個中斷時,我看到who00x5D0xFF 它永遠不會讀取0x69 我查看了其他代碼示例,有些人將第二次傳輸的數據設置為某個虛擬值(通常為0xFF0x0 ),所以我也試過了,但傳感器似乎在第二次嘗試時感到困惑who最終成為0x48 我已經嘗試了等待我可能擁有的RXNE / TXE / BSY標志的每個排列,以及許多其他事情來讓變量正確讀取SPI1數據寄存器,包括從傳感器讀取其他寄存器,但所有徒勞無功。

那么問題是,如何正確讀取該寄存器的值?

我還要提一下,我可以成功寫入設備的寄存器。 我可以發送我想要的命令,然后讀回來看看它是否適用於作用域,即使我永遠無法在代碼中獲得賦值給變量的值。 我總是得到0xFF

我包括我的分析儀屏幕,顯示傳感器從單個讀取請求發回0x69 ,以及如果我嘗試“虛擬發送”方法它發送的亂碼。 Correcly向我發送WHO_AM_I值 在“double”傳輸上發送<code> 0x48 </ code>

SPI始終(如果接收器已啟用)在傳輸時接收數據。

這是圖書館的問題,你不知道那里有什么。 SPI使用寄存器編程要容易得多。

我假設你的數據是8位。

您需要在SPI初始化期間通過以下方式設置1/4(單字節)FIFO閾值:

 SPI1 -> CR2 |= SPI_CR2_FRXTH;

接下來,您需要在每次寫入后從FIFO讀取數據(您還需要強制編譯器使用正確的大小(在本例中為8位)加載和存儲指令):

*(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庫有什么意義。

代替

while (!LL_SPI_IsActiveFlag_RXNE(SPI1));

使用寄存器

while (!(SPI1 -> SR & SPI_SR_RNE));

您還可以將其包裝到函數中:

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;
}

SPI_ReadWrite8(SPI1, 0x8f);
who = SPI_ReadWrite8(SPI1, 0);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM