日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32LL库使用——SPI通信

發布時間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32LL库使用——SPI通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STM32使用前的準備

對于要使用的每個STM32芯片,首先我們手上必備的兩本手冊(ST官網有pdf版):

  • 參考手冊(Reference manual)
  • 數據手冊(Datasheet)
  • 其中參考手冊包括各個功能模塊的具體信息、原理、各種工作模式介紹、配置方法以及寄存器相關信息;數據手冊包括芯片的基本參數、引腳數量與各自功能、電氣特性、封裝信息等內容。一般在選型與硬件設計階段,參考數據手冊多一些,而到了程序設計階段,參考手冊就是必須的了。

    以下是STM32G4系列的參考手冊的“自我介紹”:

    This reference manual targets application developers. It provides complete information on how to use the STM32G4 Series microcontroller memory and peripherals.

    本參考手冊的目標是應用程序開發人員。?它提供了關于的完整信息如何使用STM32G4系列單片機的內存和外設。 ?

    SPI相關設置

    我們以STM32G系列為例,直接翻到SPI章節,SPI結構示意圖如下:

    一共4個引腳可與外設連接:

    • MISO(Master In / Slave Out data:該引腳在從模式下發送數據,在主模式下接收數據
    • MOSI(Master Out / Slave In data):該引腳在主模式下發送數據,在從模式下接收數據
    • SCK(Serial Clock):主設備往從設備傳輸的時鐘信號
    • NSS(Slave select):用于主設備選擇從設備

    ?單個主設備與單個從設備全雙工通信模式示意圖如下:

    我們采用STM32CubeMX可以方便的完成基礎配置,實際只需要編寫如下實際通訊需要的代碼

    基礎通訊代碼

    Tx:發送緩沖區;Rx:接收緩沖區;DR:數據寄存器

    狀態指示標志:

    • Tx buffer empty flag (TXE):發送緩沖區為空
    • Rx buffer not empty (RXNE):接收緩沖區非空
    • Busy flag (BSY):SPI數據正在傳輸中

    基本工作原理:主機向從機發送一個值(指令),然后從機依據接收到的指令返回一個值

    常見情況我們用STM32作為主機

  • ?等待TXE標志置1(Tx空),表明此時發送緩沖區Tx中無待發送的值
  • 將數據寫入SPIx_DR寄存器,對DR的寫操作將把數據寫入Tx末尾
  • 等待BSY標志置0(即busy,置1表明Tx中的數據正在傳輸中)。期間數據通過MOSI發送給從機,從機返回的信息通過MISO回到主機接收緩沖區Rx
  • 等待RXNE標志置1(Rx非空),表明此時Rx存在接收到的值
  • 讀取SPIx_DR寄存器,對DR的讀操作將返回Rx中最早的值
  • // data_in:待發送的值 // data_out:接收到的值 static int spi_transmit_receive(uint16_t data_in, uint16_t *data_out){int state = 0;*data_out = 0;uint32_t timeout_cnt;static const uint32_t timeout_cnt_num = 10000;// Wait until TXE flag is set to send data timeout_cnt = 0;while(!LL_SPI_IsActiveFlag_TXE(SPI1)){timeout_cnt ++;if(timeout_cnt > timeout_cnt_num){state = -1;break;}}// Transmit data in 16 Bit modeLL_SPI_TransmitData16(SPI1, data_in);// Check BSY flag timeout_cnt = 0;while(LL_SPI_IsActiveFlag_BSY(SPI1)){timeout_cnt ++;if(timeout_cnt > timeout_cnt_num){state = -1;break;}}// Check RXNE flag timeout_cnt = 0;while(!LL_SPI_IsActiveFlag_RXNE(SPI1)){timeout_cnt ++;if(timeout_cnt > timeout_cnt_num){state = -1;break;}}// Read 16-Bits in the data register*data_out = LL_SPI_ReceiveData16(SPI1);return state; }

    ?所涉及的LL庫相關函數:

    /*** @brief Write 16-Bits in the data register* @rmtoll DR DR LL_SPI_TransmitData16* @param SPIx SPI Instance* @param TxData Value between Min_Data=0x00 and Max_Data=0xFFFF* @retval None*/ __STATIC_INLINE void LL_SPI_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData) { #if defined (__GNUC__)__IO uint16_t *spidr = ((__IO uint16_t *)&SPIx->DR);*spidr = TxData; #elseSPIx->DR = TxData; #endif /* __GNUC__ */ }/*** @brief Read 16-Bits in the data register* @rmtoll DR DR LL_SPI_ReceiveData16* @param SPIx SPI Instance* @retval RxData Value between Min_Data=0x00 and Max_Data=0xFFFF*/ __STATIC_INLINE uint16_t LL_SPI_ReceiveData16(SPI_TypeDef *SPIx) {return (uint16_t)(READ_REG(SPIx->DR)); }/*** @brief Check if Tx buffer is empty* @rmtoll SR TXE LL_SPI_IsActiveFlag_TXE* @param SPIx SPI Instance* @retval State of bit (1 or 0).*/ __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXE(SPI_TypeDef *SPIx) {return ((READ_BIT(SPIx->SR, SPI_SR_TXE) == (SPI_SR_TXE)) ? 1UL : 0UL); }/*** @brief Get busy flag* @note The BSY flag is cleared under any one of the following conditions:* -When the SPI is correctly disabled* -When a fault is detected in Master mode (MODF bit set to 1)* -In Master mode, when it finishes a data transmission and no new data is ready to be* sent* -In Slave mode, when the BSY flag is set to '0' for at least one SPI clock cycle between* each data transfer.* @rmtoll SR BSY LL_SPI_IsActiveFlag_BSY* @param SPIx SPI Instance* @retval State of bit (1 or 0).*/ __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_BSY(SPI_TypeDef *SPIx) {return ((READ_BIT(SPIx->SR, SPI_SR_BSY) == (SPI_SR_BSY)) ? 1UL : 0UL); }/*** @brief Check if Rx buffer is not empty* @rmtoll SR RXNE LL_SPI_IsActiveFlag_RXNE* @param SPIx SPI Instance* @retval State of bit (1 or 0).*/ __STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXNE(SPI_TypeDef *SPIx) {return ((READ_BIT(SPIx->SR, SPI_SR_RXNE) == (SPI_SR_RXNE)) ? 1UL : 0UL); }

    ?實際使用spi_transmit_receive函數時,一般需要在函數前后設置以下片選NSS輸出,通訊前選中當前從機,通訊后再關閉,防止多主機或者多從機模式時的沖突。

    // NSS片選引腳置0,開啟當前主從關系LL_GPIO_ResetOutputPin(GPIOx, LL_GPIO_PIN_x);spi_transmit_receive(controlword, &recbuff);// NSS置1,關閉當前主從關系LL_GPIO_SetOutputPin(GPIOx, LL_GPIO_PIN_x);

    總結

    以上是生活随笔為你收集整理的STM32LL库使用——SPI通信的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。