【RA4M2系列开发板GPIO体验2按键控制LED】
【RA4M2系列开发板GPIO体验2按键控制LED】
- 1. 前言
- 2. 配置工程
- 2.1 新建FSP项目
- 2.2 硬件连接以及FSP配置
- 2.2.1 硬件连接
- 2.2.2 FSP配置
- 3. 软件实现
- 3.1 实现的功能
- 3.2 FreeRTOS使用
- 3.2.1 Stack分配函数
- 3.2.2 LED任务
- 3.2.3 Key任务
- 3.3 程序设计
- 3.3.1 设置输出hex文件
- 3.3.2 编译
- 3.3.3 下载hex文件
- 4. 效果展示
- 5. 总结
1. 前言
终于准备开发瑞萨的板子了,开始按照教程一步一步的搭建环境,还是非常不容易的。
本次开发使用的是瑞萨官方的编译器RASC+Keil。

本文实现的功能:
- 从头创建一个新工程;
- 配置LED以及按键端口;
- 使用Renesas Flash Programmer下载程序;
- 实现流水灯以及按键SW1按下停止流水灯,按键SW2按下开启流水灯的功能。
2. 配置工程
打开RASC,可直接跳过登录账号,也可登录在瑞萨官网注册的账号即可,然后按照下面的步骤新建工程即可。
2.1 新建FSP项目
输入项目名称LED_switch

选择目标单片机
所使用的单片机为R7FA4M2AD3DFP,如果有调试器,可以选择相应的调试器,否则可以选择None,当然后期可以修改。


选择工程类型
这里直接选择Flat Project就行,如果需要体验TrustZone,,可根据实际情况选择。

选择编译方式
这里选择第一个即可。

选择是否使用FreeRTOS
我这里选择了使用,方便后期开发,但是只能选择使用静态分配的任务。
然后点击完成。

到这里工程就算新建完成,但是什么都没有,需要我们通过FSP添加想要的组件,完成功能开发。
2.2 硬件连接以及FSP配置
2.2.1 硬件连接
我们需要用到LED以及按键,先查看原理图。
LED原理图如下,由此可知,P405,P404,P002分别控制LED1,LED2,LED3,并且当控制引脚为HIGH的时候LED亮。

按键原理图如下,由此可知,P005连接到了SW01,P006连接到了SW2,且当引脚为LOW时表示按键按下。

2.2.2 FSP配置
知道了硬件连接,接下来就是使用FSP配置响应的硬件功能了。

配置按键P005,P006为输入模式。
选择FSP Configuration下面的Pins,配置引脚P405,P404,P002,配置为输出低[Output mode(Initial Low)]。


点击Generate Project Content生成配置代码。

选择Summary,进入项目文件夹

