当前位置: 首页 > news >正文

nRF52832——GPIOTE与外部中断

这里写目录标题

  • GPIOTE 原理分析
  • GPIOTE 输入事件应用
    • GPIOTE 事件寄存器应用
    • GPIOTE 事件组件的应用(库函数)
    • GPIOTE PORT 事件应用
  • GPIOTE 任务应用
    • GPIOTE 任务触发 LED 寄存器操作
    • 组件方式进行任务配置


GPIOTE 原理分析

GPIO 任务和时间(GPIOTE)模块提供了使用任务和事件访问 GPIO 引脚的功能。每个 GPIOTE 通道被分配到一个引脚,GPIOTE 其实就是对 GPIO 口进行操作,同时引入了外部中断的概念。

比如按键控制分为两种情况:

  • 按键扫描:CPU 需要不停工作来判断 GPIO 引脚是否有拉低或者置高,效率很低;
  • 外部中断控制:中断控制的效率很高,一旦系统 IO 口出现上升或下降沿电平就会触发中断内的程序。

在 nRF52832 内部普通的 IO 管脚设置成 GPIO,中断和任务管脚设置成 GPIOTE。
nRF5x 系列处理器将 GPIO 的中断的快速触发做成了一个单独的模块 GPIOTE,这个模块不仅提供了 GPIO 的中断功能,同时提供了通过 task 和 event 方式来访问 GPIO 的功能。GPIOTE 的后缀 T 即为 task,E 为 event。

Event 称为事件,来源与 GPIO 的输入、定时器的匹配中断等可以产生中断的外设来触发。Task 称为任务,就是执行某一特定功能,比如翻转 IO 端口等。那么事件 event 触发任务 task。task 和 event 的组合是为了和 52832 中的 PPI(可编程外围设备互联系统)模块的配合使用。这种机制不需要 CPU 参与,极大的减少了内核消耗,降低功率,特别适合于 BLE 低功耗蓝牙进行应用。

GPIOTE 实际上分为两种模式:

  • 任务模式:作为输出使用
  • 事件模式:作为中断触发使用

GPIOTE task 任务模式,每个 GPIOTE 通道最多可以使用三个任务来执行引脚的写操作。

  • 固定的输出高电平(SET)
  • 固定的输出低电平(CLR)
  • 输出任务(OUT)可以配置为执行 置位清零切换

GPIOTE event 事件模式,可以从以下输入条件之一在每个 GPIOTE 通道中生成事件:

  • 上升边缘
  • 下降边缘
  • 任何改变

任务模式有三种状态:置位、清零、翻转;事件模式有三种触发状态:上升沿触发、下降沿触发、任意变化触发。TASJK 任务通过通道 OUT[0]-OUT[7] 设置输出触发状态,Event 则可以通过检测信号产生 PORT event 事件,产生 IN[n] event 事件。

整个 GPIOTE 寄存器的个数非常少。GPIOTE 模块提供了 8 个通道,这 8 个通道都是通过 CONFIG[0]~CONFIG[7] 寄存器来配置。八个通道可以通过单独设置来分别和普通的 GPIO 绑定。当需要使用 GPIOTE 的中断功能时可以设置相应寄存器的相关位,让某个通道作为 event 事件模式,同时配置触发 event 动作。比如绑定的引脚有上升沿跳变或者下降沿跳变触发 event,然后配置中断使能寄存器,配置让其 event 产生时触发输入中断。这样实现了 GPIO 的中断方式。
在这里插入图片描述

  1. GPIO 绑定 GPIOTE 通道
    那么如何实现和普通 GPIO 端口的绑定了?关键是设置 GPIOTE 的 CONFIG[n]n = 0~7 寄存器,如下。
    在这里插入图片描述
    在这里插入图片描述
    如上描述,每个 GPIOTE 通道通过 CONFIG.PSEL 字段与一个物理 GPIO 引脚相绑定。
  • 在 CONFIG.MODE 中选择时间模式时:CONFIG.PSEL 绑定的引脚将被配置为输入,从而覆盖 GPIO 中的 DIR 设置。
  • 当在 CONFIG.MODE 中选择任务模式时:CONFIG.PSEL 绑定的引脚将被配置为输出,也会覆盖 GPIO 中的 DIR 寄存器设置和 OUT 值的输出。
  • 当在 CONFIG.MODE 中选择 disabled 时,CONFIG.PSEL 绑定的引脚将使用普通 GPIO 中 PIN[n].CNF 寄存器的配置,也就是不绑定。因此只能将一个 GPIOTE 通道分配给一个 GPIO 物理引脚。
  1. 设置为事件模式
    当设置为事件模式时,因为事件模式就是输入,通过输入信号可以出发事件中断。基本步骤如下:
  • 首先在寄存器 CONFIG.PSEL 绑定引脚,设置一个 GPIO 管脚绑定 GPIOTE 通道;
  • 在 CONFIG.MODE 设置为事件模式
  • 在 CONFIG.POLARITY 中设置触发事件模式的输入电平
  • 当对应电平输入 GPIOTE 通道后就会产生中断,EVENTS_IN 寄存器就来判断对应端口中断事件是否发生。

在这里插入图片描述

  1. 设置为任务模式
    因为任务模式为输出模式。配置过程:
  • 首先需要设置 CONFIG.PSEL 绑定 GPIO 管脚;
  • 然后设置 CONFIG.MODE 为 GPIOTE 任务模式
  • 设置 CONFIG.POLARITY OUT[n[ 任务输出:置位、清零、切换
  • 设置完成后触发任务。TASKS_OUT[n] 触发 OUT[n] 值、TASKS_SET[n] 触发高电平、TASKS_CLR[n] 触发低电平
    三种状态触发同时申请,则优先级如下执行:
任务状态优先级
TASKS_OUT1
TASKS_CLR2
TASKS_SET3

在这里插入图片描述

  1. 中断配置
    中断是在事件模式下触发的,如果在配置寄存器 CONFIG[n] 中,绑定了对应的 GPIO 端口,同时配置为事件输入模式,那么可以通过 INTENSET 寄存器是能对应的中断通道。通过 INTENCLR 寄存器关闭对应的中断通道。INTENSET 寄存器和 INTENCLR 寄存器如下表所示:

INTENSET 寄存器
在这里插入图片描述
在这里插入图片描述

INTENCLR 寄存器
在这里插入图片描述

GPIOTE 输入事件应用

GPIOTE 事件寄存器应用

修改前面 GPIO 应用按键应用改为中断控制方式。中断控制的效率很高,一旦系统 IO 口出现上升沿或者下降沿电平就会触发执行中断内的处理程序。这样可以大大节省 CPU 的占用。中断在计算机多任务处理,尤其是实时系统重尤为有用,这样的系统包括运行在骑上的操作系统,也成为“中断驱动”。

硬件方面,和前面讲述 GPIO 输入扫描哪里的按键输入应用一样。四个按键分别连接 P0.13、 P0.14、 P0.15、 P0.16。

在这里插入图片描述
在使用 nRF52832 完成中断时,当 IO 管脚为低的时候可以判断管脚已经按下。通过 key 的中断来控制 led 的亮灭。硬件上设计是比较简单的,这和普通的 MCU 的中断用法一致。如下创建工程。
在这里插入图片描述
这样我们需要编写 exit.c 文件,主要有两部分:初始化开发板上的按键中断;编写中断执行代码。
按键中断这里实际上使用了事件模式。在 CONFIG 寄存器里进行了事件模式的配置。代码如下:

NRF_GPIOTE->CONFIG[0] = (GPIOTE_CONFIG)_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos) //输入事件极性| (13 << GPIOTE_CONFIG_PSEL_Pos)//绑定的引脚| (GPIOTE_COFNIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos);//模式配置

上面的代码严格按照寄存器要求进行,首先是 MODE 模式设置,配置 GPIOTE 通道作为 event 还是 task 使用,这里设置成 event 事件。PSEL 设置对应绑定的 IO 管脚,选择 P0.13 作为触发管脚,POLARIY 极性设置为下降沿触发。
设置好了工作方式后,我们就需要进行中断的使能了,因为前面绑定的是 GPIOTE 的 0 通道,因此中断使能代码如下:

NVIC_EnableIRQ(GPIOTE_IRQn);//中断嵌套是能
NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_IN0_Set <<GPIOTE_INTENSET_IN0_Pos;//是能中断通道 IN0

上面任务基本上就可以把 GPIOTE 管脚中断配置好了,如果搞清楚这些寄存器配置很简单。中断函数的设计这里主要讲 LED 灯状态翻转,当然也可以加入对应的其他处理操作。

void GPIOTE_IRQHander()
{if((NRF_GPIOTE->EVENTS_IN[0] == 1) &&(NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk)){Delay(10000);//延迟消抖NRF_GPIOTE->EVENTS_IN[0] = 0;//中断事件清零}LED_Toggle();//led 灯状态翻转
}

完成 exit.c 的编写后,main 主函数的操作就很简单,直接调用写好的驱动函数,然后尝试按键是否有对应的响应即可。

#include "nrf52.h"
#include "nrf_gpio.h"
#include "exit.h"
#include "led.h"int mian()
{LED_Init();LED_Open();EXIT_KEY_Init();while(1){//这里暂时控制,主操作死循环}return 0;
}

GPIOTE 事件组件的应用(库函数)

通过使用 nrf 官方库函数可以更加方便完成整个过程的操作,对于寄存器操作我们仅仅只需要了解原理即可,如果非要使用寄存器去完成开发对日后维护和使用有很大弊端,所以官方已经将这部分进行了完美的封装。我们根据官方 SDK 的封装接口进行调用完成对应操作即可。

添加了 SDK 库函数的工程和之前也有所不同,这里添加了 nRF_Libraries 库函数路径。
在这里插入图片描述
官方也提供了一个驱动 nrfx_gpiote 的 GPIOTE 驱动库,但是这个驱动库带有错误跟踪函数,所以工程中必须添加错误跟踪库。同时区别于寄存器编程,组件库还需要配置 sdk_config.h 配置文件。

打开 sdk_config.h 配置文件,打开配置向导 Configuration Wizard,勾选以下两个使能项目,

  • GPIOTE_ENABLE 使能 GPIOTE 驱动库
  • NRFX_GPIOTE__ENABLE 使能 GPIOTE 兼容库
    在这里插入图片描述
    同时需要再 C/C++ 中添加硬件 GPIOTE 的库文件和头文件路径,如下:
    在这里插入图片描述
    库函数介绍:
  1. 函数 nrf_drv_gpiote_init 等同于函数 nrfx_gpiote_init
    在这里插入图片描述

  2. 函数 nrf_drv_gpiote_in_init 等同于函数 nrfx_gpiote_in_init
    在这里插入图片描述
    在这里插入图片描述

  3. nrf_drv_gpiote_in_event_enable 等同于函数 nrfx_gpiote_in_event_enable
    在这里插入图片描述

介绍完了前面的库函数接口。由于驱动组件库 SDK 已经编写好了,我们只需要编写 main.c 的主函数调用即可。

#include <stdbool.h>
#include "nrf.h"
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#include "boards.h"#ifdef BSP_BUTTON_0#define PIN_IN BSP_BUTTON_0
#endif
#ifndef PIN_IN#error "Please indicate input pin"
#endif#ifdef BSP_LED_0#define PIN_OUT BSP_LED_0
#endif
#ifndef PIN_OUT#error "Please indicate output pin"
#endif/**GPIOTE中断处理*/
void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{if(nrf_gpio_pin_read(PIN_IN)== 0)//按键防抖{nrf_gpio_pin_toggle(PIN_OUT);}
}
/**
配置GPIOTE初始化*/
static void gpio_init(void)
{nrf_gpio_cfg_output(PIN_OUT);//led灯的输出ret_code_t err_code;err_code = nrf_drv_gpiote_init();//初始化GPIOTEAPP_ERROR_CHECK(err_code);nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);in_config.pull = NRF_GPIO_PIN_PULLUP;//设置GPIOTE输入,极性,模式err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);APP_ERROR_CHECK(err_code);//使能GPIOTEnrf_drv_gpiote_in_event_enable(PIN_IN, true);
}/**
主函数,循环等待中断*/
int main(void)
{gpio_init();while (true){// Do nothing.}
}

GPIOTE PORT 事件应用

把普通的 GPIO 端口配置为 GPIOTE 中断输入事件,能够绑定的只有 8 个通道,如果我们中断的数据量超过了 8 个,多的中断无法处理,如何出现这种情况,怎么处理?显然芯片设计厂家为了针对这种情况,特别在 GPIOTE 模块中提出了 GPIOTE PORT 功能。

GPIOTE PORT 是从使用 GPIO DETECT 信号的多个 IO 输入引脚来生成的事件。该事件将在 DETECT 信号的上升沿而产生。也就是说这个功能可以通过 32 个 IO 端口来产生,相当于一个总通道,32 个 IO 端口共用这个通道来申请中断。

同时 GPIO DETECT 信号就是通过 GPIO 的 SENSE 寄存器打开,此功能始终处于启用状态。即便外围设备本身是休眠状态,也不需要请求时钟或其他功率密集型基础架构来启用此功能。因此此功能可用于在系统启动时从 WFI 或 WFE 类型的睡眠时,来唤醒 CPU、所有外设和 CPU 空闲。达到唤醒系统启动模式下的最低功耗模式。
为了在配置源时防止来自 PORT 事件的虚假中断,用户应首先禁用 PORT 事件中的中断(通过 INTENCLR.PORT),然后配置源(PIN_CNF[n].SENSE),清除配置期间可能发生的任何潜在事件(向EVENTS_PORT写入“1”),最后启用中断(通过INTENSET.PORT)。

采用组件库编写 GPIOTE 输入事件与 GPIOTE PORT 事件的主要区别:

  • 配置事件的时候选择 IN 事件还是 PORT 事件,这个通过配置函数实现,GPIOTE_CONFIG_IN_SENSE_HITOLO(false),当函数参数是 false 的时候选择 PORT 事件;当函数参数是 true 的时候,选择 IN 事件
  • 所有 32 个 IO 端口触发的中断都是 INTENSET.PORT,因此配置都指向一个中断配置就可以了。
#include <stdbool.h>
#include "nrf.h"
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#include "boards.h"/**GPIOTE中断处理*/
void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{//事件由按键S1产生,即按键S1按下if(pin == BUTTON_1){//翻转指示灯D1的状态nrf_gpio_pin_toggle(LED_1);}//事件由按键S2产生,即按键S2按下else if(pin == BUTTON_2){//翻转指示灯D2的状态nrf_gpio_pin_toggle(LED_2);}//事件由按键S3产生,即按键S3按下else if(pin == BUTTON_3){//翻转指示灯D3的状态nrf_gpio_pin_toggle(LED_3);}//事件由按键S4产生,即按键S4按下else if(pin == BUTTON_4){//翻转指示灯D4的状态nrf_gpio_pin_toggle(LED_4);}}
/**
配置GPIOTE初始化*/
static void gpio_init(void)
{   //配置LED灯输出nrf_gpio_cfg_output(LED_1);nrf_gpio_cfg_output(LED_2);nrf_gpio_cfg_output(LED_3);nrf_gpio_cfg_output(LED_4);ret_code_t err_code;//初始化GPIOTEerr_code = nrf_drv_gpiote_init();APP_ERROR_CHECK(err_code);//配置SENSE模式,选择fales为sense配置nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);in_config.pull = NRF_GPIO_PIN_PULLUP;//配置按键0绑定POTRerr_code = nrf_drv_gpiote_in_init(BSP_BUTTON_0, &in_config, in_pin_handler);APP_ERROR_CHECK(err_code);nrf_drv_gpiote_in_event_enable(BSP_BUTTON_0, true);//配置按键1绑定POTRerr_code = nrf_drv_gpiote_in_init(BSP_BUTTON_1, &in_config, in_pin_handler);APP_ERROR_CHECK(err_code);nrf_drv_gpiote_in_event_enable(BSP_BUTTON_1, true);//配置按键2绑定POTRerr_code = nrf_drv_gpiote_in_init(BSP_BUTTON_2, &in_config, in_pin_handler);APP_ERROR_CHECK(err_code);nrf_drv_gpiote_in_event_enable(BSP_BUTTON_2, true);//配置按键3绑定POTRerr_code = nrf_drv_gpiote_in_init(BSP_BUTTON_3, &in_config, in_pin_handler);APP_ERROR_CHECK(err_code);nrf_drv_gpiote_in_event_enable(BSP_BUTTON_3, true);}/**
主函数,循环等待中断*/
int main(void)
{gpio_init();while (true){// Do nothing.}
}

修改 sdk_config.h 配置文件,将其中中断配置的事件数目修改为 4。
在这里插入图片描述

GPIOTE 任务应用

GPIOTE 任务触发 LED 寄存器操作

GPIOTE 具有任务模式,任务模式就是输出模式。如果把 GPIO 管脚绑定了 GPIOTE 通道后,把它配置为任务模式,则可以实现输出功能。任务模式的使用不是孤立的,一般都是由事件来触发任务,如果在事件和任务中间假设一个通道,也就是后面的 PPI,那么整个过程不需要 CPU 参与了,大大节省了 MCU 资源。

构建工程:

在这里插入图片描述

新建 GPIOTE.c,首先是 GPIOTE 任务初始化,初始化两个 GPIOTE 通道。初始化首先设置通道 CONFIG[0].PSEL 域设置绑定 GPIO 的 19 管脚,CONFIG[1].PSEL 绑定 20 管脚;再设置两个通道的 CONFIG.MODE 为 TASK 任务模式;最后设置 CONFIG.POLARITY 为 OUT[0] 任务输出位翻转电平,OUT[1] 输出低电平。具体如下:

#include "nrf52.h"
#include "nrf_gpio.h"
#include "GPIOTE.h"void Delay(uint32_t temp)
{for(; temp!= 0; temp--);
} void GPIOTE_TASK_Init(void)
{NVIC_EnableIRQ(GPIOTE_IRQn);//中断嵌套设置//绑定两个GPIOTENRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)//设置极性,翻转| (GPIOTE0 << GPIOTE_CONFIG_PSEL_Pos)  //绑定管脚| (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos);//设置模式//配置任务输出状态、绑定通道、任务模式(详细说明请参看青风教程)NRF_GPIOTE->CONFIG[1] =  (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos)//输出低电平| (GPIOTE1<< GPIOTE_CONFIG_PSEL_Pos)  | (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos);配置任务输出状态、绑定通道、任务模式(详细说明请参看青风教程)}

主函数 main 中只需要初始化即可。

#include "nrf52.h"
#include "nrf_gpio.h"
#include "GPIOTE.h"
#include "led.h"
#include "nrf_delay.h"int main(void)
{/*初始化输出任务*/GPIOTE_TASK_Init();while(1){//触发输出任务模式NRF_GPIOTE->TASKS_OUT[0]=1;//由config寄存器里的极性配置觉得输出的信号NRF_GPIOTE->TASKS_OUT[1]=1;nrf_delay_ms(500);}
}

组件方式进行任务配置

和前面操作类似,这里使用 SDK 库函数的 API 进行组件方式的任务配置。

  1. nrf_drv_gpiote_out_init,类似 nrfx_gpiote_out_init
    在这里插入图片描述
  2. nrf_drv_gpiote_out_task_enabel , 类似 nrfx_gpiote_out_task_enabel
    在这里插入图片描述
    具体操作代码如下:

#include <stdbool.h>
#include "nrf.h"
#include "nrf_drv_gpiote.h"
#include "app_error.h"
#include "nrf_delay.h"#define GPIOTE0       19
#define GPIOTE1       20void GPIOTE_TASK_Init(void){ret_code_t err_code;	//初始化GPIOTE程序模块err_code = nrf_drv_gpiote_init();APP_ERROR_CHECK(err_code);//定义GPIOTE输出初始化结构体,主要是配置为翻转模式nrf_drv_gpiote_out_config_t config1 = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);////绑定GPIOTE输出引脚err_code = nrf_drv_gpiote_out_init(GPIOTE0, &config1);APP_ERROR_CHECK(err_code);//配置为引脚LED_3所在GPIOTE通道的任务模式nrf_drv_gpiote_out_task_enable(GPIOTE0);  //定义GPIOTE输出初始化结构体,主要是配置为低电平模式nrf_drv_gpiote_out_config_t config2 = GPIOTE_CONFIG_OUT_TASK_LOW;//绑定GPIOTE输出引脚err_code = nrf_drv_gpiote_out_init(GPIOTE1, &config2);APP_ERROR_CHECK(err_code);//配置为引脚LED_4所在GPIOTE通道的任务模式nrf_drv_gpiote_out_task_enable(GPIOTE1); 	}int main(void)
{GPIOTE_TASK_Init();   while(true){ //触发输出,即指示灯D3,D4翻转状态nrf_drv_gpiote_out_task_trigger(GPIOTE0);     nrf_drv_gpiote_out_task_trigger(GPIOTE1);nrf_delay_ms(500);}
} 

相关文章:

nRF52832——GPIOTE与外部中断

这里写目录标题 GPIOTE 原理分析GPIOTE 输入事件应用GPIOTE 事件寄存器应用GPIOTE 事件组件的应用&#xff08;库函数&#xff09;GPIOTE PORT 事件应用 GPIOTE 任务应用GPIOTE 任务触发 LED 寄存器操作组件方式进行任务配置 GPIOTE 原理分析 GPIO 任务和时间&#xff08;GPIO…...

根据用户名称实现单点登录

一、参数格式 二、后端实现 Controller层 public class IAccessTokenLoginController extends BaseController {Autowiredprivate ISysUserService sysUserService;Autowiredprivate ISingleTokenServiceImpl tokenService;/*** 登录方法** return 结果*/PostMapping("/l…...

【设计】855. 考场就座

855. 考场就座 这段代码实现了一个考场安排座位的算法。在这个算法中&#xff0c;考场被模拟成一个从0到n-1的数轴&#xff0c;其中每个位置代表一个座位。目的是在每次学生入座时&#xff0c;找到一个使得所有学生之间距离最大化的座位&#xff0c;并在学生离开时更新座位信息…...

Android中的传感器类型和接口名称

本文将介绍传感器坐标轴、基础传感器和复合传感器&#xff08;动作传感器、姿势传感器、未校准传感器和互动传感器&#xff09;。 1. 传感器坐标轴 许多传感器的传感器事件值在相对于设备静止的特定坐标系中表示。 1.1 移动设备坐标轴 Sensor API 仅与屏幕的自然方向相关&a…...

解析进程 /proc/pid/maps 和 /proc/pid/smaps

目录 /proc//maps 背景 具体描述 代码实现 实践 /proc/pid/smaps smaps各子项详解 代码实现 代码调用的路径如下&#xff1a; 小结 /proc/<pid>/maps 背景 相对于/proc/meminfo和dumpsys meminfo可以看到系统整体的内存信息&#xff0c;我们还需要能够具体到…...

【MQ】消息队列概述

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;MQ ⛺️稳中求进&#xff0c;晒太阳 定义 消息队列&#xff1a;一般我们简称为MQ(Message Queue) Message Queue :消息队列中间件&#xff0c;很多初学者认为&#xff0c;MQ通过消息的发送…...

交友盲盒系统PHP开源的盲盒源码

源码介绍&#xff1a; 交友盲盒系统是一款基于PHP开发的开源免费盲盒系统&#xff0c;旨在为用户提供一个充满乐趣和惊喜的社交体验。该系统具有丰富的功能和灵活的扩展性&#xff0c;可以轻松地满足各种线上交友、抽奖活动等场景的需求。 安装说明&#xff1a; PHP版本&…...

【Flutter 面试题】什么是异步编程 Flutter中如何处理异步操作?

【Flutter 面试题】什么是异步编程 Flutter中如何处理异步操作&#xff1f; 文章目录 写在前面解答补充说明从网络API异步获取数据并解析 写在前面 关于我 &#xff0c;小雨青年 &#x1f449; CSDN博客专家&#xff0c;GitChat专栏作者&#xff0c;阿里云社区专家博主&#x…...

处理error: remote origin already exists.及其Gitee文件上传保姆级教程

解决error: remote origin already exists.&#xff1a; 删除远程 Git 仓库 git remote rm origin 再添加远程 Git 仓库 git remote add origin &#xff08;HTTPS&#xff09; 比如这样&#xff1a; 然后再push过去就ok了 好多人可能还是不熟悉怎么将文件上传 Gitee:我…...

网络编程套接字(2)——Socket套接字

目录 一、概念 二、分类 1、流套接字&#xff08;使用传输层TCP协议&#xff09; TCP的特点 2、数据报套接字&#xff08;使用传输层UDP协议&#xff09; UDP的特点 3、原始套接字 一、概念 Socket套接字&#xff0c;是由系统提供用于网络通信的技术&#xff0c;是基于T…...

向量错题本

《1800》 1 看变换求和能不能成为0,为0,就是线性相关 2 矩阵等价 3 4<...

FPGA-VGA成像原理与时序

什么是VGA: VGA, Video Graphics Array。即视频图形阵列,具有分辨率高、显示速率快、颜色丰富等优点。VGA接口不但是CRT显示设备的标准接口,同样也是LCD液晶显示设备的标准接口,具有广泛的应用范围。在FGPA中,常广泛用于图像处理等领域。 VGA 显示器成像原理 在 VGA 标准刚兴…...

【VTKExamples::Points】第三期 ExtractClusters

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例ExtractClusters,并解析接口vtkEuclideanClusterExtraction,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我…...

迅速上手:CentOS 系统下 SSH 服务配置指南

前言 掌握 SSH 服务&#xff0c;就像拥有了一把解锁网络世界的钥匙。本文深入浅出地介绍了如何使用 SSH&#xff08;Secure Shell&#xff09;服务&#xff0c;从连接远程服务器到安全文件传输&#xff0c;让你轻松驾驭远程管理与数据传输&#xff0c;提高工作效率&#xff0c…...

day38 动态规划part1

509. 斐波那契数 简单 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;…...

01背包问题 刷题笔记

思路 dp 用f[i][j]来表示当体积为j时 考虑前i件物品可以获得的 最大值 记住f[i][j]本身是个价“价值” 考虑两种状态 是否将第i件物品放入背包里面 将背包的体积从小到大递增来进行考虑 首先 考虑条件 如果当前增加的体积放不下下一件物品 则该体积 可以获得的最大值可以直接…...

docker安装包(Linux和windows)

Linux——docker-20.10.9.tgz 网盘地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1T3qfVZ-uT-vMAo8w6heTMw 提取码&#xff1a;qu85 windows——docker19.03.1 链接&#xff1a;https://pan.baidu.com/s/1mK6hqhkGCBs6tdBHJxrdPw 提取码&#xff1a;4dkj...

RabbitMQ 安装使用

文章目录 RabbitMQ 安装使用安装下载 Erlang下载 RabbitMQ 的服务安装好后看是否有 RabbitMQ 的服务开启管理 UIRabbitMQ 端口使用一览图 使用输出最简单的 Hello World&#xff01;生产者定义消费者消费消息小拓展 RabbitMQ 安装使用 安装 下载 Erlang RabbitMQ 是用这个语…...

echarts x轴名称过长tip显示全称

xAxis的axisLabel的内容如下&#xff1a; axisLabel: { rotate: -45, color: document.body.className.indexOf(custom-f4c46d) > -1 ? #fff : #343434, // 显示省略号操作&#xff08;第一步&#xff09; formatter: function (value) { var val if (value.length >…...

js和css阻塞问题

面试常见问题 css 加载会不会阻塞 js 的加载&#xff1f;&#xff08;不会&#xff09;css 加载会不会阻塞 js 的执行&#xff1f;&#xff08;会&#xff09;css 加载会不会阻塞 DOM 的解析&#xff1f;&#xff08;不会&#xff09;css 加载会不会阻塞 DOM 的渲染&#xff1…...

MySQL 的基础操作

数据库的基础操作 1. 库操作2. 表的操作3. 数据类型 数据库是现代应用程序中至关重要的组成部分&#xff0c;通过数据库管理系统&#xff08;DBMS&#xff09;存储和管理数据。 1. 库操作 创建数据库 创建数据库是开始使用数据库的第一步。下面是一些常见的创建数据库的示例&a…...

【python进阶篇】面向对象编程(1)

面向对象编程——Object Oriented Programming&#xff0c;简称OOP&#xff0c;是一种程序设计思想。OOP把对象作为程序的基本单元&#xff0c;一个对象包含了数据和操作数据的函数。 在Python中&#xff0c;所有数据类型都可以视为对象&#xff0c;当然也可以自定义对象。自定…...

力扣面试经典150 —— 6-10题

力扣面试经典150题在 VScode 中安装 LeetCode 插件即可使用 VScode 刷题&#xff0c;安装 Debug LeetCode 插件可以免费 debug本文使用 python 语言解题&#xff0c;文中 “数组” 通常指 python 列表&#xff1b;文中 “指针” 通常指 python 列表索引 文章目录 6. [中等] 轮转…...

[密码学]入门篇——加密方式

一、概述 加密方法主要分为两大类&#xff1a; 单钥加密&#xff08;private key cryptography&#xff09;&#xff1a;加密和解密过程都用同一套密码双钥加密&#xff08;public key cryptography&#xff09;&#xff1a;加密和解密过程用的是两套密码 历史上&#xff0c…...

构建前后端分离项目常用的代码

构建前后端分离项目常用的代码 1.代码生成器 import com.baomidou.mybatisplus.generator.FastAutoGenerator;import com.baomidou.mybatisplus.generator.config.OutputFile;import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;​import java.util.…...

2575. 找出字符串的可整除数组(Go语言)

https://leetcode.cn/problems/find-the-divisibility-array-of-a-string/ 在看题解之前&#xff0c;我的代码是以下这样&#xff1a; package mainimport ("fmt" )func main() {fmt.Println(divisibilityArray("998244353", 3)) }func divisibilityArray…...

Redis与 Memcache区别

Redis与 Memcache区别 1 , Redis 和 Memcache 都是将数据存放在内存中&#xff0c;都是内存数据库。不过 Memcache 还可用于缓存 其他东西&#xff0c;例如图片、视频等等。 2 , Memcache 仅支持key-value结构的数据类型&#xff0c;Redis不仅仅支持简单的key-value类型的数据&…...

#QT(智能家居界面-界面切换)

1.IDE&#xff1a;QTCreator 2.实验 3.记录 &#xff08;1&#xff09;创建一个新界面&#xff08;UI界面&#xff09; &#xff08;2&#xff09;可以看到新加入一个ui文件&#xff0c;双击打开&#xff0c;设置窗口大小与登录界面一致 &#xff08;3&#xff09;加入几个PUS…...

js拓展-内置对象

目录 1. 数组对象 1.1 数组的四种方式 1.2 JS中数组的特点 1.3 常用方法 2. 日期对象 2.1 日期对象的创建 2.2 日期对象的方法 2.3 案例&#xff1a;输出现在的时间 3. 全局对象 3.1 字符串转换成数字类型 3.2 编码解码函数 1. 数组对象 注&#xff1a;数组在JS中是一…...

【李沐精读系列】GPT、GPT-2和GPT-3论文精读

论文&#xff1a; GPT&#xff1a;Improving Language Understanding by Generative Pre-Training GTP-2&#xff1a;Language Models are Unsupervised Multitask Learners GPT-3&#xff1a;Language Models are Few-Shot Learners 参考&#xff1a;GPT、GPT-2、GPT-3论文精读…...