你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始

[复制链接]
dosconio 发布时间:2026-8-21 12:27

本文提出一个面向嵌入式环境的跨平台抽象库(unisym),目标是让同一套驱动与系统代码能够分别运行于多种微控制器与更高性能的片上系统之上,而无需为每种目标重写驱动逻辑。

框架在接口层保持平台无关,平台相关的差异被收束到实现内部,调用方所见是一个稳定、一致的抽象接口;更换目标平台时通常只需做少量调整,业务逻辑本身无需改动。寄存器访问被封装为一层统一的代理机制,保留了对底层资源的直接操作语义,同时借助类型检查与一致的读写方式,降低手工位的直接拼凑可能引入的错误。在接口设计上,本工作不追求对各家 HAL 的逐一对齐,而是倾向于收敛:多阶段、多命名习惯的操作被合并为单一方法配合少量参数的形式,超时、中断与回调等通用关注点采用统一约定,从而在保持表达能力的同时缩小调用面,使 API 意图更易读、更易维护。

在体系结构层面,unisym 并不只覆盖外设驱动,而是将上位的外设驱动与系统级支撑纳入同一抽象模型,包括时钟管理、缓存与存储管理、内存管理,以及终端、图层与字体渲染等图形界面能力。这使得从最底层的一个外设操作,到构建具备图形界面的完整应用,始终处于同一套接口与心智模型之下,避免在不同生态的碎片接口之间反复拼接。

在代码组织上,该框架强调跨平台差异的清晰界定与内聚封装 —— 平台相关的部分被集中管理,平台无关的接口保持稳定,使新增平台或新增外设时对既有代码的扰动降到最低。代码同时遵循一致的命名、缩进与文件约定,寄存器访问、超时与回调机制都依据统一规范,而非各外设各自为政,从而降低审阅与迁移成本,也让跨平台比对的结构更加清晰。

例程地址:https://github.com/dosconio/alicewiki/tree/main/tutorial/mcudev/demo

Unisym 外设接口与使用教程

GPIO

GPIO 用来控制 MCU 的普通输入输出引脚。通过 Unisym,可以用统一的 C++ 接口完成常见操作,例如点亮 LED、读取按键、配置上拉下拉、开启外部中断、配置复用功能等。

最常见的写法是先取得一个引脚对象:

GPIN& led = GPIOC[13];
GPIN& key = GPIOA[0];

GPIOC[13] 表示 PC13,GPIOA[0] 表示 PA0。

1. 公开接口速查

1.1 GPIN 引脚对象

GPIN 表示一个具体 GPIO 引脚,例如 GPIOA[0]GPIOC[13]

方法 作用 参数 返回值
operator=(bool val) 设置引脚输出电平。 valtrue 时输出高电平,为 false 时输出低电平。 返回当前引脚引用,便于链式或连续赋值。
operator=(GPIN pin) 把另一个引脚当前读到的电平写到本引脚。 pin 是被读取的源引脚。 返回当前引脚引用。
operator bool() 读取引脚输入电平。 无。 高电平返回true,低电平返回 false
setMode(GPIOMode mod, GPIOSpeed spd = defa_speed, bool autoEnClk = true) 配置 GPIO 工作模式和输出速度。 mod 是输入、输出或复用模式;spd 是输出速度;autoEnClktrue 时自动打开端口时钟。 返回当前引脚引用。
canMode() 复位引脚到默认状态(对标 HAL 的HAL_GPIO_DeInit)。 无。 复位成功返回true,失败返回 false
setPull(bool pull_up) 配置输入上下拉。 pull_uptrue 时上拉,为 false 时下拉。 无返回值。
Toggle() 翻转当前输出电平。 无。 无返回值。
Lock(bool tolock_orunlock = true) 锁定 GPIO 配置,防止后续误改。 通常不传参数;STM32 上锁定后不能软件解锁,false 不能解除硬件锁。 无返回值。
isInput() 判断当前引脚是否处于输入类模式。 无。 是输入类模式返回true,否则返回 false
setInterrupt(Handler_t f) 设置该 EXTI line 的中断回调函数。 f 是中断处理函数。 无返回值。
setInterruptPriority(byte preempt, byte sub_priority) 设置该引脚对应外部中断的优先级。 preempt 是抢占优先级;sub_priority 是子优先级。 无返回值。
enInterrupt(bool enable = true) 使能或关闭该引脚对应的外部中断。 enabletrue 时使能,为 false 时关闭。 无返回值。
setMode(GPIORupt::RuptEdge edg, Handler_t f = 0) 把引脚配置为 EXTI 中断触发源。 edg 是触发边沿;f 是可选回调函数。 返回当前引脚引用。
setMode(GPIOEvent::EventEdge edg) 把引脚配置为 EXTI 事件触发源。 edg 是事件触发边沿。 返回当前引脚引用。
_set_alternate(byte selection) 设置复用功能 AF 编号。 selection 是 AF 编号。 设置成功返回true,不支持或参数无效返回 false

