NRF52832學習筆記(37)——SPI(從機)接口使用

一叮喳、SPI簡介

SPI(Serial Peripheral Interface) 協(xié)議是由摩托羅拉公司提出的通訊協(xié)議痒玩,即串行外圍設(shè)備接口恤浪,是一種高速全雙工的通信總線挨稿。它被廣泛地使用在 ADC、LCD 等設(shè)備與 MCU 間鸟妙,要求通訊速率較高的場合焦人。

芯片的管腳上只占用四根線。
MISO: 主器件數(shù)據(jù)輸出重父,從器件數(shù)據(jù)輸入花椭。
MOSI:主器件數(shù)據(jù)輸入,從器件數(shù)據(jù)輸出房午。
SCK: 時鐘信號矿辽,由主設(shè)備控制發(fā)出。
NSS(CS): 從設(shè)備選擇信號,由主設(shè)備控制袋倔。當NSS為低電平則選中從器件雕蔽。

二、API說明

以下 SPI 從機接口須包含頭文件 nrf_drv_spis.h宾娜。

#include "nrf_drv_spis.h"

2.1 NRF_DRV_SPIS_INSTANCE

功能 實例化一個SPI從機
函數(shù)定義 NRFX_SPIS_INSTANCE(id)
參數(shù) id:SPI從機實例編號
返回 攜帶有EasyDMA的SPI從機實例

2.2 nrf_drv_spis_init

功能 SPI從機驅(qū)動初始化
函數(shù)定義 ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance,
nrf_drv_spis_config_t const * p_config,
nrf_drv_spis_event_handler_t event_handler)
參數(shù) p_instance:SPI從機實例
p_config:配置參數(shù)
event_handler:回調(diào)處理函數(shù)
返回 0-成功批狐,或其他錯誤碼

2.3 nrf_drv_spis_buffers_set

功能 配置SPI從機發(fā)送和接收緩存區(qū)
函數(shù)定義 nrfx_err_t nrfx_spis_buffers_set(nrfx_spis_t const * const p_instance,
uint8_t const * p_tx_buffer,
size_t tx_buffer_length,
uint8_t * p_rx_buffer,
size_t rx_buffer_length)
參數(shù) p_instance:SPI從機實例
p_tx_buffer:發(fā)送數(shù)據(jù)緩存區(qū)
tx_buffer_length:發(fā)送數(shù)據(jù)長度
p_rx_buffer:接收數(shù)據(jù)緩存區(qū)
rx_buffer_length:接收數(shù)據(jù)長度
返回 0-成功,或其他錯誤碼

三前塔、SDK配置

點擊 sdk_config.h 文件


選擇 Configuration Wizard

nRF_Drivers 中勾選SPIS相關(guān)選項


nRF_Drivers 中添加文件

nrfx_spis.c 新版本 SPIS 兼容庫 modules\nrfx\drivers\src
nrf_drv_spis.c 老版本 SPIS 基礎(chǔ)庫 integration\nrfx\legacy

四贾陷、硬件連接

功能口 引腳
MISO 30
MOSI 29
CLK 26
CSN 31

五、使用例子

打開SDK示例工程 examples\peripheral\spis

5.1 包含頭文件

#include "nrf_drv_spis.h"

5.2 實例化SPI從機

#define SPIS_INSTANCE 1 /**< SPIS instance index. */
static const nrf_drv_spis_t spis = NRF_DRV_SPIS_INSTANCE(SPIS_INSTANCE);/**< SPIS instance. */

5.3 定義SPI從機事件處理函數(shù)

spis_event_handler 接收事件處理函數(shù)嘱根,當SPI從機接收到數(shù)據(jù)時進入該函數(shù)髓废。
spis_xfer_done 接收數(shù)據(jù)標志,當SPI從機接收到數(shù)據(jù)時置1该抒,處理完接收數(shù)據(jù)后要清0慌洪。

static volatile bool spis_xfer_done; /**< Flag used to indicate that SPIS instance completed the transfer. */

/**
 * @brief SPIS user event handler.
 *
 * @param event
 */
void spis_event_handler(nrf_drv_spis_event_t event)
{
    if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
    {
        spis_xfer_done = true;
        SEGGER_RTT_printf(0," Transfer completed. Received: %s\n",(uint32_t)m_rx_buf);
    }
}

5.4 初始化SPI從機

#define APP_SPIS_CS_PIN 31
#define APP_SPIS_MISO_PIN 30
#define APP_SPIS_MOSI_PIN 29
#define APP_SPIS_SCK_PIN 26

nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;
spis_config.csn_pin               = APP_SPIS_CS_PIN;
spis_config.miso_pin              = APP_SPIS_MISO_PIN;
spis_config.mosi_pin              = APP_SPIS_MOSI_PIN;
spis_config.sck_pin               = APP_SPIS_SCK_PIN;

