nordic的nrf52系列32M速率的SPI-SPIM3
简介:在nordic的nrf52系列中的nrf52833和nrf52840的SPIM3都是支持最大32M的spi速率,其余的只有8M,当在需要刷屏,或者一些需要高速32M-SPI时,这是一个很好的使用方式,下面我就结合GPIOTE+PPI+SPIM3实现无CPU参与的32M-SPI数据发送:

测试环境:软件:SDK_17.1,在ble_app_uart例子中添加
硬件:nrf52832-DK板
一、引脚选择
特别注意一点,需要使用32M的SPI时,一定要选择非低频的引脚作为SPI的pin脚,如下面这些引脚就不可以:

在数据手册中还有这样一条提示,他的意思是在使用32M的时候,可能还要配置为高驱模式,不然可能有数据错乱。

根据数据手册我当前选择4,5,27,26这4个引脚作为SPI的引脚。
二、代码编写
1.源文件添加
在工程中加入如下几个.c源文件,其中spi_test.c不是官方库文件,是我的SPIM配置代码,这一点注意,你只用添加前面的5个源文件就行

2、宏定义启用
这一步主要是启用相关的源文件,如果宏定义不启用刚刚添加的部分源文件是无法添加的,这一步很重要:

先启用SPIM3:

还要勾选另一个宏定义,在调试过程中发现如果只启动NRFX_SPI_ENABLED,不任意使能它下面的NRFX_SPI0_ENABLED,NRFX_SPI1_ENABLED,NRFX_SPI2_ENABLED的其中一个,居然无法让NRFX_SPIM_ENABLED生效,这一点需要注意一下。


经过以上的宏定义勾选,SPI的驱动就启动完成了。
启用PPI:


