Zynq开发板按键点灯实操:PS端GPIO与PL端AXI GPIO寄存器配置对比
拿一块带 PS 和 PL 两层结构的 Zynq 开发板上来就想做一个“软件按键点灯”按一下按键LED 亮再按一下灭。听着跟单片机课设似的可真在 PYNQ 环境下动手会发现有个问题绕不开——按键和 LED 到底接在 PS 端还是 PL 端用 PS 端 GPIO 写软件跟在 FPGA 里挂一个 PL 端 GPIO 控制器两条路都能实现同一个效果但代码、硬件、调试方式完全不一样。这篇就当做一个实操记录把两种实现都完整跑一遍从接线、Overlay 加载、寄存器读写到踩坑点一次性说清楚。不管是刚接触 Zynq 的初学者还是想把点灯逻辑真正玩明白的开发者都可以照着来。1. 一开始就要想清楚按键和 LED 到底交给 PS 还是 PL很多人习惯把 Zynq 当成“ARM FPGA 两块芯片拼在一起”实际它是一颗芯片只是内部被分成处理系统和可编程逻辑两部分。PS 端就是 ARM 处理器那一套能跑 Linux、跑 PythonPL 端就是 FPGA 那套逻辑可以自己搭电路。GPIO 这个功能两边都有但含义不同。1.1 PS 端 GPIO 的资源MIO、EMIO 和寄存器PS 端的 GPIO 是由芯片里一个固定硬件模块管理的对应一组寄存器基地址在 0xE000A000。你不需要在 FPGA 里写任何逻辑CPU 直接读写这个地址就能控制引脚。PS 端 GPIO 管脚分成几组MIO 引脚是专用物理引脚数量固定很多还和启动模式、UART、SD 卡这类功能复用所以不是所有 MIO 都能随便拿来点灯EMIO 则是把 PS 端 GPIO 控制器的一部分信号引到 PL 里再由 PL 映射到实际物理引脚。这意味着哪怕你用的是“PS 端 GPIO 控制器”信号也可能经过 PL 才落到引脚上。设计上有时候很拧巴你光看“PS GPIO”四个字以为不碰 PL 就能点灯结果一看引脚表板子上大部分按钮、LED 都连到 PL 侧引脚根本没有引出到 MIO。这就是为什么在 PYNQ 这类开发板上直接能用 PS GPIO 点亮的板载外设往往很少更多时候得走 EMIO 或者干脆做 PL 端 GPIO。做实验之前一定要看原理图别凭感觉。1.2 PL 端 GPIO 是怎么回事PL 端 GPIO 不是在芯片里预置的硬件而是你用 FPGA 逻辑“搭”出来的一个控制器一般直接在开发工具里调用厂家提供的 AXI GPIO IP 来生成。它内部有几个可读写的寄存器通过 AXI 总线暴露给 PS 端PS 端软件把 AXI GPIO 的物理地址当成普通内存来访问往地址里写数PL 端引脚电平就会变化读地址就能拿到按键状态。所以“PL 端 GPIO”本质上是三件事的组合一段 FPGA 逻辑、一组寄存器、一组物理引脚。软件控制逻辑并没有变变的只是写入的地址和寄存器语义。看完下面两条实现路径这个体会会更深。1.3 一个表格先把两种方案拉出来对比对比维度PS 端 GPIOPL 端 AXI GPIO是否需要重新编译 PL 工程用 MIO 直连时不需要用 EMIO 时仍需要必须先把 bitstream 生成出来引脚数量MIO 有限且复用严重取决于 FPGA 资源通常非常充足软件访问方式读写 0xE000A000 附近寄存器读写 AXI 分配到的地址比如 0x41200000适合场景少量固定引脚、系统级启动配置大量 IO、自定义协议、复杂时序逻辑修改灵活性改动软件马上生效改逻辑要重新综合实现一遍2. 准备阶段最容易出的三个问题接线、镜像和 Overlay在写 Python 代码之前硬件环境和工程环境必须就绪。这块看起来简单实际踩过坑的人都知道接线错误和 Overlay 没加载是点灯失败最高频的原因。2.1 按键和 LED 的接法按键这段通常有两种接法。一种是“低电平有效”按键一端接 GPIO 引脚另一端接 GND同时给 GPIO 配置内部上拉电阻。这样平时引脚读到 1按下时被拉到地读到 0。另一种是“高电平有效”按键一端接 3.3V另一端接 GPIO平时靠下拉电阻或输入缓冲保持 0按下时读到 1。开发板上板载按键一般已经处理好上拉或下拉你不用管但从板子外面飞线接按键时务必把共地做好否则读到的是悬空电平一会 1 一会 0。LED 这边最省事的是 GPIO 高电平时 LED 亮GPIO 和 GND 之间串联一个限流电阻。电阻太小会烧引脚太大又太暗220 到 470 欧姆是比较常用的范围。有些板载 LED 是从 VCC 到 GPIO 的接法这时候控制逻辑是反的写入 0 才亮写入 1 反而灭。程序里出现“灯反着亮”时别急着查代码先看原理图上的共阳共阴接法。还有一点很关键这些 GPIO 绝大部分都是 3.3V 电平别拿 5V 信号硬怼进去轻则读不到正确电平重则烧掉引脚。2.2 镜像、bitstream 和 hwh 文件的关系PYNQ 环境跑在开发板 SD 卡里的 Linux 上最常见的操作方式是浏览器打开 Jupyter Notebook然后在 Notebook 里跑 Python 控制硬件。上电后默认系统里已经带了一些官方 Overlay但如果你自己用 FPGA 工具生成了一个新的 bitstream就得把它和配套的 hwh 文件放到同一个目录再手动加载。Overlay 这个词可以理解成“一套已经配置好的 FPGA 逻辑镜像”一个 Overlay 对应一个 bit 文件。加载时用类似from pynq import Overlay; over Overlay(my_design.bit)的语句完成。真正容易漏的是bit 文件只是 FPGA 的配置如果缺少 hwh 文件里的地址信息PYNQ 就不知道该给寄存器暴露什么名称代码里引用over.xxx_ip就会报错。写完自定义 PL 工程后常见问题是只拷了.bit忘了.hwh加载没报错一访问 IP 就崩。3. PS 端 GPIO 实现直接操作寄存器点灯PYNQ 的优势是能用 Python 直接跟硬件打交道。PS 端 GPIO 的实现我习惯直接用 mmap 把物理地址映射到用户空间然后对寄存器做读写。这样做的好处是不依赖某个特定版本的封装库只要知道寄存器偏移任何时候都能跑。3.1 用 mmap 把 GPIO 控制器当一块内存来访问现代 Linux 里访问物理内存不是直接给地址就能读需要用/dev/mem配合mmap。GPIO 控制器基地址 0xE000A000 是一个已经按页对齐的地址所以可以直接映射 4KB 页面。import mmap import os import struct import time PS_GPIO_BASE 0xE000A000 DATA_RO 0x00 # 输入状态只读 DATA 0x04 # 输出数据寄存器 DIRM 0x204 # 方向控制掩码置1表示该位由软件控制 OEN 0x208 # 输出使能掩码置1表示输出模式 fd os.open(/dev/mem, os.O_RDWR | os.O_SYNC) gpio_map mmap.mmap(fd, 4096, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE, offsetPS_GPIO_BASE) def read32(offset): return struct.unpack(I, gpio_map[offset:offset 4])[0] def write32(offset, value): gpio_map[offset:offset 4] struct.pack(I, value 0xFFFFFFFF)很多教程会把这一层封装叫peek/poke意思就是看一个地址、改一个地址。理解这里比看懂点灯本身重要所有外设寄存器在你眼里不过是内存地址后续操作全是 32 位整数的读写。3.2 方向配置和按键点灯的完整循环PS 端 GPIO 控制器的方向和输出使能需要独立设置。用掩码方式理解这几个寄存器会比较快DIRM 里某一位置 1代表这个引脚的方向由软件接管OEN 里某一位置 1代表该脚是输出。复位后这些位默认是 0意味着方向不被软件控制引脚也不输出如果你只写 DATA 不动 DIRM 和 OENLED 电平根本不会变这几乎是 PS 端点灯失败的头号原因。假设手头某个 MIO 引脚接了 LED另一个 MIO 引脚接按键初始化和轮询代码可以这样写LED_PIN 0 KEY_PIN 1 # 把 LED 和 KEY 两个引脚都交给软件控制 write32(DIRM, (1 LED_PIN) | (1 KEY_PIN)) # 只有 LED 作为输出按键保持输入 write32(OEN, 1 LED_PIN) # 灯先灭 write32(DATA, 0) while True: key (read32(DATA_RO) KEY_PIN) 1 if key 0: # 按下低电平有效 write32(DATA, 1 LED_PIN) # 亮 else: write32(DATA, 0) # 灭 time.sleep(0.02)这个循环已经能跑但直接这样用会有抖动问题。按键是机械结构按下和松开的一瞬间电平会来回跳变几次这个时间通常只有几毫秒。我前面的循环每 20ms 读一次看起来已经不快但在快速按放、或者按到一半接触不良时依然可能误触发。电磁开关和机械按键的细微振动是点灯这种小实验里最容易被忽略的稳定性杀手。3.3 给按键读取加上软件消抖最朴素的消抖方式就是“连续采样多次值一致才认为有效”。可以抽象成一个小函数def read_key_stable(key_pin, check_times5, interval0.01): first (read32(DATA_RO) key_pin) 1 for _ in range(check_times - 1): time.sleep(interval) now (read32(DATA_RO) key_pin) 1 if now ! first: return None return first在轮询主循环里每次只读取一次消抖后的结果如果返回 None 就继续采样直到拿到稳定值。这样按下和松开会各有一个短暂的等待窗口避免了抖动带来的重复触发。实际调试时如果按键按下偶尔不响应就适当减少check_times如果出现一次按下触发两次动作就增加采样次数或者拉长interval。4. PL 端 GPIO 实现在 FPGA 里做一个可控的 IO 控制器相比 PS 端直接操作寄存器PL 端实现多了一道工序先在 FPGA 工具里搭一个 AXI GPIO IP生成 bitstream再回到 Python 按 AXI 地址读写。这条链路听起来复杂其实跑通一次后会比 PS 端灵活很多。4.1 Block Design 里怎么搭一个按键和 LED 控制器打开 FPGA 开发工具新建工程选对应的 Zynq 器件。在 Block Design 中添加 Zynq PS 处理系统然后添加一个 AXI GPIO IP配置成双通道第一通道作为按键输入宽度设为 4第二通道作为 LED 输出宽度也设为 4。这里的通道数量可以按你实际按钮和 LED 的数量调整只是寄存器偏移会跟着变化。如果工程里有自动连接功能让工具自动把 AXI GPIO 接到 PS 端的 AXI 主接口上并分配复位和时钟。地址编辑器会给这个 IP 分配一个地址段常见的结果类似 0x41200000。这个地址一定要记下来后面 Python 里访问 PL 外设全靠它。这一步的本质是什么你是在 PL 里创建了一组可读写的寄存器这些寄存器的读写引脚最终连到芯片物理引脚上。ARM 端看到的是一个标准 AXI 从设备写进去的数据由 FPGA 内部逻辑转成引脚电平读回来的数据也由内部逻辑从引脚采样得到。对 PS 端来说它不关心引脚实际在哪只关心地址。4.2 物理引脚约束和 bitstream 生成IP 里拖出来的接口必须绑定到开发板的具体引脚上。不同板卡引脚不同需要参考板卡原理图在约束文件里给每个端口分配物理位置和电平标准类似这样set_property PACKAGE_PIN D18 [get_ports {gpio_io_0[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio_io_0[0]}]引脚分配完成后运行综合、布局布线生成 bitstream。这一步完成会得到两个文件.bit和.hwh。把它俩放到 PYTHON 能找到的目录通常就是 PYNQ 的overlays目录或 Notebook 当前目录。加载时用 Overlay 接口代码里这个 Overlay 对象会解析 hwh 文件里的 AXI 地址把寄存器接口暴露出来。如果你只是想在开发板上玩按钮和 LED也可以直接用官方基础 Overlay它已经提前把板载按钮和 LED 接进 AXI GPIO 了。自己搭一个 IP 的意义在于理解内部结构以及后续可以往里加更多自定义逻辑。4.3 Python 侧访问 AXI GPIO 的寄存器AXI GPIO 的寄存器布局比 PS 端 GPIO 控制器简单每个通道只有数据寄存器和方向寄存器双通道时两个通道依次偏移排列。第一通道的数据寄存器偏移 0x00、方向寄存器偏移 0x04第二通道数据寄存器偏移 0x08、方向寄存器偏移 0x0C。方向寄存器里写 1 代表输入写 0 代表输出跟 PS 端的方向掩码逻辑略有不同。地址 0x41200000 可能跟我们前面 mmap 的是同一类物理地址所以复用一个读写封装PL_GPIO_BASE 0x41200000 CH1_DATA 0x00 CH1_TRI 0x04 CH2_DATA 0x08 CH2_TRI 0x0C fd os.open(/dev/mem, os.O_RDWR | os.O_SYNC) pl_map mmap.mmap(fd, 4096, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE, offsetPL_GPIO_BASE) def pl_read32(offset): return struct.unpack(I, pl_map[offset:offset 4])[0] def pl_write32(offset, value): pl_map[offset:offset 4] struct.pack(I, value 0xFFFFFFFF)初始化时把第一通道全部设成输入第二通道全部设成输出然后循环读按键值、写 LED 状态。因为板载按钮通常按下为低电平LED 又多半是点亮为高所以让按下时输出 1、松开时输出 0 的话直接对按键值取反就行pl_write32(CH1_TRI, 0xFFFFFFFF) # 按键通道全为输入 pl_write32(CH2_TRI, 0x00000000) # LED 通道全为输出 while True: btns pl_read32(CH1_DATA) 0xF # 按下为0松开为1取反后按下点亮松开熄灭 pl_write32(CH2_DATA, (~btns) 0xF) time.sleep(0.01)这时候你再回头看PL 端实现最核心的东西已经不是“GPIO 怎么操作”而是地址映射和寄存器布局。只要地址对、方向对剩下就是赋值判断。也正因为整个控制逻辑都跑在 FPGA 里你可以把按键滤波、防抖、甚至多键组合判断全部用硬件逻辑实现软件只负责最终业务判断。5. 两种方案跑完后怎么选、怎么改把同样的按键点灯分别用 PS 端 GPIO 和 PL 端 GPIO 各跑一遍之后能明显感觉到两者不是简单的“等价替换”而是在开发流程、调试难度、扩展方向上大不一样。5.1 我的实际取舍逻辑先说结论如果只是控制几个引脚读按键、亮灯而且这组引脚刚好被引到了 MIO 上那就用 PS 端 GPIO最省事连 PL 工程都不用动。但现实中更多情况是板上器件都接在 PL 侧你不得不在 FPGA 里建 PL 端控制器或者你之后要加编码器、PWM、串口时序这些自定义逻辑那无论如何都要走 PL 端。PL 端方案前期要综合、布线一次跑下来可能比写 Python 慢很多可一旦逻辑固化下来后期改动就非常灵活。比如你想让按键按下后不是立刻亮灯而是延迟 3 秒亮PL 里加一个计数器模块比 Python 里睡 3 秒可靠得多因为它不占用 ARM 的 CPU 时间也不受系统调度影响。我实际调试时只要涉及毫秒级以下时序就基本不再考虑 PS 端轮询方案。5.2 想复用的话建议把“读按键”和“写 LED”拆开不管用哪条路我都习惯在 Python 里把硬件操作封装成两个函数read_key_state()和set_led_state(value)。后面的业务逻辑不关心底层是 PS 还是 PL 寄存器只调用这两个函数。这样做的好处是以后从 PS 端切换到 PL 端时只需要替换函数内部实现主循环一行不用改测试时也可以直接 mock 一个假按键状态来验证逻辑。按键消抖的代码也建议放在这层封装里。用前面提到的连续采样法或者维护一个简单状态机记录上一次稳定电平只有在新电平持续一段时间后才认为状态变化。不要在主循环里散落一堆time.sleep(0.02)时间一长你就分不清哪段 sleep 是消抖、哪段是业务节奏。6. 点灯过程中反复踩过的几个问题以及排查思路最后记录几个我实际调试中碰到的问题。很多问题看起来像是“寄存器没写对”其实根因五花八门排查思路比答案更重要。6.1 按键读出来始终是 1按下去也没反应这个问题最常见的原因是方向配置不对。PS 端 GPIO 里如果 DIRM 没把按键对应位置 1或者 OEN 错置为 1引脚会被配置成输出输入缓冲读不到外部电平。PL 端 AXI GPIO 则要确认方向寄存器里那一对应位是 1而不是 0。硬件方面也不要忽略按键另一端是不是真连到了地或电源共地没做好电平会飘板上按键已带上拉时你还从外部并联一个下拉电阻会改变默认电平。先用万用表量一下引脚电压是最快的排查方式。6.2 写入地址没反应甚至直接报总线错误如果 Python 里 mmap 映射一个根本没分配的物理地址或者 bitstream 没加载读写时可能触发总线错误也可能读到全 0。我的排查顺序一般是先确认.bit已经加载成功再确认 BLOCK DESIGN 地址编辑器和 Python 里用的地址完全一致最后看映射 offset 是否页对齐。mmap 的 offset 参数必须按 4KB 页对齐否则虽然有时不报错但访问的物理页根本不是你想的那个。如果在 PL 端读写寄存器时数据总是一成不变可能是 PL 端 IP 时钟没跑起来检查 Zynq PS 的时钟输出有没有正确连到 IP 上而不是只盯着 Python 代码。6.3 后面还想做点什么从点灯到中断和自定义时序按键盘点灯的下一步通常是想让 CPU 不空转等按键触发中断再响应。PS 端 GPIO 控制器本身支持触发中断但需要配置对应 bank 的中断使能并且把中断信号接入 ARM 的中断系统PL 端则更常见的是用一个 GPIO IP 的中断输出接到 PS 的 IRQ 引脚软件里注册中断服务函数按键变化时硬件自动上报。如果需求更复杂比如按键短按、长按、双击区分或按键控制的是 PWM 呼吸灯我建议直接在 PL 端写一个小状态机把按键消抖、计时、PWM 生成全部放在 FPGA 逻辑里Python 只管读状态结果。这样既发挥 PL 的时序优势又保持 Python 侧代码简单也算是对“PS 端PL 端 GPIO 使用”最完整的一种理解两边各干各擅长的事。

