注:本着学习的态度,本文内容参考网上诸多博客,对其做了简单总结。
以下附上部分参考链接:https://blog.csdn.net/qq_33575901/article/details/90041554
https://blog.csdn.net/secret350/article/details/80482815
一、nrf52832 定时器部分学习
定时器可被配置为两种模式:定时模式和计数模式。nrf52832有5个定时器,分别为timer0~time4,使用蓝牙时timer0会被占用。其信号来源及工作模式如下图所示。
定时器分成了软件定时器和硬件定时器,其初始化、定义、创建、启动及关闭分别如下表所示。
其中,软件定时器的操作函数详解如下:
a. 初始化定时器: app_timer_init(); //实现定时器初始化
b. 定义: APP_TIMER_DEF(my_timer_id); //调用该宏声明的ID
c. 创建: app_timer_create(app_timer_id_t const *p_timer_id, app_timer_mode_t mode,app_timer_timeout_handler_t timeout_handler); //第一个参数为声明的timer ID,第二个参数为timer的模式,模式类型如下:
typedef enum
{
APP_TIMER_MODE_SINGLE_SHOT, //单次执行
APP_TIMER_MODE_REPEATED //循环执行
} app_timer_mode_t;
第三个参数为timer的handler,每次触发时调用.时钟源来自RTC1
d. 启动: app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);
第一个参数为timer ID.第二个参数为CPU执行的tick值,参数参考APP_TIMER_TICKS(300),tick最低设置为5.第三个参数是一个通用指针,当timer到期时,将该参数传递给超时处理程序。
e. app_timer_stop(app_timer_id_t timer_id);
关闭该ID的timer,也可以使用app_timer_stop_all(void)关闭所有的timer。
二、 nrf52832 GPIOTE部分学习
GPIO的任务TASK和事件EVENT模块提供了使用任务和事件来使用GPIO的功能。nRF52832 的寄存器分为下面的三种类型。Task :任务寄存器,可以由程序或事件触发;Event:事件寄存器,事件可以产生中断或触发任务;Register:普通寄存器。
nRF52832 的 GPIOTE 共有 8 个通道,每个通道都可以选择一个管脚,选择的管脚可以配置为Task模式或Event 模式。需要注意的是:不能将某个管脚同时分配给多个 GPIOTE
通道,否则会导致无法预料的错误。GPIOTE每个通道可以使用的Task有3个,设置、清除和切换。每个通道的事件可以由上升边缘、下降边缘及任何改变产生。
GPIOTE 除了 8 个通道外,还包含一个 PORT 事件。PORT 事件由使用 GPIO DETECT 信号的多个引脚触发,PORT 中的任意一个引脚上的上升沿都会触发 PORT 事件。
a. 初始化:Nordic 的 SDK 是模块化设计的,使用 GPIOTE 模块时,先要初始化 GPIOTE 模块,初始化直接调用初始化函数 nrf_drv_gpiote_init 即可。
b. 初始化输出引脚:初始化 GPIOTE 输出引脚通过调用 nrf_drv_gpiote_out_init 函数来完成,该函数接收两个输入参数:引脚号和 GPIOTE 输出初始化结构体,引脚号指定将要配置的引脚的编号(0~31),GPIOTE 输出初始化结构体 nrf_drv_gpiote_out_config_t 包含下面的三项内容:
1) 引脚的初始状态:高电平或是低电平。
高电平:NRF_GPIOTE_INITIAL_VALUE_HIGH
低电平 NRF_GPIOTE_INITIAL_VALUE_LOW
2) 引脚动作:任务触发后引脚执行的动作。
置位(高电平):NRF_GPIOTE_POLARITY_LOTOHI
清除(低电平):NRF_GPIOTE_POLARITY_HITOLO
翻转:NRF_GPIOTE_POLARITY_TOGGLE
3) 是否为 GPIOTE 任务引脚:如果设置成 GPIOTE 任务引脚,驱动程序才会去配置前面两项(初始状态和引脚动作)并且为该引脚分配 GPIOTE 通道,否则,将该引脚按照普通GPIO 处理。需要注意,即使将引脚配置为 GPIOTE 任务引脚,也需要使能该引脚的任务触发功能,触发任务对该引脚无效。
c. 使能任务触发:初始化GPIOTE输出引脚(配置为任务引脚)为指定的引脚分配了GPIOTE通道并且配置了引脚的初始值和动作,但是并没有配置该引脚的模式即没有配置 CONFIG[n].MODE,使能任务触发就是设置 CONFIG[n].MODE = 3,即将其配置为任务模式。
使能任务触通过调用nrf_drv_gpiote_out_task_enable 函数实现,只有使能任务触发后,才能通过触发 GPIOTE 的任务让引脚执行动作。
d. 触发任务驱动引脚
nrf_drv_gpiote_out_task_trigger:触发 GPIOTE 的 TASKS_OUT 任务,每触发一次,引脚状态翻转一次。
nrf_drv_gpiote_set_task_trigger:触发 GPIOTE 的 TASKS_SET 任务,触发后,引脚输出高电平。
nrf_drv_gpiote_clr_task_trigger:触发 GPIOTE 的 TASKS_CLR 任务,触发后,引脚输出低电平。
e. 初始化 GPIOTE 输入引脚通过调用 nrf_drv_gpiote_in_init 函数来完成,该函数接收三个输入参数:引脚号、GPIOTE 输入初始化结构体和事件句柄,相对于 GPIOTE 输出引脚的初始化,函数参数多了一个事件句柄,当 GPIOTE 检测到引脚电平变化后,会产生事件,这时会自动调用这个注册的事件句柄来处理事件。
引 脚 号 指 定 将 要 配 置 的 引 脚 的 编 号 (0~31) , GPIOTE 输 入 初 始 化 结 构 体nrf_drv_gpiote_in_config_t 包含下面的 4 项内容:
1) Sense:配置引脚的 Sense 功能,可配置为下面。
高电平到低电平的变化产生事件:NRF_GPIOTE_POLARITY_HITOLO
低电平到高电平的变化产生事件:NRF_GPIOTE_POLARITY_LOTOHI
任意电平变化产生事件:NRF_GPIOTE_POLARITY_TOGGLE
2) is_watcher:是否连接输入缓冲器,设置为“true”表示连接输入缓冲器。
3) pull:是否开启引脚的上拉电阻,设置为“true”表示打开上拉。
4) hi_accuracy:是否为高精度模式,设置为“true”表示使用高精度模式。
f. 使能事件模式: 初始化 GPIOTE 输入引脚时为指定的引脚分配了 GPIOTE 通道,但是并没有配置该引脚的模式即没有配置 CONFIG[n].MODE,使能事件模式就是设置 CONFIG[n].MODE = 1,即将其配置为事件模式,当其检测到引脚电平变化时(初始化 GPIOTE 输入引脚时 Sense 项配置了哪种变化可以产生事件)即产生事件。
一、GPIOTE原理
1.概念
1)nRF52832的GPIO只能作为通用的输入输出使能,它作为输入时无法产生中断的,这时候就需要通过GPIOTE实现这种效果了;
2)GPIOTE(GPIO任务和事件),是在GPIO的基础上引入任务和事件;
3)通过任务和事件来操作IO,任务是针对输出的,它可以让IO输出不同的动作,而事件针对输入,IO的状态变化会置位事件寄存器,从而产生事件中断。
2.原理
1)nRF52832的GPIOTE共有8个通道,每个通道都可以分配给一个引脚,分配的引脚可以配置为任务模式或事件模式;
2)GPIOTE每个通道都有SET、CLR和OUT任务,其中SET任务让引脚输出高电平,CLR任务让引脚输出低电平,OUT任务可以通过配置对引脚执行置位、清零和翻转操作;
3)GPIOTE每个通道的事件都可以配置为三种输入状态:上升沿、下降沿和任意电平跳变;
4)任务和事件通过CONFIGn寄存器配置,每个CONFIG[n]寄存器可配置一个对应编号OUTn任务寄存器和IN[n]事件寄存器;
5)当通过CONFIG寄存器配置某个引脚由SET、CLR和OUT任务寄存器或IN事件寄存器控制后,该引脚只能被GPIOTE模块写操作,正常的GPIO写入无效;
6)当在同一个GPIOTE通道中同时触发了有冲突的任务,这些任务的执行级别由高到低依次为:OUT–>CLR–>SET;
7)GPIOTE除了8个通道外,还包含一个PORT事件,PORT事件是多个引脚通过GPIO DETECT信号产生的事件。
二、GPIOTE寄存器(n=0~7)
1.OUT任务寄存器
OUT[n]:对CONFIG[n].PSEL指定的引脚进行写操作,引脚动作由CONFIG[n].POLARITY中的配置决定
2.TASKS_SET任务寄存器
TASKS_SET[n]:对CONFIG[n].PSEL指定的引脚进行写操作,引脚动作为输出高电平
3.TASKS_CLR任务寄存器
TASKS_CLR[n]:对CONFIG[n].PSEL指定的引脚进行写操作,引脚动作为输出低电平
4.EVENT_IN事件寄存器
EVENT_IN[n]:CONFIG[n].PSEL指定的引脚产生的事件
5.通用寄存器
1)INTENSET:使能中断
2)INTENCLR:禁止中断
3)CONFIG[n]:OUT[n],SET[n],CLR[n]和IN[n]的配置
三、编程分析
sdk版本:nRF5_SDK_15.2.0_9412b96
1.GPIOTE输出流程
1)初始化GPIOTE模块
2)初始化GPIOTE输出引脚
3)是否使能任务模式
2.GPIOTE输入流程
1)初始化GPIOTE模块
2)配置引脚为GPIOTE输入
3)使能事件模式
3.相关库函数使用
//头文件:nrf_drv_gpiote.h
1)ret_code_t nrf_drv_gpiote_init(void)
功能:初始化GPIOTE模块
2)ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin,nrf_drv_gpiote_out_config_t const *p_config)
功能:初始化GPIOTE输出引脚,输出引脚初始化设置中会设定引脚的动作(低电平到高电平、高电平到低电平或者翻转状态)和初始化状态(高电平或低电平)
3)void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin)
功能:释放GPIOTE输出引脚
4)void nrfx_gpiote_out_task_enable(nrfx_drv_gpiote_pin_t pin)
功能:使能GPIOTE输出引脚的任务模式
5)void nrfx_gpiote_out_task_disable(nrfx_drv_gpiote_pin_t pin)
功能:禁止GPIOTE输出引脚的任务模式
6)触发任务驱动引脚函数
1>nrf_drv_gpiote_set_task_trigger(nrf_drv_gpiote_pin_t pin)
功能:收到触发GPIOTE SET任务,触发后,对应的引脚输出高电平
2>nrf_drv_gpiote_clr_task_trigger(nrf_drv_gpiote_pin_t pin)
功能:收到触发GPIOTE CLR任务,触发后,对应的引脚输出低电平
3>nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin)
功能:收到触发GPIOTE OUT任务,触发后,对应的引脚输出状态翻转
7)ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin,nrf_drv_gpiote_in_config_t const *p_config,nrf_drv_gpiote_evt_handler_t evt_handler)
功能:初始化GPIOTE输入引脚,
8)void nrfx_gpiote_in_event_enable(nrfx_drv_gpiote_pin_t pin,bool int_enable)
功能:使能GPIOTE输入引脚