跳转至

示例:GPIO 脉冲宽度触发

Protocol Exerciser 可在支持的引脚上武装 GPIO 脉冲宽度触发,并在测量到的脉冲符合配置规则时送出全局事件。使用 AqProtocolExerciser.set_gpio_trigger 武装硬件,并为事件名称 gpio_trigger 注册处理函数。Payload 位于 PxEventMsg.global_event.gpio_trigger,类型为 PxGpioTriggerEvent(见 aqpxlib.gpioaqpxlib.event)。

限制

  • 引脚: 脉冲宽度触发与脉冲产生仅支持 GPIO 索引 8 与 9(与 send_gpio_pulse 相同)。
  • 持续时间: min_duration_nsmax_duration_ns 都必须大于 5 ns 且小于 1 s
  • 事件: 在 exerciser session 上为逻辑名称 gpio_trigger 注册处理函数。这是全局事件,不是器件级事件。

配置触发

调用 set_gpio_trigger,参数如下: | 参数 | 含义 | | -------- | ------- | | gpio_idx | 引脚索引(89)。 | | min_duration_ns / max_duration_ns | 脉冲宽度窗口,单位纳秒。 | | low_pulse | 为 True 时考虑低电平脉冲。 | | high_pulse | 为 True 时考虑高电平脉冲。 | | mode | PxGpioWidthTriggerMode.TRIGGER_PULSE_WIDTH_IN_RANGE(默认)或 TRIGGER_PULSE_WIDTH_OUT_OF_RANGE。 |

mode 决定宽度落在 [min, max] 之内之外时是否触发。

处理 gpio_trigger

处理函数收到 PxEventMsg.Payload 位于 global_event.gpio_trigger(PxGpioTriggerEvent):

字段 类型 含义
pin_idx int 造成触发的引脚索引。
pulse_duration int 测量到的宽度(纳秒)。
pulse_polarity bool 检测到的脉冲极性。

示例

下列脚本在引脚 8 武装范围内触发、注册处理函数,再用 send_gpio_pulse 发出短脉冲让处理函数执行。若由外部设备驱动该引脚,请自行替换脉冲调用。

run_gpio_trigger_example.py
import logging
import threading

from aqpxlib import AqProtocolExerciser, PxGpioWidthTriggerMode, PxIoState
from aqpxlib.event import PxEventMsg

logger = logging.getLogger(__name__)


def run_gpio_trigger_example() -> None:
    with AqProtocolExerciser.connect(port=60600) as px:
        done = threading.Event()

        def on_gpio_trigger(event_msg: PxEventMsg) -> None:
            g = event_msg.global_event.gpio_trigger
            logger.info(
                "GPIO trigger: pin=%d duration_ns=%d polarity=%s",
                g.pin_idx,
                g.pulse_duration,
                g.pulse_polarity,
            )
            done.set()

        px.add_event_handler("gpio_trigger", on_gpio_trigger)

        pin = 8
        px.set_gpio_trigger(
            gpio_idx=pin,
            min_duration_ns=500,
            max_duration_ns=50_000,
            low_pulse=True,
            high_pulse=True,
            mode=PxGpioWidthTriggerMode.TRIGGER_PULSE_WIDTH_IN_RANGE,
        )

        px.send_gpio_pulse(
            gpio_idx=pin,
            active_state=PxIoState.HIGH,
            idle_state=PxIoState.LOW,
            active_time_ns=5000,
        )

        assert done.wait(timeout=3), "GPIO trigger event not received"


if __name__ == "__main__":
    logging.basicConfig(format="[%(levelname)s] %(message)s")
    logger.setLevel(logging.INFO)
    run_gpio_trigger_example()

运行:

python run_gpio_trigger_example.py

另见