7、nRF52xx蓝牙学习(nrf_gpiote.c库函数学习)

续前一篇文章。

3、nrfx_gpiote_in_event_enable

void nrfx_gpiote_in_event_enable(nrfx_gpiote_pin_t pin, bool int_enable)
{NRFX_ASSERT(nrf_gpio_pin_present_check(pin));NRFX_ASSERT(pin_in_use_by_gpiote(pin));if (pin_in_use_by_port(pin)){nrf_gpiote_polarity_t polarity =port_handler_polarity_get(channel_port_get(pin) - GPIOTE_CH_NUM);nrf_gpio_pin_sense_t sense;if (polarity == NRF_GPIOTE_POLARITY_TOGGLE){/* read current pin state and set for next sense to oposit */sense = (nrf_gpio_pin_read(pin)) ?NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;}else{sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ?NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW;}nrf_gpio_cfg_sense_set(pin, sense);}else if (pin_in_use_by_te(pin)){int32_t             channel = (int32_t)channel_port_get(pin);nrf_gpiote_events_t event   = TE_IDX_TO_EVENT_ADDR((uint32_t)channel);nrf_gpiote_event_enable((uint32_t)channel);nrf_gpiote_event_clear(event);if (int_enable){nrfx_gpiote_evt_handler_t handler = channel_handler_get((uint32_t)channel_port_get(pin));// Enable the interrupt only if event handler was provided.if (handler){nrf_gpiote_int_enable(1 << channel);}}}
}

一、函数概述
nrfx_gpiote_in_event_enable 函数的主要功能是为指定的 GPIO 引脚启用 GPIOTE(通用外设中断和事件)输入事件。
该函数会根据引脚的使用情况(是由端口处理还是由定时器事件处理)来配置相应的引脚感应和事件中断。 
函数参数
pin:类型为 nrfx_gpiote_pin_t,表示要启用事件的 GPIO 引脚编号。 
int_enable:布尔类型,用于决定是否启用该引脚的中断功能。  
二、函数实现步骤
1. 断言检查


NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
NRFX_ASSERT(pin_in_use_by_gpiote(pin));


 NRFX_ASSERT(nrf_gpio_pin_present_check(pin)):使用断言确保传入的引脚 pin 是有效的,nrf_gpio_pin_present_check 函数用于检查该引脚是否存在于硬件中。如果检查失败,程序会触发断言错误。
NRFX_ASSERT(pin_in_use_by_gpiote(pin)):确保该引脚已经被 GPIOTE 使用,如果未被使用,程序会触发断言错误。  
2. 处理引脚由端口使用的情况


 if (pin_in_use_by_port(pin))
{
    nrf_gpiote_polarity_t polarity =
        port_handler_polarity_get(channel_port_get(pin) - GPIOTE_CH_NUM);
    nrf_gpio_pin_sense_t sense;
    if (polarity == NRF_GPIOTE_POLARITY_TOGGLE)
    {
        sense = (nrf_gpio_pin_read(pin)) ?
                NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH;
    }
    else
    {
        sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ?
                NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW;
    }
    nrf_gpio_cfg_sense_set(pin, sense);
}

(1)nrf_gpiote_polarity_t是一个枚举类型,定义如下:

typedef enum
{NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi,       ///<  Low to high.NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo,       ///<  High to low.NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle        ///<  Toggle.
} nrf_gpiote_polarity_t;

(2)port_handler_polarity_get函数定义如下 :

static nrf_gpiote_polarity_t port_handler_polarity_get(uint32_t handler_idx)
{uint8_t pin_and_polarity = (uint8_t)m_cb.port_handlers_pins[handler_idx];return (nrf_gpiote_polarity_t)((pin_and_polarity & POLARITY_FIELD_MASK) >> POLARITY_FIELD_POS);
}

(3)m_cb是一个静态变量,定义如下 :

static gpiote_control_block_t m_cb;

其类型为结构体类型gpiote_control_block_t,该类型是在nrfx_gpiote.c中定义的:

typedef struct
{nrfx_gpiote_evt_handler_t handlers[GPIOTE_CH_NUM + NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];int8_t                    pin_assignments[MAX_PIN_NUMBER];int8_t                    port_handlers_pins[NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];uint8_t                   configured_pins[((MAX_PIN_NUMBER)+7) / 8];nrfx_drv_state_t          state;
} gpiote_control_block_t;

此结构体的解释如下:

,它用于管理和控制通用外设中断和事件(GPIOTE)模块。

下面详细解释结构体中的每个成员:

整体用途 gpiote_control_block_t 结构体作为 GPIOTE 模块的控制块,负责存储和管理与 GPIOTE 操作相关的各种信息,包括事件处理函数、引脚分配、端口处理状态、引脚配置状态以及驱动程序的整体状态。

结构体成员解释

1. nrfx_gpiote_evt_handler_t handlers[GPIOTE_CH_NUM + NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];

• 类型:nrfx_gpiote_evt_handler_t 是一个函数指针类型,它指向处理 GPIOTE 事件的函数。该数组存储了所有 GPIOTE 通道(包括普通通道和低功耗事件通道)对应的事件处理函数。

• 用途:当特定的 GPIOTE 通道发生事件时,系统会调用该通道对应的事件处理函数来处理事件。GPIOTE_CH_NUM 代表普通 GPIOTE 通道的数量,NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 表示低功耗事件通道的数量。  

2. int8_t pin_assignments[MAX_PIN_NUMBER];

• 类型:int8_t 类型的数组,每个元素存储一个 8 位有符号整数。

• 用途:该数组用于记录每个 GPIO 引脚所分配的 GPIOTE 通道编号。MAX_PIN_NUMBER 是系统中可用的最大 GPIO 引脚数量。数组的索引对应引脚编号,数组元素的值为该引脚分配的 GPIOTE 通道编号。如果某个引脚未分配通道,通常用一个特殊值(如 -1)表示。  

3. int8_t port_handlers_pins[NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS];

• 类型:int8_t 类型的数组。

• 用途:此数组用于存储与低功耗事件通道相关的引脚信息。每个元素对应一个低功耗事件通道,可能存储该通道所关联的引脚编号或其他相关信息。  

4. uint8_t configured_pins[((MAX_PIN_NUMBER)+7) / 8];

• 类型:uint8_t 类型的数组,即无符号 8 位整数数组。

• 用途:这是一个位图数组,用于记录哪些 GPIO 引脚已经被配置为 GPIOTE 功能。通过使用位图,每个字节可以表示 8 个引脚的配置状态。((MAX_PIN_NUMBER)+7) / 8 确保数组大小足够存储所有引脚的状态。例如,如果某个引脚已配置,则对应位图中的相应位被设置为 1;否则为 0。  5. nrfx_drv_state_t state;

• 类型:nrfx_drv_state_t 是一个自定义的枚举类型,用于表示 GPIOTE 驱动程序的状态。

• 用途:该成员变量记录了 GPIOTE 驱动程序的当前状态,如初始化、运行、停止等。通过检查这个状态变量,系统可以了解 GPIOTE 模块的工作状态,并根据需要进行相应的操作。  总结 gpiote_control_block_t 结构体整合了管理 GPIOTE 模块所需的关键信息,通过这些成员变量,系统可以有效地分配通道、处理事件、跟踪引脚配置状态以及管理驱动程序的整体状态。

(4) pin_in_use_by_port(pin):

检查该引脚是否由端口处理。
 port_handler_polarity_get(channel_port_get(pin) - GPIOTE_CH_NUM):获取该引脚对应的端口处理极性。 
 极性判断: 
 如果极性为 NRF_GPIOTE_POLARITY_TOGGLE,则读取当前引脚的状态,根据状态设置感应为相反的电平(如果当前引脚为高电平,则感应设置为低电平;反之亦然)。 
 如果极性为 NRF_GPIOTE_POLARITY_LOTOHI,则感应设置为高电平;如果极性为其他值(可理解为 NRF_GPIOTE_POLARITY_HITOLO),则感应设置为低电平。   
 nrf_gpio_cfg_sense_set(pin, sense):将计算得到的感应设置应用到该引脚上。

 
(5). 处理引脚由定时器事件使用的情况
  else if (pin_in_use_by_te(pin))
{
    int32_t             channel = (int32_t)channel_port_get(pin);
    nrf_gpiote_events_t event   = TE_IDX_TO_EVENT_ADDR((uint32_t)channel);

    nrf_gpiote_event_enable((uint32_t)channel);

    nrf_gpiote_event_clear(event);
    if (int_enable)
    {
        nrfx_gpiote_evt_handler_t handler = channel_handler_get((uint32_t)channel_port_get(pin));
        // Enable the interrupt only if event handler was provided.
        if (handler)
        {
            nrf_gpiote_int_enable(1 << channel);
        }
    }
}


 pin_in_use_by_te(pin):检查该引脚是否由定时器事件处理。 
 channel_port_get(pin):获取该引脚对应的通道编号。
 TE_IDX_TO_EVENT_ADDR((uint32_t)channel):将通道编号转换为对应的 GPIOTE 事件地址。 
 nrf_gpiote_event_enable((uint32_t)channel):启用该通道的 GPIOTE 事件。 
 nrf_gpiote_event_clear(event):清除该事件的状态标志。 
 中断启用判断: 
 如果 int_enable 为 true,则获取该通道对应的事件处理函数 handler。 
 只有当事件处理函数存在时,才调用 nrf_gpiote_int_enable(1 << channel) 启用该通道的中断。    
 总结 该函数的核心是根据引脚的使用情况(端口处理或定时器事件处理)来配置引脚的感应和事件中断。
 对于端口处理的引脚,根据极性设置感应;对于定时器事件处理的引脚,启用事件、清除事件标志,并根据需要启用中断。通过这些步骤,确保指定引脚的 GPIOTE 输入事件能够正常工作。

void nrfx_gpiote_in_event_enablevoid nrfx_gpiote_in_event_enable

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/77251.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 实现插入排序:[通俗易懂的排序算法系列之三]

引言 大家好!欢迎继续关注我的排序算法系列。今天,我们要学习的是另一种非常基础且重要的排序算法——插入排序 (Insertion Sort)。 插入排序的思路非常贴近我们日常整理扑克牌的方式,理解起来相对自然。虽然它在最坏情况下的效率不高,但在某些特定场景下,它的表现甚至优…

Java的spring boot项目编译成功启动报错

问题现象&#xff1a;spring boot项目&#xff0c;候删除一些无用代码后&#xff0c;build成功&#xff0c;启动时报错&#xff1a;找不到java.util.Map或者其他对象&#xff08;用Lombok注解Data&#xff09;中的字段属性找不到等错误。解答&#xff1a; 常见是Lombok版本问题…

PyTorch参数管理详解:从访问到初始化与共享

本文通过实例代码讲解如何在PyTorch中管理神经网络参数&#xff0c;包括参数访问、多种初始化方法、自定义初始化以及参数绑定技术。所有代码可直接运行&#xff0c;适合深度学习初学者进阶学习。 1. 定义网络与参数访问 1.1 定义单隐藏层多层感知机 import torch from torch…

基于springboot+vue的课程管理系统

一、系统架构 前端&#xff1a;vue | element-ui 后端&#xff1a;springboot | mybatis-plus 环境&#xff1a;jdk1.8 | mysql8 | maven | node v16.20.2 | idea 二、代码及数据 三、功能介绍 01. 登录 02. 管理员-首页 03. 管理员-系管理 04. 管理员-专业管理 05. 管…

ssh密钥连接远程服务器并用scp传输文件

ssh密钥连接远程服务器 私钥的权限必须是600chmod 600 id_rsa连接时在命令中加上私钥的地址ssh -i PATH_to_id_rsa usernameip -p port scp -P port -i PATH_to_id_rsa file usernameip:PATH

ElasticSearch迁移数据

一、查询索引 1、查询所有索引 curl --user elastic:123456 -XGET "http://localhost:19200/_cat/indices?v&sindex" 2、查询索引配置 以索引名称hello为例 curl --user elastic:123456 -XGET "http://localhost:19200/hello/_settings?pretty" 3…

【Unity】animator检测某state动画播放完毕方法

博主对动画系统很不熟&#xff0c;可能使用的方法比较曲折&#xff0c;但是我确实没找到更有效的方法了。 unity的这个animator在我看来简直有毛病啊&#xff0c;为什么那么难以获取某状态动画的信息呢&#xff1f;&#xff1f;&#xff1f; 想要知道动画播完没有只有用norma…

Jmeter 插件【性能测试监控搭建】

1. 安装Plugins Manager 1.1 下载路径&#xff1a; Install :: JMeter-Plugins.org 1.2 放在lib/ext目录下 1.3 重启Jmeter&#xff0c;会在菜单-选项下多一个 Plugins Manager菜单&#xff0c;打开即可对插件进行安装、升级。 2. 客户端(Jmeter端) 2.1 安装plugins manager…

ollama+open-webui本地部署自己的模型到d盘+两种open-webui部署方式(详细步骤+大量贴图)

一、ollama准备 1.官网下载ollama&#xff1a;https://ollama.com/download 2.在 d 盘创建 ollama 文件夹&#xff0c;把软件包放进去 3.管理员身份运行黑窗口 win r 弹出运行窗口 输入 cmd 后&#xff0c; ctrl shift 回车&#xff0c;以管理员身份打开 3.切换到 d 盘&a…

(学习总结33)Linux Ext2 文件系统与软硬链接

Linux Ext2 文件系统与软硬链接 理解硬件磁盘、服务器、机柜、机房磁盘物理结构磁盘的逻辑结构实际过程 CHS 与 LBA 地址转换 引入文件系统引入 " 块 " 概念引入 " 分区 " 概念引入 " inode " 概念 ext2 文件系统宏观认识Block Group 块组与其内…

Go语言sync.Mutex包源码解读

互斥锁sync.Mutex是在并发程序中对共享资源进行访问控制的主要手段&#xff0c;对此Go语言提供了非常简单易用的机制。sync.Mutex为结构体类型&#xff0c;对外暴露Lock()、Unlock()、TryLock()三种方法&#xff0c;分别用于阻塞加锁、解锁、非阻塞加锁操作&#xff08;加锁失败…

SQL注入流量分析

免责声明&#xff1a;本文仅作分享 ~ 目录 SQL注入流量分析 特征&#xff1a; sqlmap注入类型 漏洞环境搭建 error_sql: bool_sql: time_sql: union_sql: Stacked Queries: Inline Queries: SQL注入流量分析 https://www.freebuf.com/column/161797.html SQLMAP攻击…

Linux 时间同步工具 Chrony 简介与使用

一、Chrony 是什么&#xff1f; chrony 是一个开源的网络时间同步工具&#xff0c;主要由两个组件组成&#xff1a; chronyd&#xff1a;后台服务进程&#xff0c;负责与时间服务器交互&#xff0c;同步系统时钟。chronyc&#xff1a;命令行工具&#xff0c;用于手动查看或修…

Flutter:Flutter SDK版本控制,fvm安装使用

1、首先已经安装了Dart&#xff0c;cmd中执行 dart pub global activate fvm2、windows配置系统环境变量 fvm --version3、查看本地已安装的 Flutter 版本 fvm releases4、验证当前使用的 Flutter 版本&#xff1a; fvm flutter --version5、切换到特定版本的 Flutter fvm use …

Vue 项目中的package.json各部分的作用和用法的详细说明

1. 基本信息 {"name": "my-vue-app","version": "1.0.0","description": "A Vue.js project","author": "Your Name <your.emailexample.com>","license": "MIT"…

Linux网络编程——TCP通信的四次挥手

一、前言 上篇文章讲到了TCP通信建立连接的“三次握手”的一些细节&#xff0c;本文再对TCP通信断开连接的“四次挥手”的过程做一些分析了解。 二、TCP断开连接的“四次挥手” 我们知道TCP在建立连接的时需要“三次握手”&#xff0c;三次握手完后就可以进行通信了。而在通…

某碰瓷国赛美赛,号称第三赛事的数模竞赛

首先我非常不能理解的就是怎么好意思自称第三赛事的呢&#xff1f;下面我们进行一个简单讨论&#xff0c;当然这里不对国赛和美赛进行讨论。首先我们来明确一点&#xff0c;比赛的含金量由什么来定&#xff1f;这个可能大家的评价指标可能不唯一&#xff0c;我通过DeepSeek选取…

Redis 缓存问题:缓存雪崩、缓存击穿、缓存穿透

文章目录 缓存雪崩缓存击穿缓存穿透在实际的业务场景中,Redis 通常作为缓存和其他数据库(例如 MySQL)搭配使用,用来减轻数据库的压力。但是在使用 Redis 作为缓存数据库的过程中,可能会遇到一些常见问题,例如缓存穿透、缓存击穿和缓存雪崩等。 缓存雪崩 缓存雪崩是指缓存…

Qt 入门 4 之标准对话框

Qt 入门 4 之标准对话框 Qt提供了一些常用的对话框类型,它们全部继承自QDialog类,并增加了自己的特色功能,比如获取颜色、显示特定信息等。下面简单讲解这些对话框,可以在帮助索引中查看Standard Dialogs关键字,也可以直接索引相关类的类名。 本文将以一个新的项目为主介绍不…

买不起了,iPhone 或涨价 40% ?

周知的原因&#xff0c;新关税对 iPhone 的打击&#xff0c;可以说非常严重。 根据 Rosenblatt Securities分析师的预测&#xff0c;若苹果完全把成本转移给消费者。 iPhone 16 标配版的价格&#xff0c;可能上涨43%。 iPhone 16 标配的价格是799美元&#xff0c;上涨43%&am…