_set_alternate() 只适用于 STM32F4、STM32H7、STM32MP13 这类带 AFR 寄存器的目标。STM32F1 的复用重映射不使用这个接口。

1.2 GPORT 端口对象

GPORT 表示一个 GPIO 端口,例如 GPIOAGPIOBGPIOC

方法 作用 参数 返回值
getID() 获取端口编号。 无。 返回端口编号,例如 A 口对应 0,B 口对应 1。
enClock(bool enable = true) 打开或关闭该 GPIO 端口时钟。 enabletrue 时打开,为 false 时关闭。 无返回值。
operator stduint() 读取整个端口输入值。 无。 返回端口输入寄存器快照。
operator[](int pinid) 取得端口中的某个引脚。 pinid 是 0 到 15 的引脚编号。 返回对应GPIN 引脚引用。
operator=(stduint val) 写整个端口输出值。 val 是要写入端口的输出值。 返回当前端口引用。
operator=(GPORT pot) 把另一个端口当前读到的值写到本端口。 pot 是被读取的源端口。 返回当前端口引用。
operator[](GPIOReg reg) 访问 GPIO 端口寄存器。 reg 是寄存器枚举值。 返回寄存器引用,可读写。

整端口写入会同时影响该端口上的多个引脚。只控制单个引脚时,优先使用 GPIOx[n] = trueGPIOx[n] = falseGPIOx[n].Toggle()

1.3 EXTI 辅助函数

以下函数是自由函数(非成员函数),仅限 STM32 平台,用于操作 EXTI pending 标志和软件触发。

函数 作用 参数 返回值 适用平台
EXTI_GetPending(pin) 查询 EXTI line 是否有 pending 标志。 pinGPIN 引脚。 有 pending 返回true,否则 false STM32 全系列
EXTI_ClearPending(pin) 清除 EXTI line 的 pending 标志。 pinGPIN 引脚。 无返回值。 STM32 全系列
EXTI_SoftwareTrigger(pin) 对 EXTI line 产生软件中断触发。 pinGPIN 引脚。 无返回值。 STM32 全系列
EXTI_GetPendingRising(pin) 查询上升沿 pending 标志。 pinGPIN 引脚。 有 pending 返回true,否则 false STM32MP13
EXTI_GetPendingFalling(pin) 查询下降沿 pending 标志。 pinGPIN 引脚。 有 pending 返回true,否则 false STM32MP13
EXTI_ClearPendingRising(pin) 清除上升沿 pending 标志。 pinGPIN 引脚。 无返回值。 STM32MP13
EXTI_ClearPendingFalling(pin) 清除下降沿 pending 标志。 pinGPIN 引脚。 无返回值。 STM32MP13

各平台 EXTI pending 寄存器差异:

平台 Pending 寄存器 特点
STM32F1 PR 统一 pending,写 1 清除(w1c)
STM32F4 PR 统一 pending,写 1 清除(w1c)
STM32H7 PR1/PR2/PR3(分 Core) D1 PR1 用于 GPIO(pin 0-15)
STM32MP13 RPR1/FPR1(分上升/下降沿) 上升沿和下降沿各自独立 pending

1.4 GPIO 全局入口

GPIO 是全局 GPIO 入口对象,用来按端口名取得端口对象。

方法 作用 参数 返回值
operator[](unsigned portid) 取得指定 GPIO 端口。 可以传字符形式的端口名,例如'A''B''C' 返回对应GPORT 端口引用。

常用端口已经有宏定义,通常直接写 GPIOAGPIOBGPIOC 即可:

GPIN& pa0 = GPIOA[0];
GPIN& pc13 = GPIOC[13];

2. 点亮一个 LED

