52832 PPI+SPI移植

2024-01-13 10:48
文章标签 移植 spi ppi 52832

本文主要是介绍52832 PPI+SPI移植,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、测试的平台

      本篇文章主要介绍将SPI功能移植到ble_app_hrs_pca10040_s132工程上。

整个测试平台如下

    环境:win10,64位,MDK集成开发环境.
    SDK:nRF5_SDK_15.2
    协议栈:s132_nrf52_6.1_softdevice.hex.
    硬件平台:pca10040开发板.

二、工作原理

        这里使用了SPI的PPI模式,能够极大的提高SPI的读写速度,减少MCU的干预,可以极大的节省功耗。当你对SPI的读写预先将NRF_SPIM0->TXD.PTR指向写buffer,将NRF_SPIM0->RXD.PTR指向读buffer。

       每次进行SPI读写的时候,指针会自动往后移,当数据的长度达到buffer的长度时,需要将NRF_SPIM0->TXD.PTR和NRF_SPIM0->TXD.PTR重新置位。

三、Application移植

1、添加相关C文件

      需要添加TIMER、PPI、SPI、GPIOTE四个外设的相关文件

      在工程中添加nrfx_ppi.c,nrf_drv_ppi.c,nrfx_spi.c,nrf_drv_spi.c,nrfx_spim.c,nrfx_gpiote.c这六个文件

2、添加头文件

       添加相关头文件

3、加入SPI相关代码

       SPI普通模式可以参考nRF5_SDK_15.2.0_9412b96\examples\peripheral\spi例程,在移植到协议栈中时,要注意在sdk_config.h中提高SPI的中断优先级,否则会无法进入中断

       SPI的PPI模式可以参照一下程序去编写:

     (1)SPI初始化

              在SPI的PPI模式中,只会调用到SCK,SIMO,SOMI这三个引脚。所以片选脚要自己去拉低拉高或者配置为GPIOTE模式,使用PPI去触发GPIOTE事件。

void ADC_SPIDMA_Init (void) //初始化SPI DMA相关参数
{ NRF_SPIM0->TXD.MAXCNT = 2;//每次写两个字节 (16位寄存器)NRF_SPIM0->RXD.MAXCNT = 2;//每次读两个字节 (16位数据)NRF_SPIM0->TXD.LIST=1; //开启写DMANRF_SPIM0->TXD.PTR=(uint32_t)&SPIWriteList; //指向写bufferNRF_SPIM0->RXD.LIST=1; //开启读DMANRF_SPIM0->RXD.PTR=(uint32_t)&SPIReadList1; //指向读buffer 
}void CS_Gpiote_Init(void) //初始化片选脚,一定要使用GPIOTE模式
{ uint32_t err_code; nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);  //设置为切换触发err_code = nrf_drv_gpiote_out_init(SPI_SS_PIN, &config); //设置GPIOTE引脚APP_ERROR_CHECK(err_code); // nrf_drv_gpiote_out_task_enable(SPI_SS_PIN); //使能GPIOTE事件nrf_drv_gpiote_out_set(SPI_SS_PIN); //
}void spi_init(void)
{nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
//	spi_config.ss_pin   = SPI_SS_PIN;spi_config.miso_pin = SPI_MISO_PIN;spi_config.mosi_pin = SPI_MOSI_PIN;spi_config.sck_pin  = SPI_SCK_PIN;APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event, NULL));CS_Gpiote_Init();ADC_SPIDMA_Init();
}

(2)SPI中断事件

         当数据达到指定长度时重新置位指针。

void spi_event(nrf_drv_spi_evt_t const * p_event,void *                    p_context)
{spi_count++;if(spi_count==80)//buffer长度{spi_count=0; NRF_SPIM0->TXD.PTR=(uint32_t)&SPIWriteList;//重新将指针指回起始地址NRF_SPIM0->RXD.PTR=(uint32_t)&SPIReadList1;//将指针指回起始地址}
}

       也可以加入开关控制,避免数据被覆盖。

      当检测到send_flag置1时,进行相关数据的读取,读完数据再调用SPI_start进行SPI的相关使能。

      中间可以调用SPI_stop失能SPI和定时器,这样可以节省大部分的功耗。

