一、硬件连接
功能口 | 引脚 |
---|---|
MISO | 17 |
MOSI | 18 |
CLK | 20 |
CSN | 19 |
二、移植文件
注意:以下出现缺失common.h文件错误,去除即可。uint8改为uint8_t或unsigned char或自己宏定义
链接:https://pan.baidu.com/s/1AP3VuZz2v5gN47zDDTqCVA 提取码:d84r
将 board_spi.c 和 board_spi.h 两个文件加入工程的Application文件夹下
2.1 board_spi.c
NRF的SPI片选引脚CSN只支持低电平活动。如果该信号应该是高的,应由外部控制,即单独写个GPIO控制。
/*********************************************************************
* INCLUDES
*/
#include "nrf_drv_spi.h"
#include "nrf_gpio.h"
#include "app_error.h"
#include "board_spi.h"
#include "common.h"
static void spiCallbackFunc(nrf_drv_spi_evt_t const *pEvent, void *arg);
/*********************************************************************
* LOCAL VARIABLES
*/
static volatile bool s_transferOk = true; // SPI数据传输完成标志
static const nrf_drv_spi_t s_spiHandle = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); // SPI instance
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/**
@brief SPI的初始化函数
@param 无
@return 无
*/
void SPI_Init(void)
{
ret_code_t errCode;
nrf_drv_spi_config_t spiConfig = NRF_DRV_SPI_DEFAULT_CONFIG; // 使用SPI默认配置
// 配置SPI端口,注意CSN不要在这设置,另外用GPIO口控制
spiConfig.miso_pin = BOARD_SPI0_MISO_IO;
spiConfig.mosi_pin = BOARD_SPI0_MOSI_IO;
spiConfig.sck_pin = BOARD_SPI0_CLK_IO;
spiConfig.mode = NRF_DRV_SPI_MODE_0;
spiConfig.frequency = SPI_FREQUENCY_FREQUENCY_K250;
spiConfig.irq_priority = 4; // 在定时器中使用优先级需小于6
errCode = nrf_drv_spi_init(&s_spiHandle, &spiConfig, spiCallbackFunc, NULL);
APP_ERROR_CHECK(errCode);
nrf_gpio_cfg_output(BOARD_SPI0_CSN_IO);
}
/**
@brief SPI片选信号设置
@param pinState -[in] 引脚状态
@return 无
*/
void SPI_CsnSet(bool pinState)
{
if(pinState == BOARD_SPI_CS_OFF)
{
nrf_gpio_pin_write(BOARD_SPI0_CSN_IO, 1);
}
else if(pinState == BOARD_SPI_CS_ON)
{
nrf_gpio_pin_write(BOARD_SPI0_CSN_IO, 0);
}
}
/**
@brief SPI读出写入数据
@param pWriteData -[in] 写入数据
@param pReadData -[out] 读出数据
@param writeDataLen -[in] 写入数据长度
@return 无
*/
void SPI_ReadWriteData(uint8 *pWriteData, uint8 *pReadData, uint8 writeDataLen)
{
s_transferOk = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&s_spiHandle, pWriteData, writeDataLen, pReadData, writeDataLen));
while(!s_transferOk)
{
__WFE();
} // Error in SPI or transfer already in progress.
}
/**
@brief 开启SPI,与初始化区别:没有初始化CS引脚
@param 无
@return 无
*/
void SPI_Enable(void)
{
ret_code_t errCode;
nrf_drv_spi_config_t spiConfig = NRF_DRV_SPI_DEFAULT_CONFIG; // 使用SPI默认配置
// 配置SPI端口,注意CSN不要在这设置,另外用GPIO口控制
spiConfig.miso_pin = BOARD_SPI0_MISO_IO;
spiConfig.mosi_pin = BOARD_SPI0_MOSI_IO;
spiConfig.sck_pin = BOARD_SPI0_CLK_IO;
spiConfig.mode = NRF_DRV_SPI_MODE_0;
spiConfig.frequency = SPI_FREQUENCY_FREQUENCY_M8;
spiConfig.irq_priority = 4; // 在定时器中使用优先级需小于6
errCode = nrf_drv_spi_init(&s_spiHandle, &spiConfig, spiCallbackFunc, NULL);
APP_ERROR_CHECK(errCode);
}
/**
@brief 禁用SPI
@param 无
@return 无
*/
void SPI_Disable(void)
{
nrf_drv_spi_uninit(&s_spiHandle);
}
/*********************************************************************
* LOCAL FUNCTIONS
*/
/**
@brief SPI中断处理回调函数
@param 无
@return 无
*/
static void spiCallbackFunc(nrf_drv_spi_evt_t const *pEvent, void *arg)
{
s_transferOk = true;
}
/****************************************************END OF FILE****************************************************/
2.2 board_spi.h
#ifndef _BOARD_SPI_H_
#define _BOARD_SPI_H_
/*********************************************************************
* INCLUDES
*/
#include <stdbool.h>
#include "common.h"
/*********************************************************************
* DEFINITIONS
*/
#define BOARD_SPI_CS_ON 0
#define BOARD_SPI_CS_OFF 1
#define SPI_CS_HIGH SPI_CsnSet(BOARD_SPI_CS_OFF)
#define SPI_CS_LOW SPI_CsnSet(BOARD_SPI_CS_ON)
#define BOARD_SPI0_MISO_IO 17
#define BOARD_SPI0_MOSI_IO 18
#define BOARD_SPI0_CLK_IO 20
#define BOARD_SPI0_CSN_IO 19
#define SPI_INSTANCE 0 // SPI instance index
/*********************************************************************
* API FUNCTIONS
*/
void SPI_Init(void);
void SPI_CsnSet(bool pinState);
void SPI_ReadWriteData(uint8 *pWriteData, uint8 *pReadData, uint8 writeDataLen);
void SPI_Enable(void);
void SPI_Disable(void);
#endif /* _BOARD_SPI_H_ */
三、API调用
需包含头文件 board_spi.h
SPI_Init
功能 | 初始化SPI驱动 |
---|---|
函数定义 | void SPI_Init(void) |
参数 | 无 |
返回 | 无 |
1.其中CS片选信号引脚不要直接在 spiConfig.ss_pin 设置,需要自己另外用GPIO驱动
2.spiConfig.irq_priority 为中断优先级,如果在定时器中使用则优先级需小于6
3.spiConfig.frequency 为传输速率,最高可设为SPI_FREQUENCY_FREQUENCY_M8即 8 Mbps
4.spiConfig.mode 为SPI模式,有4种模式0-3,通常为模式0
SPI_CsnSet
功能 | SPI片选信号设置 |
---|---|
函数定义 | void SPI_CsnSet(bool pinState) |
参数 | pinState:引脚状态 |
返回 | 无 |
SPI_ReadWriteData
功能 | SPI读出写入数据 |
---|---|
函数定义 | void SPI_ReadWriteData(uint8_t *pWriteData, uint8_t *pReadData, uint8_t writeDataLen) |
参数 | pWriteData:写入数据 pReadData:读出数据 writeDataLen:写入数据长度 |
返回 | 无 |
SPI_Enable
功能 | 开启SPI,实现低功耗配合SPI_Disable使用 |
---|---|
函数定义 | void SPI_Enable(void) |
参数 | 无 |
返回 | 无 |
SPI_Disable
功能 | 禁用SPI,实现低功耗配合SPI_Enable使用 |
---|---|
函数定义 | void SPI_Disable(void) |
参数 | 无 |
返回 | 无 |
四、SDK配置
点击 sdk_config.h 文件
选择 Configuration Wizard
nRF_Drivers 中勾选SPI及SPIM相关选项
在 nRF_Drivers 中添加文件
五、使用例子
1)添加头文件
#include "board_spi.h"
2)添加初始化代码(SDK15.3 中 ble_peripheral 的 ble_app_template 工程 main() 函数中)
加入 SPI_Init() 并在初始化后调用 SPI_Disable 进入低功耗,在需要用SPI时调用 SPI_Enable 开启SPI
int main(void)
{
bool erase_bonds;
/*-------------------------- 外设驱动初始化 ---------------------------*/
// Initialize.
log_init(); // 日志驱动初始化
timers_init(); // 定时器驱动初始化(在此加入自定义定时器)
SI522_Init(); // SI522驱动初始化(含SPI)
/*-------------------------- 蓝牙协议栈初始化 ---------------------------*/
power_management_init();
ble_stack_init(); // 协议栈初始化
gap_params_init();
gatt_init();
advertising_init(); // 广播初始化
services_init(); // 服务初始化
conn_params_init(); // 连接参数初始化
peer_manager_init();
/*-------------------------- 开启应用 ---------------------------*/
// Start execution.
NRF_LOG_INFO("Template example started.");
advertising_start(erase_bonds); // 开启广播
application_timers_start(); // 定时器应用开启(在此开启自定义定时器)
SPI_Disable(); // 禁用SPI,进入低功耗模式,等待读卡时再开启
// Enter main loop.
for(;;)
{
idle_state_handle();
}
}
3)写入数据
uint8_t temp[1] = {0x01};
SPI_ReadWriteData(temp, NULL, sizeof(uint8_t));
4)查看示波器
CLK
MOSI
• 由 Leung 写于 2019 年 12 月 24 日
• 参考:青风电子社区
网友评论