APP_ERROR_CHECK(nrf_drv_spis_init(&spis, &spis_config, spis_event_handler));

5.5 配置發(fā)送和接收緩存區(qū)

#define TEST_STRING "Nordic"
static uint8_t       m_tx_buf[] = TEST_STRING;           /**< TX buffer. */
static uint8_t       m_rx_buf[sizeof(TEST_STRING) + 1];    /**< RX buffer. */
static const uint8_t m_length = sizeof(m_tx_buf);        /**< Transfer length. */

APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, m_tx_buf, m_length, m_rx_buf, m_length));

5.6 完整代碼

由于SDK原工程NRF_LOG打印不出來,這里我改成了使用SEGGER_RTT打印凑保。須包含頭文件 SEGGER_RTT.h

#include "sdk_config.h"
#include "nrf_drv_spis.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "SEGGER_RTT.h"

#define SPIS_INSTANCE 1 /**< SPIS instance index. */
static const nrf_drv_spis_t spis = NRF_DRV_SPIS_INSTANCE(SPIS_INSTANCE);/**< SPIS instance. */

#define TEST_STRING "Nordic"
static uint8_t       m_tx_buf[] = TEST_STRING;           /**< TX buffer. */
static uint8_t       m_rx_buf[sizeof(TEST_STRING) + 1];    /**< RX buffer. */
static const uint8_t m_length = sizeof(m_tx_buf);        /**< Transfer length. */

static volatile bool spis_xfer_done; /**< Flag used to indicate that SPIS instance completed the transfer. */

/**
 * @brief SPIS user event handler.
 *
 * @param event
 */
void spis_event_handler(nrf_drv_spis_event_t event)
{
    if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
    {
        spis_xfer_done = true;
        SEGGER_RTT_printf(0," Transfer completed. Received: %s\n",(uint32_t)m_rx_buf);
    }
}

int main(void)
{
    // Enable the constant latency sub power mode to minimize the time it takes
    // for the SPIS peripheral to become active after the CSN line is asserted
    // (when the CPU is in sleep mode).
    NRF_POWER->TASKS_CONSTLAT = 1;

    bsp_board_init(BSP_INIT_LEDS);  // 板載LED燈初始化

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    SEGGER_RTT_printf(0,"SPIS example\n");

    nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;
    spis_config.csn_pin               = APP_SPIS_CS_PIN;
    spis_config.miso_pin              = APP_SPIS_MISO_PIN;
    spis_config.mosi_pin              = APP_SPIS_MOSI_PIN;
    spis_config.sck_pin               = APP_SPIS_SCK_PIN;

    APP_ERROR_CHECK(nrf_drv_spis_init(&spis, &spis_config, spis_event_handler));

    while (1)
    {
        memset(m_rx_buf, 0, m_length);
        spis_xfer_done = false;

        APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, m_tx_buf, m_length, m_rx_buf, m_length));

        while (!spis_xfer_done)
        {
            __WFE();
        }

        NRF_LOG_FLUSH();

        bsp_board_led_invert(BSP_BOARD_LED_0);  // LED燈置反
    }
}

查看打痈缘:
使用SDK中SPI主機工程進行接收。


? 由 Leung 寫于 2021 年 5 月 18 日

? 參考:nRF52832 寄存器操作 SPI Slave

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欧引,一起剝皮案震驚了整個濱河市频伤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌芝此,老刑警劉巖憋肖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異婚苹,居然都是意外死亡岸更,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門膊升,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怎炊,“玉大人,你說我怎么就攤上這事廓译∑浪粒” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵非区,是天一觀的道長瓜挽。 經(jīng)常有香客問我,道長院仿,這世上最難降的妖魔是什么秸抚? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任速和,我火速辦了婚禮歹垫,結(jié)果婚禮上剥汤,老公的妹妹穿的比我還像新娘。我一直安慰自己排惨,他們只是感情好吭敢,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暮芭,像睡著了一般鹿驼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辕宏,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天畜晰,我揣著相機與錄音,去河邊找鬼瑞筐。 笑死凄鼻,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的聚假。 我是一名探鬼主播块蚌,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膘格!你這毒婦竟也來了峭范?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤瘪贱,失蹤者是張志新(化名)和其女友劉穎纱控,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體菜秦,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡其徙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喷户。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唾那。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖褪尝,靈堂內(nèi)的尸體忽然破棺而出闹获,到底是詐尸還是另有隱情,我是刑警寧澤河哑,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布避诽,位于F島的核電站,受9級特大地震影響璃谨,放射性物質(zhì)發(fā)生泄漏沙庐。R本人自食惡果不足惜鲤妥,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拱雏。 院中可真熱鬧棉安,春花似錦、人聲如沸铸抑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鹊汛。三九已至蒲赂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刁憋,已是汗流浹背滥嘴。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留至耻,地道東北人若皱。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像有梆,于是被迫代替她去往敵國和親是尖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容