3. 软件实现
3.1 实现的功能
- 系统上电,LED1,LED2,LED3按照亮灭,亮灭,亮灭的状态流水灯显示,流水灯切换周期为500ms;
- 按下按键SW1,流水灯停止;
- 按下按键SW2,流水灯继续;
3.2 FreeRTOS使用
创建工程的时候选择了使用FreeRTOS,RASC会默认配置一个最小配置项的freeRTOS环境,只支持基本的功能,很多扩展功能都不支持,只支持静态创建任务,我还没找到在哪里可以配置,因为直接修改配置文件不行,RASC再次生成的时候会覆盖。
虽然freeRTOS只支持静态配置以及一些基础功能,但是也够我们使用了,下面开始实现我的逻辑。
3.2.1 Stack分配函数
实现Idle任务的Stack分配函数,因为是静态分配栈,所以该部分功能需要我们自己实现,FreeRTOS提供了接口。
/* Implement the Idle task memory static alocation */
void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize)
{*ppxIdleTaskTCBBuffer = &xIdleTaskTcb;*ppxIdleTaskStackBuffer = xIdleTaskStack;*pulIdleTaskStackSize = 1024;
}
实现Timer任务的Stack分配函数
因为是静态分配栈,所以该部分功能需要我们自己实现,FreeRTOS提供了接口。
/* Implement the Timer task memory static alocation */
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,StackType_t **ppxTimerTaskStackBuffer,uint32_t *pulTimerTaskStackSize)
{*ppxTimerTaskTCBBuffer = &xTimerTaskTcb;*ppxTimerTaskStackBuffer = xTiemrTaskStack;*pulTimerTaskStackSize = 2048;
}
3.2.2 LED任务
LED任务实现流水灯功能,每200ms切换一次。
任务创建:
/* Create static task */Task_Led_Handle = xTaskCreateStatic(Task_LedRunning,"Led", /* Task name */1024, /* Stack */NULL, /* Task parameter */4, /* Priority */xTaskLedStack,&xTaskLedTcb); /* Task handler */
LED任务实现:
static void Task_LedRunning(void *pvParameters)
{(void)pvParameters;for (;;){R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);/* Delay for 200ms */vTaskDelay(pdMS_TO_TICKS(200));R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_HIGH);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);/* Delay for 200ms */vTaskDelay(pdMS_TO_TICKS(200));R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH);/* Delay for 200ms */vTaskDelay(pdMS_TO_TICKS(200));}
}
3.2.3 Key任务
按键实现了对按键SW1与SW2的采集,滤波等功能,任务周期为10ms,滤波时间为40ms。
当SW1按下,暂停LED任务;
当SW2按下,恢复LED任务。
任务创建:
Task_Key_Handle = xTaskCreateStatic(Task_KeyRunning,"Key", /* Task name */1024, /* Stack */NULL, /* Task parameter */3, /* Priority */xTaskKeyStack,&xTaskKeyTcb); /* Task handler */
任务实现:
static void Task_KeyRunning(void *pvParameters)
{(void)pvParameters;bsp_io_level_t key_Status[2] = {BSP_IO_LEVEL_HIGH, BSP_IO_LEVEL_HIGH};uint16_t key_press_cnt[2] = {0U, 0U};for (;;){if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &key_Status[0])){if (key_Status[0] == BSP_IO_LEVEL_LOW){/* Filter */if (key_press_cnt[0] >= 0U){/* Key SW0 press confirm *//* Suspend led task */vTaskSuspend(Task_Led_Handle);}else{key_press_cnt[0] ++;}}else{key_press_cnt[0] = 0U;}}if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, &key_Status[1])){if (key_Status[1] == BSP_IO_LEVEL_LOW){/* Filter */if (key_press_cnt[1] >= 4U){/* Key SW1 press confirm *//* Resume led task */vTaskResume(Task_Led_Handle);}else{key_press_cnt[1] ++;}}else{key_press_cnt[1] = 0U;}}vTaskDelay(pdMS_TO_TICKS(10)); }
}
3.3 程序设计
hal_entry.c完整代码
#include "hal_data.h"
#include "FreeRTOS.h"
#include "task.h"FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER/* Stack for Idle task */
static StackType_t xIdleTaskStack[512];
static StaticTask_t xIdleTaskTcb;
/* Stack for Timer task */
static StackType_t xTiemrTaskStack[512];
static StaticTask_t xTimerTaskTcb;/* Staack for LED task */
static StackType_t xTaskLedStack[1024];
static StaticTask_t xTaskLedTcb;
static TaskHandle_t Task_Led_Handle = NULL;/* Staack for LED task */
static StackType_t xTaskKeyStack[1024];
static StaticTask_t xTaskKeyTcb;
static TaskHandle_t Task_Key_Handle = NULL;extern void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize);
extern void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,StackType_t **ppxTimerTaskStackBuffer,uint32_t *pulTimerTaskStackSize);static void Task_LedRunning(void *pvParameters);
static void Task_KeyRunning(void *pvParameters);static void Task_LedRunning(void *pvParameters)
{(void)pvParameters;for (;;){R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_02, BSP_IO_LEVEL_LOW);/* Delay for 200ms */vTaskDelay(pdMS_TO_TICKS(200));R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_HIGH);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_02, BSP_IO_LEVEL_LOW);/* Delay for 200ms */vTaskDelay(pdMS_TO_TICKS(200));R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_05, BSP_IO_LEVEL_LOW);R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_02, BSP_IO_LEVEL_HIGH);/* Delay for 200ms */vTaskDelay(pdMS_TO_TICKS(200));}
}static void Task_KeyRunning(void *pvParameters)
{(void)pvParameters;bsp_io_level_t key_Status[2] = {BSP_IO_LEVEL_HIGH, BSP_IO_LEVEL_HIGH};uint16_t key_press_cnt[2] = {0U, 0U};for (;;){if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &key_Status[0])){if (key_Status[0] == BSP_IO_LEVEL_LOW){/* Filter */if (key_press_cnt[0] >= 0U){/* Key SW0 press confirm *//* Suspend led task */vTaskSuspend(Task_Led_Handle);}else{key_press_cnt[0] ++;}}else{key_press_cnt[0] = 0U;}}if (FSP_SUCCESS == R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, &key_Status[1])){if (key_Status[1] == BSP_IO_LEVEL_LOW){/* Filter */if (key_press_cnt[1] >= 4U){/* Key SW1 press confirm *//* Resume led task */vTaskResume(Task_Led_Handle);}else{key_press_cnt[1] ++;}}else{key_press_cnt[1] = 0U;}}vTaskDelay(pdMS_TO_TICKS(10)); }
}/* Implement the Idle task memory static alocation */
void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,StackType_t ** ppxIdleTaskStackBuffer,uint32_t * pulIdleTaskStackSize)
{*ppxIdleTaskTCBBuffer = &xIdleTaskTcb;*ppxIdleTaskStackBuffer = xIdleTaskStack;*pulIdleTaskStackSize = 1024;
}/* Implement the Timer task memory static alocation */
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,StackType_t **ppxTimerTaskStackBuffer,uint32_t *pulTimerTaskStackSize)
{*ppxTimerTaskTCBBuffer = &xTimerTaskTcb;*ppxTimerTaskStackBuffer = xTiemrTaskStack;*pulTimerTaskStackSize = 2048;
}/*******************************************************************************************************************//*** main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function* is called by main() when no RTOS is used.**********************************************************************************************************************/
void hal_entry(void)
{/* Create static task */Task_Led_Handle = xTaskCreateStatic(Task_LedRunning,"Led", /* Task name */1024, /* Stack */NULL, /* Task parameter */4, /* Priority */xTaskLedStack,&xTaskLedTcb); /* Task handler */Task_Key_Handle = xTaskCreateStatic(Task_KeyRunning,"Key", /* Task name */1024, /* Stack */NULL, /* Task parameter */3, /* Priority */xTaskKeyStack,&xTaskKeyTcb); /* Task handler */if (NULL != Task_Led_Handle){vTaskStartScheduler();}while (1) {}#if BSP_TZ_SECURE_BUILD/* Enter non-secure code */R_BSP_NonSecureEnter();
#endif
}/*******************************************************************************************************************//*** This function is called at various points during the startup process. This implementation uses the event that is* called right before main() to set up the pins.** @param[in] event Where at in the start up process the code is currently at**********************************************************************************************************************/
void R_BSP_WarmStart(bsp_warm_start_event_t event)
{if (BSP_WARM_START_RESET == event){
#if BSP_FEATURE_FLASH_LP_VERSION != 0/* Enable reading from data flash. */R_FACI_LP->DFLCTL = 1U;/* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and* C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif}if (BSP_WARM_START_POST_C == event){/* C runtime environment and system clocks are setup. *//* Configure pins. */R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);}
}#if BSP_TZ_SECURE_BUILDBSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{}
#endif
3.3.1 设置输出hex文件

3.3.2 编译

3.3.3 下载hex文件
打开Renesas Flash Programmer,点击File->New Project,做如下配置。
主要是配置微控制器类型,工程名字,工程目录以及串口端口。

配置完成之后点击Connect,此时会连接失败,如下图

需要按住Reset按钮,之后点击Connect,在松手。
配置Boot
如果使用串口下载,需要配置一下单片机上面的boot跳线帽,切换为SCI/USB BOOT模式如下:

开发板上也有描述,下载完成之后需要将跳线帽变回Interrnal Flash模式。
下载hex文件到单片机
如下图,选择hex文件,然后按下Reset按钮,电机Start,松开Reset按钮,等待下载完成即可。

4. 效果展示
- 系统上电,LED1,LED2,LED3按照亮灭,亮灭,亮灭的状态流水灯显示,流水灯切换周期为500ms;
- 按下按键SW1,流水灯停止;
- 按下按键SW2,流水灯继续。
5. 总结
🥳🥳🥳通过对这篇文章我们掌握了RA4M2系列开发板GPIO体验2按键控制LED,配置过程大约需要10分钟,这个时候需要耐心等待,多尝试几次就可以,接下来会有许多有趣的实验,进而丰富我们的生活。🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境,🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣
参考文献
【瑞萨RA4系列开发板体验】1. 新建工程+按键控制LED
【瑞萨RA4系列开发板体验】1 RA4M2开发环境搭建
【瑞萨RA4系列开发板体验】2. KEIL环境搭建+STLINK调试+FreeRTOS使用
【 RA4M2开发板环境搭建之串口下载1】
相关文章:
【RA4M2系列开发板GPIO体验2按键控制LED】
【RA4M2系列开发板GPIO体验2按键控制LED】1. 前言2. 配置工程2.1 新建FSP项目2.2 硬件连接以及FSP配置2.2.1 硬件连接2.2.2 FSP配置3. 软件实现3.1 实现的功能3.2 FreeRTOS使用3.2.1 Stack分配函数3.2.2 LED任务3.2.3 Key任务3.3 程序设计3.3.1 设置输出hex文件3.3.2 编译3.3.3…...
初步介绍CUDA中的统一内存
初步介绍CUDA中的统一内存 更多精彩内容: https://www.nvidia.cn/gtc-global/?ncidref-dev-876561 文章目录初步介绍CUDA中的统一内存为此,我向您介绍了统一内存,它可以非常轻松地分配和访问可由系统中任何处理器、CPU 或 GPU 上运行的代码使用的数据。…...
UVM实战--加法器
前言 这里以UVM实战(张强)第二章为基础修改原有的DUT,将DUT修改为加法器,从而修改代码以使得更加深入的了解各个组件的类型和使用。 一. 组件的基本框架 和第二章的平台的主要区别点 (1)有两个transactio…...
Linux系统点亮LED
目录应用层操控硬件的两种方式sysfs 文件系统sysfs 与/sys总结标准接口与非标准接口LED 硬件控制方式编写LED 应用程序在开发板上测试对于一款学习型开发板来说,永远都绕不开LED 这个小小的设备,基本上每块板子都至少会有一颗 LED 小灯,对于我…...
在superset中快速制作报表或仪表盘
在中小型企业,当下需要快速迭代、快速了解运营效果的业务,急需一款开源、好用、能快速迭代生产的报表系统。 老板很关心,BI工程师很关心,同时系统开发人员也同样关心,一个好的技术选型往往能够帮助公司减少很多成本&a…...
【可视化实战】Python 绘制出来的数据大屏真的太惊艳了
今天我们在进行一个Python数据可视化的实战练习,用到的模块叫做Panel,我们通过调用此模块来绘制动态可交互的图表以及数据大屏的制作。 而本地需要用到的数据集,可在kaggle上面获取 https://www.kaggle.com/datasets/rtatman/188-million-us…...
Obsidium一键编码作业,Obsidia惊人属性
Obsidium一键编码作业,Obsidia惊人属性 每个区域都包含几个可定制的功能,允许用户确定如何完全执行应用程序的安全性。Obsidia的功能区允许用户存储任何调整或一键编码作业。 Obsidia惊人属性: 代码虚拟化:代码虚拟化允许您转换程序代码的特定…...
约束优化:约束优化的三种序列无约束优化方法
文章目录约束优化:约束优化的三种序列无约束优化方法外点罚函数法L2-罚函数法:非精确算法对于等式约束对于不等式约束L1-罚函数法:精确算法内点罚函数法:障碍函数法等式约束优化问题的拉格朗日函数法:Uzawas Method fo…...
RocketMQ快速入门:消息发送、延迟消息、消费重试
一起学编程,让生活更随和! 如果你觉得是个同道中人,欢迎关注博主gzh:【随和的皮蛋桑】。 专注于Java基础、进阶、面试以及计算机基础知识分享🐳。偶尔认知思考、日常水文🐌。 目录1、RocketMQ消息结构1.1…...
FANUC机器人通过KAREL程序实现与PLC位置坐标通信的具体方法示例
FANUC机器人通过KAREL程序实现与PLC位置坐标通信的具体方法示例 在通信IO点位数量足够的情况下,可以使用机器人的IO点传输位置数据,这里以传输机器人的实时位置为例进行说明。 基本流程如下图所示: 基本步骤可参考如下: 首先确认机器人控制柜已经安装了总线通信软件(例如…...
[蓝桥杯 2015 省 B] 移动距离
蓝桥杯 2015 年省赛 B 组 H 题题目描述X 星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为 1,2,3,⋯ 。当排满一行时,从下一行相邻的楼往反方向排号。比如:当小区排号宽度为 6 时,开始情形如下:我们的…...
Pandas库入门仅需10分钟
数据处理的时候经常性需要整理出表格,在这里介绍pandas常见使用,目录如下: 数据结构导入导出文件对数据进行操作 – 增加数据(创建数据) – 删除数据 – 改动数据 – 查找数据 – 常用操作(转置࿰…...
python的socket通信中,如何设置可以让两台主机通过外网访问?
要让两台主机通过外网进行Socket通信,需要在网络设置和代码实现两个方面进行相应的配置。下面是具体的步骤: 确认网络环境:首先要确保两台主机都能够通过外网访问。可以通过ping命令或者telnet命令来测试两台主机之间是否可以互相访问。 确定…...
检测数据的方法(回顾)
检测数据类型的4种方法typeofinstanceofconstructor{}.toString.call() 检测数据类型的4种方法 typeof 定义 用来检测数据类型的运算符 返回一个字符串,表示操作值的数据类型(7种) number,string,boolean,object,u…...
比特数据结构与算法(第三章_上)栈的概念和实现(力扣:20. 有效的括号)
一、栈(stack)栈的概念:① 栈是一种特殊的线性表,它只允许在固定的一端进行插入和删除元素的操作。② 进行数据插入的删除和操作的一端,称为栈顶 。另一端则称为 栈底 。③ 栈中的元素遵守后进先出的原则,即…...
JVM13 类的生命周期
1. 概述 在 Java 中数据类型分为基本数据类型和引用数据类型。基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载。 按照 Java 虚拟机规范,从 class 文件到加载到内存中的类,到类卸载出内存为止,它的整个生命周期包…...
Docker网络模式解析
目录 前言 一、常用基本命令 (一)查看网络 (二)创建网络 (三)查看网络源数据 (四)删除网络 二、网络模式 (一)总体介绍 (二)…...
游山城重庆
山城楼梯多,路都是上坡。 为了赶早上8点从成都到重庆的动车,凌晨5点半就爬起床来,由于昨天喝了咖啡,所以我将尽3点才睡觉,这意味着我只睡了2个多小时。起来简单休息之后,和朋友协商好时间就一起出门了。 …...
Vuex的创建和简单使用
Vuex 1.简介 1.1简介 1.框框里面才是Vuex state:状态数据action:处理异步mutations:处理同步,视图可以同步进行渲染1.2项目创建 1.vue create 名称 2.运行后 3.下载vuex。采用的是基于vue2的版本。 npm install vuex3 --save 4.vu…...
Arduino IDE搭建Heltec开发板开发环境
Arduino IDE搭建Heltec开发板开发环境Heltec开发板开发环境下载与搭建Arduino IDE下载与安装搭建Heltec开发板的开发环境添加package URL方法通过Git的方法安装离线安装Heltec开发板开发环境下载与搭建 Arduino IDE下载与安装 Heltec的ESP系列和大部分的LoRa系列开发板都是用A…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
