首页 > 其他分享 >nordic—RTC+PPI定时驱动某外设做非单次触发(本次测试为驱动GPIO口做电平翻转)

nordic—RTC+PPI定时驱动某外设做非单次触发(本次测试为驱动GPIO口做电平翻转)

时间:2023-12-25 17:55:21浏览次数:23  
标签:err code RTC rtc PPI nrf drv 驱动

简介:在nordic的开发中使用到RTC时,对于比较通道0/1/2/3的中断来说如果不进行相关配置(如SDK中例子,使用的RTC比较通道就只能触发一次,不能多次触发),会导致比较中断只进入一次,如果说是使用RTC+PPI+ADC进行采样或者RTC+PPI+GPIOTE做IO口翻转等,都会只采样一次或者翻转一次就停止了,不能做的无限触发,接下来我就进行一下相关配置,让其可以无限循环起来。

测试环境:

硬件:nrf52840DK

软件路径:nordic的SDK\examples\ble_peripheral\ble_app_uart\pca10056 (在官方的SDK中的ble_app_uart例子中加入相关测试代码)

环境:keil5

一、RTC和PPI加入

1、源文件加入

加入三个文件分别是RTC和PPI的驱动文件,如果你选择ADC,作为RTC触发后要执行的任务的外设,在选择的工程没有ADC的源文件时,需要你自己加入,因为我本次测试使用的是RTC+PPI+GPIOTE去做IO口输出控制,ble_app_uart中已经有GPIOTE相关的代码了,我就不在加入了。

 

sdk_config.h修改,由于RTC需要低速时钟,默认是外部低速晶振,且协议栈使用了RTC0,然后app timer使用了RTC1,所以我就只能使用RTC2来进行配置,实际中你也可以使用RTC1的其余通道(app timer没有用到的通道进行,这就不改了,有需要自己看源码进行配置就行),因此有一些截图的配置

 以上宏定义启动完成对于RTC和PPI来说就够了GPIOTE的我使用的例子中已经启用好了,如果你驱动的是其他外设,参考SDK中和外设相关的例子进行宏定义启动就可以了,所有外设的基础例子都在如下截图的SDK路径下:

头文件加入:

#include "nrf_drv_rtc.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_gpiote.h"

二、RTC带中断的无线循环模式

初始化RTC:

const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(2);  //2就是初始化RTC2的意思
#define handle_tirgg_timer 1                 //RTC通道0的中断时间
#define GPIO_pin 16                             //需要翻转的GPIO口

在main中调用的代码

        uint32_t err_code;
        /*###############  时钟使能  ###############*/
    //ble中时钟已经初始化,不用再次初始化,否则会报错 ERROR 133 [NRF_ERROR_MODULE_ALREADY_INITIALIZED]
//    err_code = nrf_drv_clock_init();
//    APP_ERROR_CHECK(err_code);

    nrf_drv_clock_lfclk_request(NULL);

       /*################ RTC 初始化 #######################################*/ 
        
    //Initialize RTC instance
    nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
    config.prescaler = 4095;
    err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler);
    APP_ERROR_CHECK(err_code);
    /*禁用tick和溢出,你也可以根据需要启用*/   
    nrfx_rtc_tick_disable(&rtc);
    nrfx_rtc_overflow_disable(&rtc);
        /* 启用CC通道使能 */
    err_code = nrf_drv_rtc_cc_set(&rtc,0,handle_tirgg_timer * 8,true);
    APP_ERROR_CHECK(err_code);

  nrf_drv_rtc_enable(&rtc);

回调:

static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
{
    if (int_type == NRF_DRV_RTC_INT_COMPARE0)
    {
            uint32_t err_code;
       printf("NRF_DRV_RTC_INT_COMPARE0 \n");
            /* 再次设置溢出值 */
             err_code = nrf_drv_rtc_cc_set(&rtc,0,handle_tirgg_timer * 8,true);
            APP_ERROR_CHECK(err_code);
            /* 清除 */
            nrf_drv_rtc_counter_clear(&rtc);
    }
}