相关新闻

open-code-review实战指南:如何设计高效的代码评审流程与检查清单

open-code-review实战指南:如何设计高效的代码评审流程与检查清单

1. 从“open-code-review”这个名字说起:它到底想解决什么问题第一次看到“open-code-review”这个标题,我脑子里冒出来的第一个念头是:这大概率不是一个具体的工具名,而是一类做法的统称——把代码评审这件事从“关起门来几个人看…

2026/10/13 9:01:58 阅读更多 →
Redis替代MySQL做主存储:架构设计、持久化与迁移实战

Redis替代MySQL做主存储:架构设计、持久化与迁移实战

1. 架构决策背后的真实动因先聊聊这个标题。Redis 不做缓存、改行做 MySQL 的主存储——这事放五年前,谁敢提这个方案,大概率会被运维同事当场按住。但现在,越来越多的团队开始在特定业务场景里认真评估这个选择,而且已经有落地案…

2026/10/13 9:02:39 阅读更多 →
GAN生成对抗网络MATLAB版本:可直接运行的深度生成模型实践指南

GAN生成对抗网络MATLAB版本:可直接运行的深度生成模型实践指南

简介:这份资源是面向深度学习初学者与科研人员的GAN生成对抗网络MATLAB实现代码,可直接运行,帮助读者在无需Python环境的前提下理解生成器与判别器的博弈训练机制。压缩包共14个文件,以13个m脚本和1个bmp图像为主,整体…

