RP2040 C SDK GPIO和IRQ 唤醒功能使用

RP2040 C SDK GPIO和中断功能使用


SIO介绍

  • 手册27页:
    The Single-cycle IO block (SIO) contains several peripherals that require low-latency, deterministic access from the processors. It is accessed via each processor’s IOPORT: this is an auxiliary bus port on the Cortex-M0+ which can perform rapid 32-bit reads and writes. The SIO has a dedicated bus interface for each processor’s IOPORT, as shown in Figure 7. Processors access their IOPORT with normal load and store instructions, directed to the special IOPORT address segment, 0xd0000000…0xdfffffff. The SIO appears as memory-mapped hardware within the IOPORT space.
    单周期IO块(SIO)包含几个外设,它们需要从处理器中进行低延迟的、确定性的访问。它可以通过每个处理器的IOPORT进行访问:这是Cortex-M0+上的一个辅助总线端口,它可以执行快速的32位读取和写操作。SIO为每个处理器的IOPORT都有一个专用的总线接口,如图7所示。处理器使用正常负载和存储指令访问他们的IOPORT,指向特殊的IOPORT地址段0xd0000000…0xdfffffff。SIO显示为IOPORT空间中的内存映射硬件。
  • NOTE:The SIO is not connected to the main system bus due to its tight timing requirements. It can only be accessed by the processors, or by the debugger via the processor debug ports.由于其严格的定时要求,SIO没有连接到主系统总线。它只能由处理器或调试器通过处理器调试端口进行访问。

在这里插入图片描述

上图.单周期IO块包含记忆映射硬件,处理器必须能够快速访问。FIFOs和自旋锁支持两个核之间的消息传递和同步。共享的GPIO寄存器提供快速和并发的安全的直接访问。一些核心-本地算术硬件可以用来加速处理器上的常见任务。

  • 所有的IOPORT读取和写入(因此所有的SIO访问)都在一个周期内发生,这与主AHB-Lite系统总线不同,其中Cortex-M0+需要两个周期来加载或存储,并且由于来自其他系统总线主服务器的争用,可能需要等待更长的时间。这对于像GPIO这样的接口至关重要,它们有严格的时间要求。
  • SIO寄存器被映射到0xd0000000…0xd000017c范围内的单词对齐地址。IOPORT空间的其余部分被保留以供将来使用。
  • 下面的节将详细描述SIO外围设备。
GPIO控制