到这一步宏定义就都启用完成了,你可以检测一下加入的源文件是否都启用了。
然后就是代码部分,我已经进行了相关注释,可以直接copy使用。
三、代码
1、.c文件
#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nrf_drv_gpiote.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h> /*log打印的头文件*/
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h" #include "nrf_drv_ppi.h"
#include "spi_test.h" #define PIN_IN BUTTON_4
#define leng 10
#define TEST_STRING "spi_ppi_test" uint8_t TX_buffer[]=TEST_STRING;
uint8_t RX_buffer[leng]; /*PPI 通道实例变了定义*/
static nrf_ppi_channel_t m_ppi_channel; /*SPIM3可以达到32M*/
static nrfx_spim_t my_spi=NRFX_SPIM_INSTANCE(3); /*变量定义,用于确定SPI是否正确传输,每一次都会进行加一,0x31只是一个本次随意设置的初始值*/
uint8_t test=0x31; /*同时设置TX和RX的buffer*/
nrfx_spim_xfer_desc_t m_buffer = NRFX_SPIM_XFER_TRX(TX_buffer,sizeof(TX_buffer),RX_buffer,leng);
/**
* @brief SPI user event handler.
* @param event
*/
void spi_event_handler(nrfx_spim_evt_t const * p_event,
void * p_context)
{
ret_code_t err_code;
/*传输事件判断*/
if(NRF_DRV_SPI_EVENT_DONE == p_event->type)
{
NRF_LOG_INFO("Transfer completed.")
TX_buffer[0]=++test;
/*一次传输完成,提供下一次传输的buffer,如果有大量接收的数据,可以使用两个buffer交替接收,便于流出时间进行数据处理,第二个buffer也是使用
nrfx_spim_xfer_desc_t m_buffer = NRFX_SPIM_XFER_TRX(TX_buffer2,sizeof(TX_buffer2),RX_buffer2,leng2);进行定义,如果是只想单独定义一个TX和RX
请使用 NRFX_SPIM_XFER_TX 或者 NRFX_SPIM_XFER_RX
*/
err_code = nrfx_spim_xfer(&my_spi,&m_buffer,NRF_DRV_SPI_FLAG_HOLD_XFER);
APP_ERROR_CHECK(err_code);
}
/*如果有接收数据就打印一下,实际应用中可以是其余处理*/
if (RX_buffer[0] != 0)
{
NRF_LOG_INFO(" Received:");
NRF_LOG_HEXDUMP_INFO(RX_buffer, strlen((const char *)RX_buffer));
}
} void gpiote_init(void)
{
ret_code_t err_code;
/*由于这个例子是基于ble_app_uart,在 主函数中的buttons_leds_init(&erase_bonds);中已经初始化了GPIOTE,所以注释掉,不能重复初始化*/
// err_code = nrf_drv_gpiote_init();
// APP_ERROR_CHECK(err_code); nrf_drv_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
in_config.pull = NRF_GPIO_PIN_PULLUP; /*由于这个例子是基于ble_app_uart,在 主函数中的buttons_leds_init(&erase_bonds);中已经初始化了DK板上的按键4,我要用来做SPI数据触发,所以先解绑这个引脚在配置 */
nrf_drv_gpiote_in_uninit(PIN_IN);
/* 中断初始化,回调为NULL,因为是通过PPI触发SPIM所以不需要回调,当然如果有需要你也可以设置 */
err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, NULL);
APP_ERROR_CHECK(err_code);
/* GPIO中断事件使能 */
nrf_drv_gpiote_in_event_enable(PIN_IN, true);
} void spim_init(void)
{
/*不能使用低频引脚,还要配置为高驱*/
nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
spi_config.ss_pin = 27;
spi_config.miso_pin = 4;//如果是刷屏可以不使用MISO数据pin脚,可以设置为 NRFX_SPIM_PIN_NOT_USED
spi_config.mosi_pin = 5;
spi_config.sck_pin = 26;
spi_config.frequency=NRF_SPIM_FREQ_32M;
APP_ERROR_CHECK(nrfx_spim_init(&my_spi, &spi_config, spi_event_handler, NULL)); /*高驱配置*/
nrf_gpio_cfg(27,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(4,
NRF_GPIO_PIN_DIR_INPUT,
NRF_GPIO_PIN_INPUT_CONNECT,
NRFX_SPIM_MISO_PULL_CFG,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(5,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg(26,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE); NRF_LOG_INFO("SPI init end.");
} void ppi_init(void)
{
ret_code_t err_code; err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code); /*给spi初始化缓存,并flag选择什么时候启动传输*/
/*NRF_DRV_SPI_FLAG_HOLD_XFER ---- 占时不启用,可在PPI触发下的SPIM的传输*/
err_code = nrfx_spim_xfer(&my_spi,&m_buffer,NRF_DRV_SPI_FLAG_HOLD_XFER);
APP_ERROR_CHECK(err_code); /* 触发的事件地址*/
uint32_t gpio_event_addr = nrfx_gpiote_in_event_addr_get(PIN_IN);
/* 执行的任务地址 */
uint32_t spim_tick_addr = nrfx_spim_start_task_get(&my_spi); /*PPI设置*/
//把PPI的通道1分配出来
err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
APP_ERROR_CHECK(err_code);
/* 关联事件和任务*/
err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
gpio_event_addr,
spim_tick_addr);
APP_ERROR_CHECK(err_code);
/* 启动PPI*/
err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
APP_ERROR_CHECK(err_code); } void SPIM_test_init(void)
{
spim_init();
gpiote_init();
ppi_init();
}
2、.h文件
#ifndef SPI_TEST_H__
#define SPI_TEST_H__ void SPIM_test_init(void); #endif
只要在主函数中引用SPIM_test_init();就可以了。
nordic的nrf52系列32M速率的SPI-SPIM3的更多相关文章
- Nordic nRF52系列/nRF5340硬件设计(一)选型及原理图设计
Nordic 的BLE系列芯片从第一代的nRF51系列,到第二代的nRF52系列,发展到目前最新的第三代的nRF5340.目前市场中使用最多的nRF52系列一共有七款芯片,它们是:nRF52805.n ...
- nRF52系列来袭,Nordic的低功耗蓝牙方案大有可为
坐落在北欧的挪威不像他的邻居芬兰那样,可以先后依靠NOKIA和愤怒的小鸟在世界科技界享有盛名.在一般人看来,挪威除了一个逐渐式微的Opera浏览器以外,并没有更多拿得出手的科技企业.而事实证明这只 ...
- nordic——nrf52系列SWD设置回读保护
在开发时可能需要回读保护功能,在产品出厂后这个功能可以让你的代码更加安全,无法用SEGGER或者其余方式读取你的代码HEX文件,也就是禁用SWD下载接口.但是SWD锁住了,还想使用(从新下载代码)也是 ...
- nRF52系列——nRF52832来袭
nRF52系列——nRF52832来袭 Nordic凭借着在无线技术的数十年深耕,推出第一个μBlue芯片-- nRF8001.其低功耗等特性在当时吸引了无数厂商的目光,并将这产品应用到多个领域,再之 ...
- NRF52840相对于之前的NRF52系列、NRF51系列增加了什么功能
现在广大客户的蓝牙采用NORDIC越来越多了,NORDIC一直在不断进行技术改进更好的满足市场需求 推出了新款NRF52840.NRF52840更为先进些,支持的功能也多点,比如IEEE802.15. ...
- Nordic nRF51/nRF52开发环境搭建
本文将详述Nordic nRF51系列(包括nRF51822/nRF51802/nRF51422等)和nRF52系列(包括nRF52832/nRF52810/nRF52840)开发环境搭建. 1. 强 ...
- Nordic nRF51/nRF52开发流程说明
Nordic nRF51系列包括nRF51822/nRF51422/nRF51802等芯片,nRF52系列包括nRF52832/nRF52840/nRF52810等芯片,硬件工程师可以按照如下流程去评 ...
- Nordic NRF51822 从零开始系列(外部设备片—MPU6050DMP驱动的移植)
一.硬件准备 (1)开发板和软件参看 Nordic NRF51822 从零开始系列(一)开发环境的搭建 (2)mpu6050模块 二.前置知识 ...
- Nordic NRF51822 从零开始系列(一)开发环境的搭建
硬件准备 (1)nrf51822 开发板一块(此处使用的是青云系列的,自带jlijnk ob+usb串口芯片)或者使用nrf51822模块+jlink_ob ( ...
- 【Dubbo源码阅读系列】之 Dubbo SPI 机制
最近抽空开始了 Dubbo 源码的阅读之旅,希望可以通过写文章的方式记录和分享自己对 Dubbo 的理解.如果在本文出现一些纰漏或者错误之处,也希望大家不吝指出. Dubbo SPI 介绍 Java ...
随机推荐
- 文心一言 VS 讯飞星火 VS chatgpt (78)-- 算法导论7.4 2题
二.如果用go语言,证明:在最好情况下,快速排序的运行时间为 Ω(nlgn). 文心一言: 在最好情况下,快速排序的运行时间为Ω(nlgn)的证明如下: 快速排序是一种分治算法,它将一个数组分成两个子 ...
- [ABC305C] Snuke the Cookie Picker题解
题目大意 有一个 \(H\times W\) 的网格,一种有一个矩形,矩形中间有一个点被挖空,求这个点的坐标.(. 表示空白,# 表示矩形内的点) 解析 观察我们可以发现,每一矩形内的个点上下左右至少 ...
- 快手Java一面11问(附参考答案)
现在已经到了面试招聘比较火热的时候,后续会分享一些面试真题供大家复习参考.准备面试的过程中,一定要多看面经,多自测! 今天分享的是一位贵州大学的同学分享的快手一面面经. 快手一面主要会问一些基础问题, ...
- AI绘画StableDiffusion实操教程:月光下的美人(含高清图片)
本教程收集于:AIGC从入门到精通教程汇总 今天继续分享AI绘画实操教程,如何用lora包生成超真实好看质感超强的人物图片. 放大高清图已放到教程包内,需要的可以自取. 出图效果: 更多图片资源访问查 ...
- CodeForces 1367E Necklace Assembly
题意 给定一个字符串\(s\),长度为\(n\),一根项链为一个环,定义一根项链为\(k-beautiful\),则该项链顺时针转\(k\)下后与原项链相等,给出\(k\),请构造一根最长的\(k-b ...
- .NET开源最全的第三方登录整合库 - CollectiveOAuth
前言 我相信很多同学都对接过各种各样的第三方平台的登录授权获取用户信息(如:微信登录.支付宝登录.GitHub登录等等).今天给大家推荐一个.NET开源最全的第三方登录整合库:CollectiveOA ...
- Nomad 系列-安装
系列文章 Nomad 系列文章 Nomad 简介 开新坑!近期算是把自己的家庭实验室环境初步搞好了,终于可以开始进入正题研究了. 首先开始的是 HashiCorp Nomad 系列,欢迎阅读. 关于 ...
- oracle导入导出某个schema数据
背景 公司之前部门拆分,但一些服务并没有拆分清楚.其中一个老服务,两个部门都在用,现在为了避免互相影响,决定克隆该服务.克隆就要克隆全套,当然也包括数据库,我们这个老服务,用的oracle,所以,就涉 ...
- 每日一练:无感刷新页面(附可运行的前后端源码,前端vue,后端node)
1.前言 想象下,你正常在网页上浏览页面.突然弹出一个窗口,告诉你登录失效,跳回了登录页面,让你重新登录.你是不是很恼火.这时候无感刷新的作用就体现出来了. 2.方案 2.1 redis设置过期时间 ...
- Visual Studio 2022 设置代码补全
Visual Studio 2022 设置代码补全 VS默认使用 Tab 键进行代码补全. 若要使用回车补全需要重新设置,具体路径如下: 工具----选项----文本编辑器----C/C++--- ...