测试结果如下:

 注意如何你需要的是tick就不需要清除,tick配置如下:

nrfx_rtc_tick_enable(&rtc);

 

三、RTC+PPI+GPIOTE

注意:

在这里配置的时候需要注意几个点:

  • GPIO要配置为GPIOTE的out功能,否则无法用PPI去触发输出
  • RTC初始化时,需要禁用回调功能,否则也只能执行一次
  • 需要启用PPI的fork机制,用于RTC的清除,否则无法触发循环,只能执行一次。

头文件和相关变量定义:

#include "nrf_drv_rtc.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_gpiote.h"

const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(2); //2就是初始化RTC2的意思
#define handle_tirgg_timer 1     //RTC通道0的中断时间
#define GPIO_pin 16                     //需要翻转的GPIO口

1、RTC配置

RTC要工作需要启动低频时钟,代码如下

uint32_t err_code;
/*###############  时钟使能  ###############*/
    //ble中时钟已经初始化,不用再次初始化,否则会报错 ERROR 133 [NRF_ERROR_MODULE_ALREADY_INITIALIZED]
//    err_code = nrf_drv_clock_init();
//    APP_ERROR_CHECK(err_code);

 nrf_drv_clock_lfclk_request(NULL);
/*################ RTC 初始化 #######################################*/ 
    //Initialize RTC instance
    nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
    config.prescaler = 4095;
    err_code = nrf_drv_rtc_init(&rtc, &config, NULL);
    APP_ERROR_CHECK(err_code);
    /*禁用tick和overflow降低功耗 */    
        nrfx_rtc_tick_disable(&rtc);
        nrfx_rtc_overflow_disable(&rtc);
   /* 启用CC通道使能 32768/(4095+1)=0.125ms,那么1s定时为0.125*8,所以设置定时器值是乘以8了,可以自由设置 */
        err_code = nrf_drv_rtc_cc_set(&rtc,0,handle_tirgg_timer * 8,false);
    APP_ERROR_CHECK(err_code);

2、GPIO口配置为GPIOTE的OUT模式

代码如下:

uint32_t err_code;
/*################ GPIO 口初始化 ############################*/ /* 前面已经有初始化了,不用再次初始化 */ // err_code = nrf_drv_gpiote_init(); // APP_ERROR_CHECK(err_code); nrf_drv_gpiote_out_config_t out_config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); //绑定输出端口 err_code = nrf_drv_gpiote_out_init(GPIO_pin, &out_config); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_out_task_enable(GPIO_pin);

3、PPI的配置(需要PPI的fork机制)

代码如下:

  uint32_t err_code;  
/* ############### PPI 初始化 ####################*/ err_code = nrf_drv_ppi_init(); APP_ERROR_CHECK(err_code); /* 触发的事件地址*/ uint32_t rtc_event_addr = nrf_drv_rtc_event_address_get(&rtc,NRF_RTC_EVENT_COMPARE_0); /* 执行的任务地址 */ uint32_t gpio_tick_addr = nrfx_gpiote_out_task_addr_get(GPIO_pin); /* 执行二次任务的地址 */ uint32_t rtc_clear_tick_addr = nrf_drv_rtc_task_address_get(&rtc,NRF_RTC_TASK_CLEAR); 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, rtc_event_addr, gpio_tick_addr); APP_ERROR_CHECK(err_code); /* 关联二次任务 */ err_code = nrf_drv_ppi_channel_fork_assign( m_ppi_channel, rtc_clear_tick_addr); APP_ERROR_CHECK(err_code); /* 启动PPI*/ err_code = nrf_drv_ppi_channel_enable(m_ppi_channel); APP_ERROR_CHECK(err_code);

4、使能RTC

最后使能RTC:

//Power on RTC instance
    nrf_drv_rtc_enable(&rtc);

结果:你会看到GPIO口16以1s的频率进行翻转。

 

标签:err,code,RTC,rtc,PPI,nrf,drv,驱动
From: https://www.cnblogs.com/HW-liu/p/17926414.html