处理器可以访问GPIO寄存器,以快速和直接地控制具有GPIO功能的引脚。有两组完全相同的寄存器:

  • • GPIO_x for direct control of IO bank 0 (user GPIOs 0 to 29, starting at the LSB)用于直接控制IO组0(用户GPIO0到29,从LSB开始)
  • • GPIO_HI_x for direct control of the QSPI IO bank (in the order SCLK, SSn, SD0, SD1, SD2, SD3, starting at the LSB)GPIO_HI_x,用于直接控制QSPI IO库(按SCLK、SSn、SD0、SD1、SD2、SD3,从LSB开始
  • NOTE:To drive a pin with the SIO’s GPIO registers, the GPIO multiplexer for this pin must first be configured to select the SIO GPIO function.要使用SIO的GPIO寄存器驱动引脚,必须首先将此引脚的GPIO复用器配置为选择SIO GPIO功能。
  • 这些GPIO寄存器在两个核之间共享,并且两个核可以同时访问它们。每个BANK有三个寄存器:
    • Output registers, GPIO_OUT and GPIO_HI_OUT, are used to set the output level of the GPIO (1/0 for high/low)
    • Output enable registers, GPIO_OE and GPIO_HI_OE, are used to enable the output driver. 0 for high-impedance, 1
    for drive high/low based on GPIO_OUT and GPIO_HI_OUT.
    • Input registers, GPIO_IN and GPIO_HI_IN, allow the processor to sample the current state of the GPIOs

📑RP2040 中断功能简介

Each core is equipped with a standard ARM Nested Vectored Interrupt Controller (NVIC) which has 32 interrupt inputs.
Each NVIC has the same interrupts routed to it, with the exception of the GPIO interrupts: there is one GPIO interrupt per bank, per core. These are completely independent, so e.g. core 0 can be interrupted by GPIO 0 in bank 0, and core 1 by GPIO 1 in the same bank.RP2040
由于是双核,每个核心都配备了一个标准的ARM嵌套的向量中断控制器(NVIC),它有32个中断输入。每个NVIC都有相同的中断路由到它,除了GPIO中断:每个库,每个核心都有一个GPIO中断。这些都是完全独立的,例如,核心0可以被bank0中的GPIO 0中断,而核心1可以被同一银行中的GPIO 1中断。
On RP2040, only the lower 26 IRQ signals are connected on the NVIC, and IRQs 26 to 31 are tied to zero (never firing).
The core can still be forced to enter the relevant interrupt handler by writing bits 26 to 31 in the NVIC ISPR register.

  • 中断号:
    在这里插入图片描述

📗GPIO功能

Pads

Each GPIO is connected to the off-chip world via a “pad”. Pads are the electrical interface between the chip’s internal
logic and external circuitry. They translate signal voltage levels, support higher currents and offer some protection
against electrostatic discharge (ESD) events. Pad electrical behaviour can be adjusted to meet the requirements of the
external circuitry. The following adjustments are available:
• Output drive strength can be set to 2mA, 4mA, 8mA or 12mA
• Output slew rate can be set to slow or fast
• Input hysteresis (schmitt trigger mode) can be enabled
• A pull-up or pull-down can be enabled, to set the output signal level when the output driver is disabled
• The input buffer can be disabled, to reduce current consumption when the pad is unused, unconnected or
connected to an analogue signal.
在这里插入图片描述

  • 📜 GPIO引脚功能配置,枚举类型:
enum gpio_function {
    GPIO_FUNC_XIP = 0,
    GPIO_FUNC_SPI = 1,
    GPIO_FUNC_UART = 2,
    GPIO_FUNC_I2C = 3,
    GPIO_FUNC_PWM = 4,
    GPIO_FUNC_SIO = 5,
    GPIO_FUNC_PIO0 = 6,
    GPIO_FUNC_PIO1 = 7,
    GPIO_FUNC_GPCK = 8,
    GPIO_FUNC_USB = 9,
    GPIO_FUNC_NULL = 0x1f,
};

作为外部中断使用,gpio引脚功能配置GPIO_FUNC_SIO

  • 🌿gpio功能配置

void gpio_set_function(	uint 	gpio,enum gpio_function 	fn )	
  • 🌿gpio输入输出方式,可以配置为输入模式和输出模式。
static inline void gpio_set_dir(uint gpio, bool out)
  • 🌿gpio状态,可以配置为上拉、下拉,上下拉都使能。
void gpio_set_pulls(uint gpio, bool up, bool down);
  • 🌿gpio输出模式下,可以配置速度:慢和快。电平变化的斜率(压摆率)

void gpio_set_slew_rate	(	uint 	gpio,enum gpio_slew_rate 	slew )	
enum gpio_slew_rate {
    GPIO_SLEW_RATE_SLOW = 0,  ///< Slew rate limiting enabled
    GPIO_SLEW_RATE_FAST = 1   ///< Slew rate limiting disabled
};
  • 🌿gpio对外驱动能力,可配置驱动电流大小:
void gpio_set_drive_strength(uint gpio, enum gpio_drive_strength drive) 
/*! \brief Drive strength levels for GPIO outputs
 *  \ingroup hardware_gpio
 *
 * Drive strength levels for GPIO outputs.
 * \sa gpio_set_drive_strength
 */
enum gpio_drive_strength {
    GPIO_DRIVE_STRENGTH_2MA = 0, ///< 2 mA nominal drive strength
    GPIO_DRIVE_STRENGTH_4MA = 1, ///< 4 mA nominal drive strength
    GPIO_DRIVE_STRENGTH_8MA = 2, ///< 8 mA nominal drive strength
    GPIO_DRIVE_STRENGTH_12MA = 3 ///< 12 mA nominal drive strength
};
blink点灯程序
#include "pico/stdlib.h"

int main() {
#ifndef PICO_DEFAULT_LED_PIN
#warning blink example requires a board with a regular LED
#else
    const uint LED_PIN = PICO_DEFAULT_LED_PIN;
    gpio_init(LED_PIN);//
    gpio_set_dir(LED_PIN, GPIO_OUT);
    while (true) {
        gpio_put(LED_PIN, 1);
        sleep_ms(250);
        gpio_put(LED_PIN, 0);
        sleep_ms(250);
    }
#endif
}
  • 🌿gpio初始化:void gpio_init(uint gpio)
void gpio_init(uint gpio) {
    gpio_set_dir(gpio, GPIO_IN);//输入模式
    gpio_put(gpio, 0);//设置为低电平
    gpio_set_function(gpio, GPIO_FUNC_SIO);//SIO模式
}
  • 多个gpio初始化操作:void gpio_init_mask(uint gpio_mask)
  • gpio位操作函数:
static inline void gpio_put(uint gpio, bool value);
  • 多个gpio位操作 static inline void gpio_put_masked(uint32_t mask, uint32_t value)
gpio_set_mask(1ul << gpio);//置位
sio_hw->gpio_set = 1ul << gpio;//原子操作

gpio_clr_mask(1ul << gpio);//清零
sio_hw->gpio_clr = 1ul << gpio;//原子操作
gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
sio_hw->gpio_togl = 1ul << gpio;//状态翻转

从上面的函数可以看出,SDK给出了不同封装层的gpio操作方式。

📘GPIO 中断

GPIO中断函数介绍
  • void gpio_set_irq_enabled_with_callback(uint gpio, uint32_t events, bool enabled, gpio_irq_callback_t callback)
  • 第一个形参,引脚号
  • 第二个形参事件可以是设定为下面的一种或多种信号作为触发事件:
enum gpio_irq_level {
    GPIO_IRQ_LEVEL_LOW = 0x1u,
    GPIO_IRQ_LEVEL_HIGH = 0x2u,
    GPIO_IRQ_EDGE_FALL = 0x4u,
    GPIO_IRQ_EDGE_RISE = 0x8u,
};
  • 形参三,是irq使能:irq_set_enabled(IO_IRQ_BANK0, true);
  • 形参四,是要执行的回调函数,✨需要注意:该回调函数可以是默认带2个形参的typedef void (*gpio_irq_callback_t)(uint gpio, uint32_t event_mask);这2个形参是gpio中断发生时,传递过来的返回值,记录了gpio中断发生的引脚和触发响应事件,如果传递过来的形参,用不到的话,自己写也可以不带任何形参作为回调函数填进去。形参不可以是void类型,如果是void类型那么就相当于带了一个形参,无法通过编译语法✨

👉该gpio中断配置函数的好处就是,在发生gpio中断事件后,不需要手动再去清除中断事件标志位。类似的函数还有 gpio_set_irq_callback;另外该gpio中断配置函数的好处就是,会自动使能gpio中断配置函数 irq_set_enabled(IO_IRQ_BANK0, true);(具体看函数方法实现)

  • static inline void gpio_add_raw_irq_handler(uint gpio, irq_handler_t handler) :gpio中断回调,在发生gpio中断事件后,需要手动清除标志事件。
  • 形参一,配置gpio引脚
  • 形参二,回调函数,typedef void (*irq_handler_t)(void);✨需要注意形参是void类型,形参可以是void类型或者无形参。

✨另外需要注意的是,使用该函数,在产生gpio中断事件时,需要手动清gpio中断事件标志位,void gpio_acknowledge_irq(uint gpio, uint32_t events);在配置时,还需要手动使能gpio中断,才能响应gpio中断。手动使能gpio中断: irq_set_enabled(IO_IRQ_BANK0, true);

  • 📝SDK给出的例程:
/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

static char event_str[128];

void gpio_event_string(char *buf, uint32_t events);

void gpio_callback(uint gpio, uint32_t events) {//带2个形参
    // Put the GPIO event(s) that just happened into event_str
    // so we can print it
    gpio_event_string(event_str, events);
    printf("GPIO %d %s\n", gpio, event_str);
}

int main() {
    stdio_init_all();

    printf("Hello GPIO IRQ\n");
    gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &gpio_callback);

    // Wait forever
    while (1);
}


static const char *gpio_irq_str[] = {
        "LEVEL_LOW",  // 0x1
        "LEVEL_HIGH", // 0x2
        "EDGE_FALL",  // 0x4
        "EDGE_RISE"   // 0x8
};

void gpio_event_string(char *buf, uint32_t events) {
    for (uint i = 0; i < 4; i++) {
        uint mask = (1 << i);
        if (events & mask) {
            // Copy this event string into the user string
            const char *event_str = gpio_irq_str[i];
            while (*event_str != '\0') {
                *buf++ = *event_str++;
            }
            events &= ~mask;

            // If more events add ", "
            if (events) {
                *buf++ = ',';
                *buf++ = ' ';
            }
        }
    }
    *buf++ = '\0';
}


🛠需要手动清除gpio中断标志位配置使用方法

    gpio_init(EXT_INT_PIN);
   // gpio_set_dir(EXT_INT_PIN, GPIO_IN);// sio_hw->gpio_oe_set = mask;
    gpio_set_input_enabled(EXT_INT_PIN, true);
     // 单独中断
   gpio_set_irq_enabled(EXT_INT_PIN, GPIO_IRQ_EDGE_RISE, true);
   gpio_add_raw_irq_handler(EXT_INT_PIN, my_irq_handler);  
    irq_set_enabled(IO_IRQ_BANK0, true); // 使能中断控制器
    ......
    
    void my_irq_handler()
{
    if (gpio_get_irq_event_mask(EXT_INT_PIN) & GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL)
    {
        gpio_acknowledge_irq(EXT_INT_PIN, GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL);  //clear irq flag
      //  gpio_xor_mask(1<<LED_PIN); // Toggle the LED
        printf("GPIO %d\n", EXT_INT_PIN);
    
    }

}

📒GPIO中断清标志位自动配置使用

    gpio_set_irq_enabled_with_callback(EXT_INT_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &my_irq_handler); // 复用中断
    gpio_set_irq_enabled_with_callback(EXT_INT_PIN2, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &my_irq_handler);
    //gpio_set_irq_callback(&my_irq_handler);
......

void my_irq_handler()
{
    if (gpio_get_irq_event_mask(EXT_INT_PIN) & GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL)
    {

   //  gpio_xor_mask(1<<LED_PIN); // Toggle the LED
        printf("GPIO %d\n", EXT_INT_PIN);
    //    gpio_clear_irq(EXT_INT_PIN);
    }
    if (gpio_get_irq_event_mask(EXT_INT_PIN2) & GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL)
    {
        //  gpio_xor_mask(1<<LED_PIN); // Toggle the LED
        printf("GPIO %d \n", EXT_INT_PIN2);
    }
}
  • 👉一般情况下推荐使用gpio_set_irq_enabled_with_callback来配置需要的gpio中断,比较省事。在SDK给出的多种API接口函数,需要熟悉各功能函数的使用差异以及注意事项。

📗GPIO 唤醒功能使用

在芯片进入睡眠模式(DORMANT State)下,gpio可以用作唤醒。


/*
 CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_Deep_Sleep_Wake.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_Deep_Sleep_Wake.elf verify reset exit"

*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "hardware/gpio.h"
#include "hardware/xosc.h"
#include "pico/multicore.h"
#include "pico/stdio.h"
#include "pico/time.h"

#define LED_PIN 25
#define EXT_INT_PIN 5

static void measure_freqs(void);

void disable_pll() {
  clock_configure(clk_sys,
    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF,
    0,
    12 * MHZ,
    12 * MHZ);
}

void enable_pll() {
  clock_configure(clk_sys,
    CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
    CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
    125 * MHZ,
    125 * MHZ);
}

int main() {

   // stdio_init_all();
  gpio_init(PICO_DEFAULT_LED_PIN);
  gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
  gpio_put(PICO_DEFAULT_LED_PIN, true);
    gpio_init(EXT_INT_PIN);
    gpio_set_dir(EXT_INT_PIN, GPIO_IN);// sio_hw->gpio_oe_set = mask;
     gpio_set_pulls(EXT_INT_PIN, false, true); // 下拉
    gpio_set_dormant_irq_enabled(EXT_INT_PIN, IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_LEVEL_HIGH_BITS, true);

    disable_pll();
    xosc_dormant(); // WARNING: This stops the xosc until woken up by an irq
//   gpio_acknowledge_irq(EXT_INT_PIN, IO_BANK0_DORMANT_WAKE_INTE0_GPIO0_LEVEL_HIGH_BITS);
    enable_pll();
    stdio_init_all();
  while (true)  {

    measure_freqs();
    gpio_xor_mask(1ul << PICO_DEFAULT_LED_PIN); // Toggle the LED
    sleep_ms(1000);

    // for (uint32_t i=0; i<3; i++) {
    //     gpio_put(PICO_DEFAULT_LED_PIN, false);
    //     sleep_ms(100);
    //     gpio_put(PICO_DEFAULT_LED_PIN, true);
    //     sleep_ms(100);
    // }
  }
}

static void measure_freqs(void)
{
    uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);
    uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);
    uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);
    uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
    uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);
    uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);
    uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);
    uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);

    printf("pll_sys  = %dkHz\n", f_pll_sys);
    printf("pll_usb  = %dkHz\n", f_pll_usb);
    printf("rosc     = %dkHz\n", f_rosc);
    printf("clk_sys  = %dkHz\n", f_clk_sys);
    printf("clk_peri = %dkHz\n", f_clk_peri);
    printf("clk_usb  = %dkHz\n", f_clk_usb);
    printf("clk_adc  = %dkHz\n", f_clk_adc);
    printf("clk_rtc  = %dkHz\n", f_clk_rtc);

    // Can't measure clk_ref / xosc as it is the ref
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PHP基础知识

一、PHP变量&#xff1a; 变量是用于存储信息的"容器" <?php$x5;$y6;$z$x$y;echo $z; ?> 在 PHP 中&#xff0c;这些$字母被称为变量。 PHP 变量 变量可以是很短的名称&#xff08;如 x 和 y&#xff09;或者更具描述性的名称&#xff08;如 age、carname、…

【Java异常】(简简单单拿捏)

【Java异常】&#xff08;简简单单拿捏&#xff09; 1. 异常的简单介绍2. 异常的抛出2.1 语法 3. 异常的处理3.1 异常声明throws3.2 try-catch捕获并处理 4. 例子&#xff08;try-catch自定义异常&#xff09; 1. 异常的简单介绍 程序员在运行代码时会遇到很多异常&#xff0c…

学习threejs,绘制二维线

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言二、&#x1f340;绘制二维线1. ☘️…

基于Hive和Hadoop的保险分析系统

本项目是一个基于大数据技术的保险分析系统&#xff0c;旨在为用户提供全面的汽车保险信息和深入的保险价格分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark…

2016年国赛高教杯数学建模A题系泊系统的设计解题全过程文档及程序

2016年国赛高教杯数学建模 A题 系泊系统的设计 近浅海观测网的传输节点由浮标系统、系泊系统和水声通讯系统组成&#xff08;如图1所示&#xff09;。某型传输节点的浮标系统可简化为底面直径2m、高2m的圆柱体&#xff0c;浮标的质量为1000kg。系泊系统由钢管、钢桶、重物球、…

SpringBoot使用EasyPoi根据模板导出word or pdf

1、导出效果 1.1 wrod 1.2 pdf 2、依赖 <!--word--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.3.0</version></dependency><dependency><groupId>cn.…

探讨TikTok直播专线的必要性

随着社交媒体的迅速发展&#xff0c;短视频平台如TikTok&#xff08;在中国抖音&#xff09;已成为现代人生活中不可或缺的一部分。TikTok的直播功能因其即时性和互动性受到广泛喜爱&#xff0c;但在中国市场上&#xff0c;主播们在使用这一功能时面临不少挑战&#xff0c;其中…

优选拼团平台架构解析与关键代码逻辑概述

一、系统架构设计 唐古拉优选拼团平台采用多层架构设计&#xff0c;主要包括前端展示层、业务逻辑层、数据访问层及数据存储层。 前端展示层&#xff1a;负责用户界面的展示和交互&#xff0c;包括商品列表、拼团详情、订单管理等页面。前端采用现代前端框架&#xff08;如Vue…

【Linux】图解详谈HTTPS的安全传输

文章目录 1.前置知识2.只使用对称加密3.只使用非对称加密 因为私钥加密只能公钥解开&#xff0c;公钥加密只能私钥解开4.双方都是使用非对称加密5.非对称加密 对称加密6.非对称加密对称加密CA认证&#xff08;一&#xff09;CA认证&#xff08;二&#xff09;https &#xff0…

信息学奥赛的最佳启蒙阶段是小学还是初中?

信息学奥赛&#xff08;NOI&#xff09;近年来越来越受家长和学生的关注&#xff0c;尤其是在编程教育不断升温的背景下&#xff0c;信息学竞赛成为了许多家庭的教育选择之一。家长们往往关心的是&#xff1a;孩子应该在什么年龄段开始接触信息学竞赛&#xff0c;才能打下坚实的…

ArcEngine C#二次开发图层处理:根据属性分割图层(Split)

需求&#xff1a;仅根据某一属性&#xff0c;分割图层&#xff0c;并以属性值命名图层名称保存。 众所周知&#xff0c;ArcGIS ArcToolbox中通过Split可以实现图形分割一个图层&#xff0c;以属性值命名图层&#xff0c;如下图所示。 本文仅仅依据属性值&#xff0c;将一个shp…

统信服务器操作系统【qcow2 镜像空间扩容】方案

使用 qcow2 镜像安装系统,当默认安装系统存储空间不够用时,进行自定义扩容 文章目录 准备环境扩容步骤一、检查环境信息1.查看镜像信息2.查看镜像分区信息3.确认需要扩容的分区名二、扩容1.备份镜像2.创建新的镜像文件,并指定空间3.将系统扩容到新的镜像三、扩容 lvm 分区四…

自然语言处理实战项目:从理论到实现

一、引言 自然语言处理&#xff08;NLP&#xff09;是计算机科学、人工智能和语言学交叉的领域&#xff0c;旨在让计算机能够理解、处理和生成人类语言。随着互联网的飞速发展&#xff0c;大量的文本数据被产生&#xff0c;这为自然语言处理技术的发展提供了丰富的素材&#xf…

从响应到预见:前瞻性客户服务策略的实践与探索

在快速变化的商业环境中&#xff0c;客户服务已不再是简单的需求响应与问题解决&#xff0c;它正逐步演变为企业竞争力的核心要素之一。传统的“响应式”服务模式虽能满足基本的客户需求&#xff0c;但在追求极致客户体验和构建长期忠诚度的今天&#xff0c;显然已显不足。因此…

使用 Puppeteer-Cluster 和代理进行高效网络抓取: 完全指南

文章目录 一、介绍&#xff1f;二、什么是 Puppeteer-Cluster&#xff1f;三、为什么代理在网络抓取中很重要&#xff1f;四、 为什么使用带代理的 Puppeteer-Cluster&#xff1f;五、分步指南&#xff1a; 带代理的 Puppeteer 群集5.1. 步骤 1&#xff1a;安装所需程序库5.2. …

ERROR:start workflow error,dolphinscheduler log重复刷屏(死循环)直至磁盘存满

在使用ds过后发现&#xff0c;我虚拟机中的磁盘内存全部沾满了 查看目录下大于100M的文件&#xff1a; find / -size 100M 查看后发现问题在于ds产生的日志文件特别大而且多&#xff0c; 查看日志后发现日志中一直都在死循环错误&#xff1a;start workflow error 等 其中文件…

命令行gcc -v和g++ -v输出版本不一致

命令行gcc -v和g -v输出版本不一致 前言&#xff1a;本文初编辑于2024年9月27日 CSDN主页&#xff1a;https://blog.csdn.net/rvdgdsva 博客园主页&#xff1a;https://www.cnblogs.com/hassle 博客园本文链接&#xff1a;https://www.cnblogs.com/hassle/p/18435916 赞美大…

Java ERP管理系统源码解析:微服务架构实践Spring Cloud Alibaba与Spring Boot

在当今数字化浪潮的推动下&#xff0c;企业对于高效、稳定且易于扩展的管理系统需求日益增长。为了满足这一需求&#xff0c;我们精心打造了一款基于Java技术的鸿鹄ERP&#xff08;Enterprise Resource Planning&#xff09;管理系统。该系统充分利用了Spring Cloud Alibaba、S…

局域网广域网,IP地址和端口号,TCP/IP 4层协议,协议的封装和分用

前言 在古老的年代&#xff0c;如果我们要实现两台机器进行数据传输&#xff0c; A员工就得去B员工的办公电脑传数据&#xff08;B休息&#xff0c;等A传完&#xff09;&#xff0c;这样就很浪费时间 所以能不能不去B的工位的同时&#xff0c;还能传数据。这时候网络通信就出来…

一文彻底掌握inout双向端口

inout端口信号在FPGA中应用还是很广泛的&#xff0c;特别是一些总线通信、数据交互的场景&#xff0c;比如i2c、spi等等。 一、inout的基本概念 Inout 端口的实现基础是三态门。 三态门具有三种输出状态&#xff0c;即高电平、低电平以及高阻态&#xff08;Z&#xff09;。 …