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

news2024/11/16 21:50:56

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
}

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

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

相关文章

MyBatis——Plus

MyBatis——Plus怎么知道他是访问哪张表

48 旋转图像

解题思路&#xff1a; \qquad 这道题同样需要用模拟解决&#xff0c;原地算法要求空间复杂度尽量小&#xff0c;最好为 O ( 1 ) O(1) O(1)。模拟的关键是找到旋转的内在规律&#xff0c;即旋转前后的位置坐标的变化规律。 \qquad 正方形矩阵类似洋葱&#xff0c;可以由不同大小…

计算机毕业设计 在线问诊系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

又一条地铁无人线开通!霞智科技智能清洁机器人正式“上岗”

2024年9月26日12时&#xff0c;又一条无人线开通运营&#xff0c;这是陕西省首条全自动无人驾驶地铁线路。该线路作为北跨战略的先行工程&#xff0c;是连接主城区与渭北地区的轨道交通快线&#xff0c;对优化城市总体空间布局、推动区域融合发展、促进沿线产业升级具有十分重要…

电脑上数据丢了怎么找回来 Win系统误删文件如何恢复

无论是在工作中&#xff0c;还是生活中&#xff0c;电脑都是不可缺少的重要工具&#xff0c;尤其是在工作中&#xff0c;电脑不仅可以高效的完成工作&#xff0c;还可以存储工作中的重要资料。不过在使用电脑的时候&#xff0c;也会遇到数据丢失的情况。针对这一问题&#xff0…

渗透测试--文件上传常用绕过方式

文件上传常用绕过方式 1.前端代码&#xff0c;限制只允许上传图片。修改png为php即可绕过前端校验。 2.后端校验Content-Type 校验文件格式 前端修改&#xff0c;抓取上传数据包&#xff0c;并且修改 Content-Type 3.服务端检测&#xff08;目录路径检测&#xff09; 对目…

在Java中使用GeoTools解析POI数据并存储到PostGIS实战

目录 前言 一、POI数据相关介绍 1、原始数据说明 2、空间数据库表设计 二、POI数据存储的设计与实现 1、对应的数据模型对象的设计 2、属性表数据和空间信息的读取 3、实际运行结果 三、总结 前言 POI点&#xff0c;全称为Point of Interest&#xff08;兴趣点&#xf…

大数据技术:Hadoop、Spark与Flink的框架演进

大数据技术&#xff0c;特别是Hadoop、Spark与Flink的框架演进&#xff0c;是过去二十年中信息技术领域最引人注目的发展之一。这些技术不仅改变了数据处理的方式&#xff0c;而且还推动了对数据驱动决策和智能化的需求。在大数据处理领域&#xff0c;选择合适的大数据平台是确…

git 清除二进制文件的 changes 状态

问题&#xff1a;某个分支上修改了二进制文件&#xff0c;导致 changes 一直存在&#xff0c;切换到主分支也仍然存在&#xff0c;点击 Discard 也没用 使用 git reset --hard 还原到初始状态&#xff0c;也不行&#xff0c;不过输出结果会给出错误信息 Encountered 7 file(s) …

raise Exception(“IPAdapter model not found.“)

IPAdapter模型文件太多了&#xff0c;而节点IPAdapter Unified Loader是通过函数&#xff08;get_ipadapter_file与get_clipvision_file&#xff09;预设来加载模型文件&#xff0c;当发生错误“IPAdapter model not found.“时并不指明模型文件名&#xff0c;导致想要有针对性…

C语言 | Leetcode C语言题解之第438题找到字符串中所有字母异位词

题目&#xff1a; 题解&#xff1a; /*** Note: The returned array must be malloced, assume caller calls free().*/ /* *int strCmpn&#xff1a;比较滑动窗口和字符串的相同值 char * s&#xff1a;字符串s&#xff0c;滑动窗口的位置 char * p&#xff1a;字符串p&#…

【Python】Flask-Admin:构建强大、灵活的后台管理界面

在 Web 应用开发中&#xff0c;构建一个直观且功能丰富的后台管理系统对于处理数据和维护应用至关重要。虽然构建一个完全自定义的管理后台界面非常耗时&#xff0c;但 Flask-Admin 提供了一个简洁、灵活的解决方案&#xff0c;可以让开发者快速集成一个功能齐全的后台管理系统…

【移植】轻量系统STM32F407芯片移植案例

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 介绍基于 STM32F407IGT6 芯片在拓维信息 Niobe407 开发板上移植 Op…

Linux操作系统中MongoDB

1、什么是MongoDB 1、非关系型数据库 NoSQL&#xff0c;泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c;传统的关系数据库在处理web2.0网站&#xff0c;特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心&#xff0c;出现了很多难以克服的问…

改变安全策略的五大实践

随着网络威胁形势的加剧&#xff0c;网络安全计划必须不断发展以保护组织的使命。 为了管理这种持续的网络安全发展&#xff0c;应遵循五项关键的安全计划变更管理实践&#xff1a; 1. 识别并吸引受安全风险影响的业务利益相关者 随着新的网络安全风险被发现&#xff0c;受影…

HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13

HEITRONICS TC13红外辐射高温计CT13 INFRARED RADIATION PYROMETER CT13

山海优选电商平台卷轴模式订单系统核心架构解析

山海优选卷轴模式的订单核心源码是涉及订单处理、支付、搜索、状态管理等关键功能的代码部分。由于直接提供完整的源代码可能涉及版权和隐私保护问题&#xff0c;我将基于参考文章中的信息&#xff0c;概述该模式订单核心源码的主要结构和功能点。 一、订单核心源码概述 在山海…

IDEA2020运行项目时不从配置的maven仓库找jar包,从C盘默认路径下找jar包

目录 问题描述&#xff1a; 解决方案&#xff1a; 问题描述&#xff1a; 使用IDEA2020做java开发&#xff0c;idea的设置中maven仓库地址配在D盘&#xff0c; maven的配置文件setting.xml中的仓库也已经确认配置到D盘&#xff0c; 项目根据pom文件自动下载jar包时也会下载到…

【Python快速学习笔记01】下载解释器/环境变量配置/PyCharm下载/第一个代码

目录 1.下载python解释器 2.第一个python程序 3.配置解释器环境变量 4.下载开发工具 PyCharm 4.通过PyCharm编写第一个python程序 1.下载python解释器 官网下载&#xff0c;但是下载太慢了&#xff0c;所以直接百度搜了下载了个 Welcome to Python.org 1.官网下载 2.直…

深度伪造语音检测(Deepfake Speech Detection, DSD)全面概述

近期&#xff0c;深度学习技术和神经网络在生成型人工智能领域已取得重大突破。如今&#xff0c;关键的通信媒介&#xff0c;如音频、图像、视频和文本&#xff0c;均能实现自动生成&#xff0c;并广泛应用于诸多领域&#xff0c;包括聊天机器人系统&#xff08;如ChatGPT&…