#include <cpp/MCU/ST/STM32F1>
using namespace uni;

void led_init()
{
    GPIN& LED = GPIOC[13];
    LED.setMode(GPIOMode::OUT_PushPull, GPIOSpeed::Atmost_2MHz);
}

void led_on()
{
    GPIOC[13] = true;
}

void led_off()
{
    GPIOC[13] = false;
}

void led_toggle()
{
    GPIOC[13].Toggle();
}

如果开发板上的 LED 是低电平点亮,那么 truefalse 对应的亮灭关系会相反,按实际电路调整即可。

3. 读取一个按键

#include <cpp/MCU/ST/STM32F1>
using namespace uni;

void key_init()
{
    GPIN& KEY = GPIOA[0];

    KEY.setMode(GPIOMode::IN_Pull);
    KEY.setPull(true);
}

bool key_pressed()
{
    return GPIOA[0] == false;
}

setPull(true) 表示上拉,setPull(false) 表示下拉。上拉输入时,常见的低电平按键电路会在按下时读到 false

如果外部硬件已经提供了上下拉,也可以使用浮空输入:

GPIOA[0].setMode(GPIOMode::IN_Floating);

4. 使用外部中断

按键、传感器告警脚等信号可以接到 EXTI 外部中断。

#include <cpp/MCU/ST/STM32F1>
using namespace uni;

static volatile bool key_event;

void on_key_down()
{
    key_event = true;
}

void key_irq_init()
{
    GPIN& KEY = GPIOA[0];

    KEY.setMode(GPIOMode::IN_Pull);
    KEY.setPull(true);

    KEY.setMode(GPIORupt::Negedge, on_key_down);
    KEY.setInterruptPriority(2, 0);
    KEY.enInterrupt();
}

void main_loop()
{
    if (key_event) {
        key_event = false;
        // 在这里处理按键事件
    }
}

外部中断支持三种边沿:

GPIORupt::Posedge    // 上升沿触发
GPIORupt::Negedge    // 下降沿触发
GPIORupt::Anyedge    // 双边沿触发

中断回调函数应该尽量短,只做置位标志、记录状态等简单工作。耗时处理建议放到主循环或任务里完成。

5. 使用 EXTI 事件

如果只希望 GPIO 触发事件,而不是进入中断,可以使用事件接口:

#include <cpp/MCU/ST/STM32F1>
using namespace uni;

void key_event_init()
{
    GPIN& KEY = GPIOA[0];

    KEY.setMode(GPIOMode::IN_Pull);
    KEY.setPull(true);
    KEY.setMode(GPIOEvent::Negedge);
}

事件不会调用中断回调,也不会自动打开 NVIC。它适合配合 WFE、低功耗等待或其它事件唤醒机制使用。

事件也支持三种边沿:

GPIOEvent::Posedge
GPIOEvent::Negedge
GPIOEvent::Anyedge

6. Cortex EVENTOUT 信号输出(仅 STM32F1)

STM32F1 有一个容易和 EXTI 事件混淆的功能:Cortex-M3 EVENTOUT 信号

EXTI 事件是外部引脚边沿 → 内核(输入方向);而 EVENTOUT 是反方向——内核 → 外部引脚(输出方向)。CPU 执行 SEV 指令时,Cortex-M3 内核产生一个 EVENTOUT 脉冲,经过 AFIO 的 EVCR 寄存器路由到指定的 GPIO 引脚上输出。

这是 STM32F1 独有的功能——F4/H7/MP13 的 SYSCFG 没有 EVCR 寄存器。

6.1 接口

函数 作用
EVENTOUT_Config(pin) 指定 EVENTOUT 信号输出到哪个引脚
EVENTOUT_Enable() 使能 EVENTOUT 输出
EVENTOUT_Disable() 关闭 EVENTOUT 输出

6.2 使用示例

#include <cpp/MCU/ST/STM32F1>
using namespace uni;

void eventout_demo()
{
    // 将 Cortex EVENTOUT 信号路由到 PC13
    EVENTOUT_Config(GPIOC[13]);
    EVENTOUT_Enable();

    // 之后执行 SEV 指令会在 PC13 上产生一个脉冲
    __SEV();

    // 不再需要时关闭
    EVENTOUT_Disable();
}

6.3 典型用途

  • 多核/多芯片同步:一个 MCU 通过 EVENTOUT 脉冲通知另一个 MCU 的 WFE 等待
  • 调试:观察 SEV 指令的执行时序
  • 与其他 Cortex-M3 设备的事件接口对接

6.4 与 EXTI 事件的区别

EXTI 事件(GPIOEvent EVENTOUT
方向 引脚 → 内核 内核 → 引脚
触发源 外部引脚边沿 CPU 执行SEV 指令
等待方式 WFE 等待外部事件 输出脉冲给外部设备
适用平台 STM32 全系列 仅 STM32F1

7. AFIO 复用重映射(仅 STM32F1)

STM32F1 没有 AFR 寄存器,外设引脚重映射通过 AFIO_MAPR / AFIO_MAPR2 寄存器完成。Unisym 提供 AFIORemap 枚举 + AFIO_Remap() 函数,替代 HAL 的 76 个 __HAL_AFIO_REMAP_* 宏。

7.1 接口

// 单 bit 重映射:第二参数 bool
void AFIO_Remap(AFIORemap remap, bool enable);

// 多 bit 字段重映射:第二参数 byte → 使用 AFIO_RemapConfig
void AFIO_RemapConfig(AFIORemap remap, byte value);

7.2 AFIORemap 枚举

单 bit(用 bool 版本):

枚举值 寄存器 说明
SPI1 MAPR 0 SPI1 重映射
I2C1 MAPR 1 I2C1 重映射
USART1 MAPR 2 USART1 重映射
USART2 MAPR 3 USART2 重映射
TIM4 MAPR 12 TIM4 重映射
PD01 MAPR 16 PD0/PD1 重映射
TIM5CH4 MAPR 17 TIM5_CH4 重映射
SPI3 MAPR 28 SPI3 重映射(互联型)
ETH MAPR 21 以太网重映射(互联型)
CAN2 MAPR 22 CAN2 重映射(互联型)
MII_RMII MAPR 23 MII/RMII 选择(互联型)
ADC1_ETRGINJ MAPR 18 ADC1 外部触发注入
ADC1_ETRGREG MAPR 19 ADC1 外部触发规则
ADC2_ETRGINJ MAPR 20 ADC2 外部触发注入
ADC2_ETRGREG MAPR 21 ADC2 外部触发规则
TIM2ITR1 MAPR 29 TIM2 ITR1 → USB/ETH(互联型)
PTP_PPS MAPR 30 以太网 PTP_PPS(互联型)
TIM9 MAPR2 5 TIM9 重映射
TIM10 MAPR2 6 TIM10 重映射
TIM11 MAPR2 7 TIM11 重映射
TIM12 MAPR2 12 TIM12 重映射
TIM13 MAPR2 8 TIM13 重映射
TIM14 MAPR2 9 TIM14 重映射
TIM15 MAPR2 0 TIM15 重映射
TIM16 MAPR2 1 TIM16 重映射
TIM17 MAPR2 2 TIM17 重映射
CEC MAPR2 3 CEC 重映射
TIM1DMA MAPR2 4 TIM1 DMA 重映射
TIM67DACDMA MAPR2 11 TIM6/7 + DAC DMA 重映射
FSMC_NADV MAPR2 10 FSMC NADV 断开
MISC MAPR2 13 杂项重映射

多 bit 字段(用 byte 版本):

枚举值 寄存器 位域
USART3 MAPR 5:4 0=NoRemap, 1=Partial, 2=Full
TIM1 MAPR 7:6 0=NoRemap, 1=Partial, 3=Full
TIM2 MAPR 9:8 0=NoRemap, 1=Partial1, 2=Partial2, 3=Full
TIM3 MAPR 11:10 0=NoRemap, 2=Partial, 3=Full
CAN1 MAPR 14:13 0=PA11, 2=PB8, 3=PD0
SWJ MAPR 26:24 0=Full, 1=NoJNTRST, 2=NoJTAG, 4=Disable

7.3 使用示例

#include <cpp/MCU/ST/STM32F1>
using namespace uni;

void remap_demo()
{
    // 单 bit:使能 SPI1 重映射
    AFIO_Remap(AFIORemap::SPI1, true);

    // 多 bit:TIM3 完全重映射到 PC6/7/8/9
    AFIO_RemapConfig(AFIORemap::TIM3, 3);  // 3=Full

    // CAN1 重映射到 PB8/PB9
    AFIO_RemapConfig(AFIORemap::CAN1, 2);  // 2=Remap2(PB8)

    // SWJ:禁用 JTAG,保留 SWD
    AFIO_RemapConfig(AFIORemap::SWJ, 2);   // 2=NoJTAG

    // 取消 SPI1 重映射
    AFIO_Remap(AFIORemap::SPI1, false);

    // TrustZone:将 PB7 设为 Secure(仅 MP13)
    GPIO_SecurePin(GPIOB[7]);
    if (GPIO_IsPinSecured(GPIOB[7])) {
        // Secure 引脚,NonSecure 代码无法访问
    }
    GPIO_NonSecurePin(GPIOB[7]); // 恢复为 NonSecure

    // 原子多引脚写入:同时 set PA5/PA7, reset PA1/PA3
    GPIOA.maset(0x00A0, 0x000A); // setMask=bit5,7  resetMask=bit1,3
}

7.4 注意事项

  • 标注"互联型"的位只在 STM32F105/F107 上有效,其他型号该位保留
  • ADC2_ETRGREGETH 占同一位(bit 21),不同子型号含义不同,不会同时使用
  • SWJ 的值不是连续的:0/1/2/4(没有 3),因为 bit 26 独立控制全禁用
  • 修改 SWJ 配置会释放对应的 JTAG 引脚(如 PA15/PB3/PB4),可作 GPIO 使用
  • FSMC_NADV 使能=true 表示断开 NADV(反直觉),与 HAL 宏 FSMCNADV_DISCONNECTED 对应

8. 配置复用功能

USART、SPI、I2C、TIM、SDIO 等外设通常需要把 GPIO 配置成复用功能。

在 STM32F4、STM32H7、STM32MP13 上,除了设置 GPIO 模式,还要设置 AF 编号。例如 PA9 配置为 USART1_TX:

#include <cpp/MCU/ST/STM32F4>
using namespace uni;

void usart1_tx_pin_init()
{
    GPIOA[9].setMode(GPIOMode::OUT_AF_PushPull, GPIOSpeed::High)
            ._set_alternate(7);
}

AF 编号请以具体芯片的数据手册为准。

STM32F1 没有 AFR 寄存器,普通默认复用只需要设置 GPIO 模式:

#include <cpp/MCU/ST/STM32F1>
using namespace uni;

void usart1_tx_pin_init()
{
    GPIOA[9].setMode(GPIOMode::OUT_AF_PushPull, GPIOSpeed::Atmost_50MHz);
}

如果 STM32F1 需要外设重映射,需要另外配置 AFIO remap。

9. 锁定 GPIO 配置

GPIO lock 可以锁定引脚配置,防止后续代码误改 GPIO 模式。

#include <cpp/MCU/ST/STM32F4>
using namespace uni;

void led_lock_init()
{
    GPIOA[5].setMode(GPIOMode::OUT_PushPull, GPIOSpeed::High);
    GPIOA[5].Lock();
}

STM32 的 GPIO lock 是硬件单向锁。锁定后软件不能解锁,只能等下一次 reset 后解除。因此它适合在板级初始化完成后使用,不适合调试阶段反复调用。

10. 复位引脚配置

canMode() 用于将 GPIO 引脚复位到默认状态,对标 HAL 库的 HAL_GPIO_DeInit()

10.1 功能说明

调用 canMode() 后,引脚会被恢复到复位后的默认状态:

平台 复位后状态
STM32F1 浮空输入,ODR 清零,EXTI 映射清除
STM32F4 输入模式,AFR/PUPDR/OTYPER/OSPEEDR 清零,EXTI 映射清除
STM32H7/MP13 模拟模式,AFR/PUPDR/OTYPER/OSPEEDR 清零,EXTI 映射清除
CW32F030 输入模式,OPENDRAIN/SPEED/ANALOG 清零
MSP432P4 输入方向

对于已配置为 EXTI 中断/事件源的引脚,canMode() 会同时清除 EXTI 映射、中断屏蔽、事件屏蔽和边沿触发配置。

10.2 使用示例

#include <cpp/MCU/ST/STM32F4>
using namespace uni;

void pin_reset_demo()
{
    // 先配置引脚
    GPIOA[5].setMode(GPIOMode::OUT_PushPull, GPIOSpeed::High);
    GPIOA[5] = true;

    // 复位引脚到默认状态
    if (GPIOA[5].canMode()) {
        // 复位成功,引脚现在是输入模式
        // 可以重新配置为其他用途
    }
}

10.3 典型应用场景

动态切换外设功能:

void switch_to_uart()
{
    // 先复位引脚
    GPIOA[9].canMode();
    GPIOA[10].canMode();

    // 重新配置为 USART1
    GPIOA[9].setMode(GPIOMode::OUT_AF_PushPull, GPIOSpeed::High)
            ._set_alternate(7);
    GPIOA[10].setMode(GPIOMode::IN_Pull)._set_alternate(7);
}

void switch_to_timer()
{
    // 先复位引脚
    GPIOA[9].canMode();

    // 重新配置为 TIM1_CH2
    GPIOA[9].setMode(GPIOMode::OUT_AF_PushPull, GPIOSpeed::High)
            ._set_alternate(1);
}

清除 EXTI 配置:

void disable_key_irq()
{
    // canMode() 会自动清除 EXTI 映射和中断配置
    GPIOA[0].canMode();
}

10.4 注意事项

  • canMode() 是单向操作,无法恢复之前的配置。调用前应确认是否需要保存当前状态。
  • 对于已锁定的引脚(Lock() 调用后),canMode() 可能无法生效。
  • 复位后引脚进入高阻态,外部电路需要考虑悬空期间的影响。

11. 整端口读写

除了单个 pin,也可以操作整个 GPIO 端口:

#include <cpp/MCU/ST/STM32F4>
using namespace uni;

void port_demo()
{
    GPIOB.enClock();

    GPIOB = 0x00FF;
    stduint input = GPIOB;
    (void)input;
}

整端口写入会影响该端口上的所有输出引脚。如果只想控制单个引脚,优先使用 GPIOx[n] = trueGPIOx[n] = falseGPIOx[n].Toggle()

12. 常用代码速查

GPIOA[5].setMode(GPIOMode::OUT_PushPull);
GPIOA[5].setMode(GPIOMode::OUT_PushPull, GPIOSpeed::High);
GPIOA[5] = true;
GPIOA[5] = false;
GPIOA[5].Toggle();

GPIOA[0].setMode(GPIOMode::IN_Pull);
GPIOA[0].setPull(true);
bool level = GPIOA[0];

GPIOA[0].setMode(GPIORupt::Negedge, on_key_down);
GPIOA[0].setInterruptPriority(2, 0);
GPIOA[0].enInterrupt();

GPIOA[0].setMode(GPIOEvent::Negedge);

GPIOA[9].setMode(GPIOMode::OUT_AF_PushPull, GPIOSpeed::High)
        ._set_alternate(7);

GPIOA[5].Lock();

GPIOA[5].canMode();

// EXTI 辅助函数
EXTI_GetPending(GPIOA[0]);
EXTI_ClearPending(GPIOA[0]);
EXTI_SoftwareTrigger(GPIOA[0]);

// STM32MP13 独有:分边沿 pending
EXTI_GetPendingRising(GPIOA[0]);
EXTI_ClearPendingFalling(GPIOA[0]);

13. 注意事项

  • setMode() 默认会自动打开 GPIO 端口时钟。
  • setPull(true) 是上拉,setPull(false) 是下拉。
  • 中断回调函数应保持短小,复杂逻辑放到主循环或任务中处理。
  • 整端口写入会影响同一端口的多个 pin,使用前要确认不会覆盖其它输出。
  • STM32F1 的 AFIO remap 与 STM32F4/H7/MP13 的 _set_alternate() 不是同一种机制。
  • STM32 GPIO lock 锁定后不能软件解锁,只能 reset 后解除。
  • EXTI_GetPending / EXTI_ClearPending / EXTI_SoftwareTrigger 仅适用于 STM32 平台(F1/F4/H7/MP13)。CW32 和 MSP432 没有 EXTI 硬件。
  • EXTI_ClearPending 使用写 1 清除(w1c)语义,不要用读-改-写方式操作。
  • STM32MP13 的 pending 寄存器分为上升沿(RPR)和下降沿(FPR),可用 EXTI_GetPendingRising / EXTI_GetPendingFalling 分别查询。
收藏 评论0 发布时间:2026-8-21 12:27

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版