2026/10/13 11:17:06 阅读更多 →

最新新闻

CATIA V5R13汽车线束设计:三维布线到展平BOM的避坑指南

CATIA V5R13汽车线束设计:三维布线到展平BOM的避坑指南

简介:针对CATIA V5R13汽车线束设计的PPT课件,面向电气工程初学者与CATIA V5新用户,系统讲解线束在数字样机中的创建、装配与连接方法。在整车开发中,线束承担汽车电气系统中电能与信号传输,设计质量直接影响整车布线合…

2026/10/13 14:21:17 阅读更多 →
机器学习从入门到精通:一份带路标的实操地图

机器学习从入门到精通:一份带路标的实操地图

经常被问到同一个问题:学Python机器学习,到底怎么从入门走到精通?问的人五花八门,有想转行的程序员,有在校学生,也有做数据分析正考虑转型的同事。大家手里不缺教程,收藏夹里躺着几十个视频和几…

2026/10/13 14:21:17 阅读更多 →
新人接手项目管理:第一周先做三张表,快速建立掌控感

新人接手项目管理:第一周先做三张表,快速建立掌控感

1. 新人接手项目管理的真实困境:不是不会管,是不知道先管什么刚入职不久就被拉进项目群、丢过来一份需求文档、告诉你"这个项目你来跟",这种场景在不少公司都挺常见。尤其是节奏快、业务复杂度高的环境里,新人往往还没搞…

2026/10/13 14:21:17 阅读更多 →
三月份实习笔记:数据整理、需求梳理与竞品调研的实战复盘

三月份实习笔记:数据整理、需求梳理与竞品调研的实战复盘

1. 三月份实习笔记的缘起与记录逻辑三月份是很多团队一年中节奏切换最明显的节点。春节后的复工潮刚过,年度目标已经拆解到季度,各种项目开始从规划阶段进入实际执行。对于实习生来说,这个时间点进入团队,既赶上了业务最忙碌的窗口…

2026/10/13 14:21:17 阅读更多 →
Tableau标靶图实战:从坐标重构到业务决策穿透

Tableau标靶图实战:从坐标重构到业务决策穿透

1. 标靶图不是炫技,是业务问题的视觉翻译器“手把手教你 Tableau 绘制标靶图(十)”——这个标题里藏着一个被很多人忽略的关键信号:它不是第1次讲,而是第10次。这意味着标靶图在真实业务场景中已被反复验证、持续迭代&…

2026/10/13 14:21:17 阅读更多 →
JVMTI Agent开发避坑指南:从加载失败到生产级稳定

JVMTI Agent开发避坑指南:从加载失败到生产级稳定

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:20:16 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →