ESP32-C3 入门笔记04:gpio_key 按键 (ESP-IDF + VSCode)
1.GPIO简介
ESP32-C3是QFN32封装,GPIO引脚一共有22个,从GPIO0到GPIO21。
理论上,所有的IO都可以复用为任何外设功能,但有些引脚用作连接芯片内部FLASH或者外部FLASH功能时,官方不建议用作其它用途。
通过开发板的原理图,可以看到开发板上的ESP32引脚连接情况。这里我们使用BOOT按键,来学习一下GPIO功能。
ESP32的GPIO,可以用作输入、输出,可以配置内部上拉、下拉,可以配置为中断引脚。
这里我们把连接 BOOT按键的IO9 引脚,设置为GPIO中断,接收BOOT按键请求。
2.编写程序
我们复制 esp-idf-v5.1.4\examples\get-started\sample_project
这个工程到我们的实验文件夹,然后把这个文件夹的名称修改为 gpio_key,方便日后搞清楚这个工程的作用。
在ESP-IDF的安装路径下,打开官方例程:D:\ESP_IDF\INS\Espressif\frameworks\esp-idf-v5.1.4\examples\get-started
使用 VSCode 打开 gpio_key 这个文件夹。单击打开工程一级目录下的 CMakeLists.txt 文件(注意不是 main 目录下的),然后我们把工程名字修改为 gpio_key,保存后关闭此文件。
点击打开main.c文件,发现里面只写了这么几行代码:
#include <stdio.h>void app_main(void)
{}
从这个工程原来的文件夹名字就可以知道,这是一个示例工程,我们现在需要实现按键中断,比较简单,所以在这个工程上写就可以了。
现在再打开一个VSCode软件,然后打开esp-idf-v5.1.4
整个工程文件夹,然后我们依次找到
examples\peripherals\gpio\generic_gpio
这个工程作为参考,注意不要修改这个工程中的内容和配置,只是作为参考。
单击gpio_example_main.c
打开这个文件,找到app_main
函数。
/* GPIO ExampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"/*** Brief:* This test code shows how to configure GPIO and how to use GPIO interrupts.** GPIO status:* GPIO18: output (ESP32C2/ESP32H2 uses GPIO8 as the second output pin)* GPIO19: output (ESP32C2/ESP32H2 uses GPIO9 as the second output pin)* GPIO4: input, pulled up, interrupt from rising edge and falling edge* GPIO5: input, pulled up, interrupt from rising edge.** Note. These are the default GPIO pins to be used in the example. You can* change IO pins in menuconfig.** Test:* Connect GPIO18(8) with GPIO4* Connect GPIO19(9) with GPIO5* Generate pulses on GPIO18(8)/19(9), that triggers interrupt on GPIO4/5*/#define GPIO_OUTPUT_IO_0 CONFIG_GPIO_OUTPUT_0
#define GPIO_OUTPUT_IO_1 CONFIG_GPIO_OUTPUT_1
#define GPIO_OUTPUT_PIN_SEL ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1))#define GPIO_INPUT_IO_0 CONFIG_GPIO_INPUT_0
#define GPIO_INPUT_IO_1 CONFIG_GPIO_INPUT_1
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))#define ESP_INTR_FLAG_DEFAULT 0 // 中断标志的宏定义// 将 GPIO 中断事件发送到这个队列gpio_evt_queue,以便在任务中处理。
// gpio_evt_queue 被用来接收中断处理程序发送的 GPIO 事件然后由 gpio_task_example 任务处理这些事件。static QueueHandle_t gpio_evt_queue = NULL; // 静态队列句柄// ISR 中断服务函数
static void IRAM_ATTR gpio_isr_handler(void* arg)
{uint32_t gpio_num = (uint32_t) arg;//xQueueSendFromISR是在 ISR(中断服务例程)中发送数据到 FreeRTOS 队列的函数调用。//gpio_evt_queue:要发送数据的队列句柄。//&gpio_num:要发送的数据,这里是指向 GPIO 编号的指针,表示触发中断的引脚。//NULL:优先级参数xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); }// GPIO 任务函数
static void gpio_task_example(void* arg)
{uint32_t io_num;for(;;) {// 任务处理 处理gpio_evt_queue里面的任务if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num));}}
}void app_main(void)
{// 零初始化配置结构gpio_config_t io_conf = {};// 配置输出引脚io_conf.intr_type = GPIO_INTR_DISABLE; // 禁用中断io_conf.mode = GPIO_MODE_OUTPUT; // 设置为输出模式io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; // 设置引脚gpio0/gpio1io_conf.pull_down_en = 0; // 禁用下拉模式io_conf.pull_up_en = 0; // 禁用上拉模式gpio_config(&io_conf); // 配置 GPIO// 配置输入引脚io_conf.intr_type = GPIO_INTR_POSEDGE; // 上升沿中断io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL; // 设置引脚gpio0/gpio1io_conf.mode = GPIO_MODE_INPUT; // 设置为输入模式io_conf.pull_up_en = 1; // 启用上拉模式gpio_config(&io_conf); // 配置 GPIO// 改变 GPIO 中断类型gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE); // 任何边缘中断// 创建队列以处理 ISR 的 GPIO 事件gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));// 启动 GPIO 任务xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);// 安装 GPIO ISR 服务gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);// 钩住 ISR 处理程序gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);// 从 GPIO 中移除 ISR 处理程序(可选)gpio_isr_handler_remove(GPIO_INPUT_IO_0);gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0); // 再次钩住 ISRprintf("Minimum free heap size: %"PRIu32" bytes\n", esp_get_minimum_free_heap_size());int cnt = 0;while(1) {printf("cnt: %d\n", cnt++);vTaskDelay(1000 / portTICK_PERIOD_MS);gpio_set_level(GPIO_OUTPUT_IO_0, cnt % 2); // 切换输出引脚状态gpio_set_level(GPIO_OUTPUT_IO_1, cnt % 2); // 切换输出引脚状态}
}
复制它的前几行语句(第80~93行)到我们自己的gpio_key工程中,如下所示:
#include <stdio.h>void app_main(void)
{//zero-initialize the config structure.gpio_config_t io_conf = {};//disable interruptio_conf.intr_type = GPIO_INTR_DISABLE; // 关闭中断//set as output modeio_conf.mode = GPIO_MODE_OUTPUT; // 输出模式//bit mask of the pins that you want to set,e.g.GPIO18/19io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; // 配置引脚号//disable pull-down modeio_conf.pull_down_en = 0; // 上下拉电阻,0是关闭,1是打开//disable pull-up modeio_conf.pull_up_en = 0; //configure GPIO with the given settingsgpio_config(&io_conf);// 使用gpio_config函数进行配置
}
在gpio_example_main.c
文件中的GPIO_INTR_DISABLE上单击右键,然后选择“转到定义”,就可以找到这几个宏定义,如下所示:
typedef enum {
GPIO*INTR_DISABLE = 0, //*!< Disable GPIO interrupt 禁用 GPIO 中断 _/
GPIO_INTR_POSEDGE = 1, //_!< GPIO interrupt type : rising edge 中断类型:上升沿_/
GPIO_INTR_NEGEDGE = 2, //_!< GPIO interrupt type : falling edge 中断类型:下降沿_/
GPIO_INTR_ANYEDGE = 3, //_!< GPIO interrupt type : both rising and falling edge 中断类型:上升沿和下降沿均可_/
GPIO_INTR_LOW_LEVEL = 4, //_!< GPIO interrupt type : input low level trigger 中断类型:低电平触发_/
GPIO_INTR_HIGH_LEVEL = 5,//_!< GPIO interrupt type : input high level trigger 中断类型:高电平触发\_/
GPIO_INTR_MAX,
} gpio_int_type_t;
上面的代码,总结来说一下,就是先定义一个GPIO结构体,然后给GPIO结构体成员变量赋值,然后使用GPIO配置函数配置GPIO。给结构体成员变量赋值,也可以在定义的时候直接赋值,如下代码所示:
方法1:
void app_main(void)
{
gpio_config_t io_conf = {
.intr_type = GPIO_INTR_NEGEDGE, //falling edge interrupt
.mode = GPIO_MODE_INPUT, //set as input mode
.pin_bit_mask = 1<<GPIO_NUM_9, //bit mask of the pins GPIO9
.pull_down_en = 0, //disable pull-down mode
.pull_up_en = 1 //enable pull-up mode
};
//configure GPIO with the given settings
gpio_config(&io_conf);
}
方法2:
void app_main(void)
{
//zero-initialize the config structure.
gpio_config_t io_conf = {};
//falling edge interrupt
io_conf.intr_type = GPIO_INTR_NEGEDGE;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//bit mask of the pins GPIO9
io_conf.pin_bit_mask = 1<<GPIO_NUM_9;
//disable pull-down mode
io_conf.pull_down_en = 0;
//enable pull-up mode
io_conf.pull_up_en = 1;
//configure GPIO with the given settings
gpio_config(&io_conf);
}
接下来,我们再复制gpio_example_main.c
文件中的第108~116行代码到我们的main.c
文件中。
//create a queue to handle gpio event from isrgpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));//start gpio taskxTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);//install gpio isr servicegpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);//hook isr handler for specific gpio pingpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
开始,定义了一个队列句柄,用来处理gpio队列消息。
然后,定义了两个函数。
第一个函数是gpio 中断服务函数,当GPIO产生中断的时候呢,会进入这个函数,xQueueSendFromISR函数将参数GPIO_NUM_9添加到队列消息。
第二个函数是gpio的 任务函数,在任务函数中,接收队列消息,当接收到一个队列消息时,打印字符串。
PRIu32 是C语言中用于格式化输出的宏,用于打印32位无符号整数。它是由C99标准
引入的,位于inttypes.h
头文件中。在使用该宏时,需要包含inttypes.h头文件。
gpio_get_level
函数用于获取引脚的电平。 这些内容,不需要做修改。 接下来,我们再把需要的头文件添加到我们的main.c文件就可以了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
使用printf函数,需要添加stdio.h头文件。string.h和stdlib.h我们这里用不着,可以去掉。接下来是3个freeRTOS的头文件,最后一个头文件是用于gpio的配置。
3.编译和下载
接下来,依次配置VSCode左下角的配置选项,串口号、目标芯片、下载方式、menuconfig里面,把FLASH大小修改为8MB,其它不做修改。
中断输入是项目中常用的方式,如果你想试试查询法,可以不开中断,使用gpio_get_level函数查询引脚电平。 引脚设置为输出,可以使用gpio_set_level来控制引脚的电平。具体使用方法,可以查看我们刚才参考的gpio例程。 ESP32还有一个特殊的引脚,就是GPIO11,它默认是VDD_SPI引脚,VDD_SPI默认是一个3.3V输出的电源引脚,可以用来给外部的FLASH芯片供电,这个引脚也可以修改为GPIO11,作为通用引脚使用。需要注意的是,这个修改是不可逆的,修改成GPIO11以后,就不能再修改为3.3V输出电源引脚了。我们在设计电路的时候,可以根据需求,决定是否用这个引脚给外部FLASH供电。我们的开发板没有用这个引脚给外部FLASH供电,而是作为GPIO引脚。这个引脚设置为GPIO的方法,我们会在I2S音频接口章节介绍。
源文件 main.c
#include <stdio.h>
#include <inttypes.h>// C99标准 PRIu32无符号32位数据类型
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"// 声明一个静态队列句柄,用于处理 GPIO 事件
static QueueHandle_t gpio_evt_queue = NULL;// GPIO 中断服务例程(ISR)处理函数
static void IRAM_ATTR gpio_isr_handler(void* arg)
{uint32_t gpio_num = (uint32_t) arg; // 获取触发中断的 GPIO 编号xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); // 将 GPIO 编号发送到队列
}// GPIO 任务示例
static void gpio_task_example(void* arg)
{uint32_t io_num; // 存储接收到的 GPIO 编号for(;;) {// 从队列中接收 GPIO 事件,阻塞直到有数据可用 portMAX_DELAY表示如果没有接收到消息,则会一直等待if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {// 打印触发中断的 GPIO 编号及其当前电平值printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num));// gpio_set_level( GPIO_NUM_9,1)}}
}// 主应用程序入口
void app_main(void)
{// 零初始化配置结构gpio_config_t io_conf = {.intr_type = GPIO_INTR_NEGEDGE, // 设置为下降沿中断.mode = GPIO_MODE_INPUT, // 设置为输入模式.pin_bit_mask = 1ULL << GPIO_NUM_9, // 设置引脚位掩码,指定为 GPIO_NUM_9.pull_down_en = 0, // 禁用下拉模式.pull_up_en = 1 // 启用上拉模式};// 根据配置设置 GPIOgpio_config(&io_conf);// 创建一个队列(句柄),用于处理 ISR 发送的 GPIO 事件gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));// 创建一个任务xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);//任务的函数、任务的名称、堆栈大小、传递给任务函数的参数、任务的优先级,值越大表示优先级越高、用于接收任务句柄的指针// 安装 GPIO ISR 服务gpio_install_isr_service(0); // 默认值0// 为特定 GPIO 引脚钩住 ISR 处理程序gpio_isr_handler_add(GPIO_NUM_9, gpio_isr_handler, (void*) GPIO_NUM_9);// 中断源 中断函数的名称 中断函数的入口参数(void* arg)
}
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
是用于在 FreeRTOS 中创建新任务的函数调用。具体说明如下:
参数说明:
gpio_task_example
:要执行的任务函数名。"gpio_task_example"
:任务的名称,用于调试和监控。2048
:为任务分配的堆栈大小(以字节为单位),这里为 2048 字节。NULL
:任务的参数,这里设置为NULL
,表示没有传递参数。10
:任务的优先级,值越大优先级越高。这里设置为 10。NULL
:用于接收任务句柄的指针,这里设置为NULL
,表示不需要句柄。
功能:
- 创建一个名为
gpio_task_example
的任务,该任务将运行gpio_task_example
函数。 - 这个任务将负责从 GPIO 中断队列中接收事件,并处理这些事件。
如果你有更多问题或需要进一步的解释,请告诉我!
4.实验效果
5.参考资料
- [1] 立创·实战派ESP32-C3开发板 立创开发板技术文档中心
- [2] 【B站】立创·实战派ESP32-C3【手把手带你拥有项目经验】教程-04-gpio_key按键
相关文章:

ESP32-C3 入门笔记04:gpio_key 按键 (ESP-IDF + VSCode)
1.GPIO简介 ESP32-C3是QFN32封装,GPIO引脚一共有22个,从GPIO0到GPIO21。 理论上,所有的IO都可以复用为任何外设功能,但有些引脚用作连接芯片内部FLASH或者外部FLASH功能时,官方不建议用作其它用途。 通过开发板的原…...

C语言(函数)—函数栈帧的创建和销毁
目录 前言 补充知识 一、函数线帧是什么? 二、函数线帧的实现(举例说明) 两数之和代码 编辑两数之和 汇编代码分析 执行第一条语句 执行第二条语句 执行第三条语句 执行第四、五、六条语句 执行第七条语句 执行第八、九、十条语句 执行第十…...

点餐小程序实战教程20广告管理
目录 1 创建数据源2 添加轮播容器3 创建变量4 绑定变量5 预览应用总结 一般餐厅需要有一些宣传,在我们的点餐页面可以在顶部加载广告位。广告主要是用轮播图的形式进行展示,本节我们介绍一下如果显示广告。 1 创建数据源 打开控制台,点击应用…...

市场上几个跨平台开发框架?
跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上,开发者需要为每个操作系统编写不同的代码,使用不同的开发工具和语言。而跨平台桌面应用开发框架通过…...

同步和异步、引用、变量声明、全局变量
同步和异步 如果计算机足够快,任何资源的访问速度都像Cache一样,没有异步的必要。 编程语言的同步和异步 越早期的编程语言,支持语言级别的异步越欠缺。 JS提供某些操作的同步和异步函数,例如文件读取,fs.readFile和fs…...

2024年10月份实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】
首先,来看下效果图 在线体验地址:https://geojson.hxkj.vip,并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据࿰…...

@RequestMapping对不同参数的接收方式
1、简单参数 1、参数名与形参变量名相同,定义形参即可接收参数,且会自动进行类型转换。 RequestMapping("/simple")public String simpleParam(String name,int age){String username name;int userAge age;System.out.println(username&…...

机器学习_KNN(K近邻)算法_FaceBook_Location案例(附数据集下载链接)
Facebook_location_KNN 流程分析: 1.数据集获取(大型数据怎么获取? 放在电脑哪里? 算力怎么搞?) 2.基本数据处理(数据选取-确定特征值和目标值-分割数据集) 缩小数据范围 选择时间特征 去掉签到较少的地方 确定特征值和目标值 分割数据集 3.特征工程(特征预处理:标…...

【str_replace替换导致的绕过】
双写绕过 随便输入一个 usernameadmin&passwords 没有回显测试注入点 usernameadmin or 11%23&passwords 回显hello admin测试列数 usernameadmin order by 3%23&passwords测试回显位 usernameadmi union select 1,2,3%23&passwords 没有显示数据,推…...

如何用AI大模型提升挖洞速度
工具背景 越权漏洞在黑盒测试、SRC挖掘中几乎是必测的一项,但手工逐个测试越权漏洞往往会耗费大量时间,而自动化工具又存在大量误报, 基于此产生了AutorizePro, 那它是怎么提升效率一起来看看 AutorizePro 是一款专注于越权检测的 Burp 插件…...

两个数列问题
# 问题描述 给定长度分别为 n 和 m 的两个数列a[n]、b[m],和一个整数k。求|(a[i] - b[j])^2 - k^2|的最小值。 ## 输入格式 第一行有 2 个整数 n、m、k,分别表示数列 a、b 的长度,以及公式中的整数 k。 第二行有 n 个整数,表示…...

python中堆的用法
Python 堆(Headp) Python中堆是一种基于二叉树存储的数据结构。 主要应用场景: 对一个序列数据的操作基于排序的操作场景,例如序列数据基于最大值最小值进行的操作。 堆的数据结构: Python 中堆是一颗平衡二叉树&am…...

轮班管理新策略,提高效率与降低员工抱怨
良好轮班管理对企业关键,需提前计划、明确期望、保持灵活公平、加强沟通并利用轮班调度系统。ZohoPeople作为智能排班系统,提供轻松创建班次、自动更换、分配管理员、设置津贴及即时通知等功能,助力企业高效管理。 一、HR轮班管理的5大技巧 …...

spring-cloud-alibaba-nacos-config2023.0.1.*启动打印配置文件内容
**背景:**在开发测试过程中如果可以打印出配置文件的内容,方便确认配置是否准确;那么如何才可以打印出来呢; spring-cloud-alibaba-nacos-config 调整日志级别 logging:level:com.alibaba.cloud.nacos.configdata.NacosConfigD…...

数据结构:二叉树、堆
目录 一.树的概念 二、二叉树 1.二叉树的概念 2.特殊类型的二叉树 3.二叉树的性质 4.二叉树存储的结构 三、堆 1.堆的概念 2.堆的实现 Heap.h Heap.c 一.树的概念 注意,树的同一层中不能有关联,否侧就不是树了,就变成图了ÿ…...

hi3798mv100 linux 移植
# Linux开发环境搭建 ## uboot编译 1. 必须先安装gcc,要不然make 等命令无法使用 2. 配置arm 交叉编译链 # gcc sudo apt-get install gcc-9 gcc -v# 安装 Linaro gcc-arm-linux-gnueabihf,注意不是arm-linux-gnueabihf-gcc sudo apt-get install ar…...

Docker-Harbor概述及构建
文章目录 一、Docker Harbor概述1.Harbor的特性2.Harbor的构成 二、搭建本地私有仓库三、部署 Docker-Harbor 服务四、在其他客户端上传镜像五、维护管理Harbor 一、Docker Harbor概述 Harbor 是 VMware 公司开源的企业级 Docker Registry 项目,其目标是帮助用户迅…...

部署项目最新教程
3.3安装mysql 运行代码: yum install mysql 运行代码: yum install mysql-server 中间还是一样要输入y然后回车 运行代码: yum install mysql-devel 好,经过上面三步,mysql安装成功,现在启动mysql…...

linux证明变量扩展在路径名扩展之前执行
题目:怎么设计一组命令来证明变量扩展在路径名扩展之前执行。 为了证明变量扩展在路径名扩展之前执行,可以通过编写一个简单的 shell 脚本来观察这两个过程的顺序。我们可以使用以下步骤进行设计: 步骤 1:准备环境 在你选择的 …...

CentOS 7.9安装MySQL
下载Linux版MySQL安装包 下载地址https://downloads.mysql.com/archives/community/ 下载解压后 安装,按照从上至下顺序,一条一条执行即可安装完毕。 进入到rpm所在目录rpm -ivh mysql-community-common-8.0.26-1.el7.x86_64.rpm rpm -ivh mysql-comm…...

MacOS虚拟机安装Windows停滞在“让我们为你连接到网络”,如何解决?
1. 问题描述 MacOS在虚拟机安装win11过程中,停止在“让我们为你连接到网络”步骤,页面没有任何可以点击的按钮,进行下一步操作。 2. 解决方案(亲测有效) 到达该界面,按下ShiftF10(Windows&…...

黑马程序员Java笔记整理(day03)
1.switch 2.for与while对比 3.嵌套定义,输出的区别性 4.break与continue 5.随机数生成的两种方式 6.Random 7.随机验证码...

centos7更换阿里云镜像源操作步骤及命令
centos7更换阿里云镜像源 在CentOS 7上更换为阿里云的镜像源可以通过以下步骤进行: 备份当前的YUM源配置文件 sudo cp -a /etc/yum.repos.d /etc/yum.repos.d.backup清理原有的YUM源配置文件 sudo rm -f /etc/yum.repos.d/*.repo下载阿里云的CentOS 7源配置文件 …...

冲刺大厂 | 一个线程调用两次start()方法会出现什么现象?
大家好,我是冰河~~ 今天给大家分享的面试题是:一个线程调用两次start()方法会出现什么现象?这道面试题是一道关于多线程的基础面试题,很多小伙伴对这个面试题不太了解,其实,如果你看过JDK中关于Thread类的…...

leaflet(一)初始化地图
Leaflet 与天地图结合使用,可以通过天地图提供的 API 获取地图瓦片,并在 Leaflet 地图上显示。 1. 安装依赖 首先,确保你已经安装了 Leaflet 和 Vue: npm install leaflet npm install vue-leaflet npm install leaflet.tilela…...

Unity开发Hololens项目
Unity打包Hololens设备 目录Visual Studio2019 / Visual Studio2022 远端部署设置Visual Studio2019 / Visual Studio2022 USB部署设置Hololens设备如何查找自身IPHololens设备门户Unity工程内的打包设置 目录 记录下自己做MR相关:Unity和HoloLens设备的历程。 Vi…...

立志最细,FreeRtos的中断管理(Interrupt Management)函数,详解!!!
前言:本文参考,韦东山老师开发文档,连接放在最后。 为什么需要中断管理函数? 在FreeRtos操作系统中,需要实时响应性,也就是随时随地必须保证正常多任务的运行,如果有中断发生,因为中…...

作业2-线性回归的Matlab代码实现
一、前言 相关配置:Matlab 2020a(版本的影响应该不大,.m代码基本都能运行,个人感觉就是Simulink对版本的要求高一些) 二、任务描述 基于近两节课的理论推导,用代码实现线性回归,并对预测结果进…...

用jQuery在canvas上绘制绝对定位的元素
在Web开发中,我们经常需要在canvas上精确定位和绘制元素。虽然canvas本身不支持DOM元素的定位,但我们可以借助jQuery来实现这一功能。本文将介绍如何使用jQuery在canvas上实现元素的绝对定位。 1. 基本思路 我们的基本思路是: 创建一个包含canvas的容器div将需要定位的元素放…...

Android中 tools:text 和 android:text区别
首先引入命名空间 <androidx.constraintlayout.widget.ConstraintLayoutxmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"/androidx.constraintlayout.widget.ConstraintLayout> tools:te…...