相关文章

  • 车灯LED光源驱动全亮半亮爆闪大电流1.5A
    产品描述AP2402是一款PWM工作模式,高效率、外围简单、内置功率管,适用于5-100V输入的高精度降压LED恒流驱动芯片。输出最大功率可达15W,最大电流1.5A。AP2402可实现三段功能切换,通过MODE1/2/3切换三种功能模式:全亮,半亮,爆闪,AP2402工作频率固定在150KHZ左右,同时内置抖频......
  • 5.10 Windows驱动开发:摘除InlineHook内核钩子
    在笔者上一篇文章《内核层InlineHook挂钩函数》中介绍了通过替换函数头部代码的方式实现Hook挂钩,对于ARK工具来说实现扫描与摘除InlineHook钩子也是最基本的功能,此类功能的实现一般可在应用层进行,而驱动层只需要保留一个读写字节的函数即可,将复杂的流程放在应用层实现是一个非常明......
  • 实时湖仓技术选型,企业如何借实时湖仓赢在“数据驱动”时代
    在之前三期的实时湖仓系列文章中,我们从业务侧、产品侧、应用侧等几个方向,为大家介绍了实时湖仓方方面面的内容,包括实时湖仓对于企业数字化布局的重要性以及如何进行实时湖仓的落地实践等。本文将从纯技术的角度,为大家解析实时湖仓的存储原理以及生态选型,为企业建设实时湖仓给出技......
  • MappingJackson2HttpMessageConverter使用及jackson配置原理和避坑说明
    转载自:https://blog.csdn.net/Heron22/article/details/109512976MappingJackson2HttpMessageConverter消息转换器创建和生效原理HttpMessageConverters对象的创建使用WebMvcConfigurationSupport配置时转换器创建过程使用WebMvcAutoConfiguration配置时转换器创建过......
  • Linux下PCI设备驱动开发详解(五)
    Linux下PCI设备驱动开发详解(五)本章及其以后的几章,我们将从用户态软件、内核态驱动、FPGA逻辑介绍一个通过PCIExpress总线实现CPU和FPGA数据通信的简单框架。这个框架就是开源界非常有名的RIFFA(reuseableintegrationframeworkforFPGAaccelerators),它是一个FPGA加速器的一种可......
  • Linux安装无线网卡驱动
    您可以通过以下步骤来实现:首先,将Linux安装盘插入电脑的USB接口。打开电脑的BIOS设置,将启动顺序设置为优先从USB设备启动。重启电脑并进入Linux安装界面。在安装过程中,选择“手动分区”选项,然后为Linux系统分配一个适当的分区。接下来,选择“安装Linux内核”选项,并等待安装完成。安装......
  • 如何解决appium 自动化无法获取悬浮窗问题
    如何解决appium自动化无法获取悬浮窗问题-CSDN博客......
  • Spring MVC 源码分析 - HandlerMapping 组件(三)之 AbstractHandlerMethodMapping
    HandlerMapping组件HandlerMapping组件,请求的处理器匹配器,负责为请求找到合适的 HandlerExecutionChain 处理器执行链,包含处理器(handler)和拦截器们(interceptors)handler 处理器是Object类型,可以将其理解成HandlerMethod对象(例如我们使用最多的 @RequestMapping 注解所标......
  • A novel local-global dependency deep learning model for soil mapping
    程哥的一区文章“Anovellocal-globaldependencydeeplearningmodelforsoilmapping”(Li和Zhang,2022,pp.-)(pdf)研究问题:“工程“discrete”特征不能反映环境协变量之间的相互作用或依赖关系”(pdf)预测的对象是土壤质地的预测。属于step1里面的对于......
  • 中文TigerBot-70B大模型:领先Llama-2,全球开源新标杆,300B数据驱动
    引言随着大型语言模型(LLM)在自然语言处理领域的日益重要,新型多语言多任务模型——TigerBot-70B的问世,标志着全球范围内一个新的技术里程碑的达成。TigerBot-70B不仅在性能上匹敌行业巨头如OpenAI的模型,而且其创新算法和数据处理方式在行业内引起广泛关注。Huggingface模型下载:https:......