void spi_event(nrf_drv_spi_evt_t const * p_event,void *                    p_context)
{spi_count++;if(spi_count==80){nrf_drv_timer_pause(&m_timer1);//暂停PPI触发定时器spi_count=0; send_flag = 1;}
}void SPI_reset_buff(void)
{spi_count = 0;NRF_SPIM0->TXD.PTR=(uint32_t)&SPIWriteList;NRF_SPIM0->RXD.PTR=(uint32_t)&SPIReadList1;
}void SPI_stop(void)
{nrf_drv_timer_disable(&m_timer1);nrf_spim_disable(NRF_SPIM0);
}void SPI_start(void)
{SPI_reset_buff();//复位指针nrf_spim_enable(NRF_SPIM0);	//使能SPInrf_drv_timer_enable(&m_timer1);//使能TIMER
}

(3)PPI事件

       这里一共有两个PPI事件,事件1是触发SPI开始以及GPIOTE,事件2是触发GPIOTE

void my_ppi_init(void)
{uint32_t err_code = NRF_SUCCESS;err_code = nrf_drv_ppi_init();//init PPIAPP_ERROR_CHECK(err_code);err_code = nrf_drv_timer_init(&m_timer1, NULL, timer_handler1);//init timer 1APP_ERROR_CHECK(err_code);/* setup m_timer for compare event every 15us */uint32_t ticks = nrf_drv_timer_us_to_ticks(&m_timer1, 15);nrf_drv_timer_extended_compare(&m_timer1, NRF_TIMER_CC_CHANNEL0, ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);//设置比较时间nrf_drv_timer_enable(&m_timer1);//使能定时器uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer1, NRF_TIMER_CC_CHANNEL0);uint32_t spi_start_event_addr = nrf_drv_spi_start_task_get(&spi);uint32_t spi_end_event_addr = nrf_drv_spi_end_event_get(&spi);uint32_t gpiote_out_event_addr = nrf_drv_gpiote_out_task_addr_get(SPI_SS_PIN);/* setup ppi channel so that timer compare event is triggering sample task in SAADC */err_code = nrf_drv_ppi_channel_alloc(&time_ppi_channel);APP_ERROR_CHECK(err_code);err_code = nrf_drv_ppi_channel_assign(time_ppi_channel, timer_compare_event_addr, gpiote_out_event_addr);//timer触发gpiote,片选脚拉低APP_ERROR_CHECK(err_code);err_code=nrf_drv_ppi_channel_fork_assign(time_ppi_channel,spi_start_event_addr);//timer触发spiAPP_ERROR_CHECK(err_code);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, spi_end_event_addr, gpiote_out_event_addr);//spi结束触发gpiote,片选脚拉高APP_ERROR_CHECK(err_code);err_code = nrf_drv_ppi_channel_enable(time_ppi_channel);APP_ERROR_CHECK(err_code);err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);APP_ERROR_CHECK(err_code);
}

 

这篇关于52832 PPI+SPI移植的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/601187

相关文章

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

RT-Thread(Nano版本)的快速移植(基于NUCLEO-F446RE)

目录 概述 1 RT-Thread 1.1 RT-Thread的版本  1.2 认识Nano版本 2 STM32F446U上移植RT-Thread  2.1 STM32Cube创建工程 2.2 移植RT-Thread 2.2.1 安装RT-Thread Packet  2.2.2 加载RT-Thread 2.2.3 匹配相关接口 2.2.3.1 初次编译代码  2.2.3.

stm32之软件SPI读写W25Q64存储器应用案例

系列文章目录 1. stm32之SPI通信协议 文章目录 系列文章目录前言一、电路接线图二、应用案例代码三、应用案例分析3.1 SPI通信模块3.2 W25Q64模块3.3 主程序 前言 提示:本文主要用作在学习江科大自化协STM32入门教程后做的归纳总结笔记,旨在学习记录,如有侵权请联系作者 本案例使用软件SPI通信的方式实现了STM32与W25Q64 Flas

libmad音频解码库-Linux交叉编译移植

下载并解压libmad-0.15.1b.tar.gz 下载链接:https://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz $tar -xvf libmad-0.15.1b.tar.gz$cd libmad-0.15.1b 1、先执行下面的命令:这条命令是为了适配高版本的gcc,因为高版本的gcc已经将-fforce-mem去除了:

arm linux lua移植

lua: lua home 1.下载lua源码 lua下载 lua-5.3.4.tar.gz 2.解压: tar xvf lua-5.3.4.tar.gz 3.修改makefile and luaconf.h $修改 lua-5.3.4/Makefile #INSTALL_TOP= /usr/local INSTALL_TOP= $(shell pwd)/out #修改安装目录(当前目录/o

Flink1.10基于工厂模式的任务提交与SPI机制

《2021年最新版大数据面试题全面开启更新》 Flink任务执行模式包含了yarn-session、standalone、per-job、local, 在1.10中又增加k8s的执行模式,那么在任务提交过程中如何根据不同的执行模式进行任务提交呢?主要通过两个接口来实现:PipelineExecutorFactory 与 PipelineExecutor。PipelineExecutorF

s3c2440---PWM使用之蜂鸣器驱动移植

一、蜂鸣器驱动介绍 1.1.什么是蜂鸣器               蜂鸣器是一种简单的声响发生器,常用于电子产品中作为警示或提醒作用。其基本原理是通过交替改变直流电的电压方向来产生声音,一般使用交替电流产生声音会比较稳定。 1.2.蜂鸣器的类别 1.有源蜂鸣器 1)结构原理 有源蜂鸣器内部自带振荡源,只需接通电源即可发声。内部电路会自动产生一定频率的振荡信号,从而驱动蜂鸣器发声。

转载 SPI的比喻理解

SPI 传输是一个虚拟的移位寄存器方式。 你这么理解就可以: 主机和从机之间有一条 16 格的传送带。主机一格一格拨动它转动(相当于发送时钟)。 如果是主机发送,它就把一个个的东西放在传送带上,转动 8 次,就传到从机一侧了。这时,从机可以从传送带上将东西取下。如果从机没有取东西,这些东西再转 8 次又回到主机一侧。 如果是主机接收,从机就要把 8 个东西一次放上传送带。当主机转动 8 次,东西就

【GD32】---- 移植工程模板及点灯测试

1 新建模板文件夹 新建一个名叫03_GD32TemplateProject的文件夹,用于建造工程模板 2 移植官方库文件 在模板文件夹里新建5个文件夹,分别存放官方库文件和系统驱动文件 01_main 存放main函数 02_Startup 存放系统启动文件 03_System 存放官方的系统文件 04_Firmware_PeripheralDriver 存放官方