当前位置: 首页 > article >正文

PIO 中的赋值魔术,MOV 指令

前言

      在普通编程语言中,mov 可以理解为“赋值指令”,将一个值从一个地方拷贝到另一个地方。在 RP2040 的 PIO 汇编语言中,mov 同样是数据传递的关键指令,但它操作的是 PIO 独有的几个寄存器。

      在 PIO 中,你可以用 mov 把值从一个寄存器传到另一个寄存器,或者从一个常量设定某个寄存器状态。PIO 的寄存器包括:

  • x、y:通用寄存器

  • osr(Output Shift Register):主控写入 PIO 的数据在这里

  • isr(Input Shift Register):PIO 采集到的数据进入这里

  • pins:GPIO 当前状态(作为输入)

  • pc:程序计数器(一般不用动)

  • null:空目标,丢弃数据用


语法格式

mov <destination>, (op) <source>

参数

含义

destination

目标寄存器,如 x, y, isr, osr

source

来源寄存器或值,如 x, y, pins, osr, null

op(可选)

求反(按位求补),反转比特顺序

用法示例

1. 把 x 的值给 y:

mov(y, x)

用途:x 计数器计算完毕后,把值传给 y 用于下一步处理。

2. 从主控写入的 osr 中取值放到 x 中:

mov(x, osr)

用途:主控通过 .put() 写入一个值,PIO 用这个指令加载进 x。

注意:这条指令默认是阻塞的,如果 osr 没准备好,会停在这里等待。

3. 将当前引脚状态读到 isr 中:

mov(isr, pins)

用途:一次读取所有输入引脚状态(适用于并口采集等并发场景)

4. 把某个值清空:

mov(x, null)

用途:清空某个寄存器(实际作用是丢弃)

5. 将寄存器取反再传递(适用于补码或反相逻辑):

mov(x, invert(x))

用途:对信号进行反向处理,比如 PWM 输出反向控制

代码示例

from machine import Pin
from rp2 import StateMachine
import time# PIO 程序:取反 OSR 的值,送入 X 寄存器,再写入 ISR 推送出去
@rp2.asm_pio()
def not_example():pull(block)         # 从主控获取数据mov(x, osr)         # 把 osr 的值放入 xmov(x, invert(x))    # 对 x 按位取反mov(isr, x)         # 将 x 放入 isrpush(block)         # 推送 isr 值# 创建状态机
sm = StateMachine(0, not_example, freq=2000)
sm.active(1)# 发送一个测试值,比如 0xAAAAAAAA(101010...)
input_val = 0xAAAAAAAA
sm.put(input_val)
time.sleep(0.01)
result = sm.get()print(f"输入值: 0x{input_val:08X}")
print(f"取反后: 0x{result:08X}")

程序输出

输入值: 0xAAAAAAAA
取反后: 0x55555555


与 set 的区别

指令

特点

用途

set

设置一个寄存器为常量(立即数)

初始化常量,如 set x, 10

mov

寄存器间或从特殊寄存器传值

动态传值,如 mov x, osr

结论:

  • set:态赋值

  • mov:态传递


总结

       mov 在 PIO 中的意义远超简单的“赋值”,它是串起主控与状态机之间沟通的桥梁,是 PIO 灵活处理控制逻辑的核心指令之一。

掌握了 mov,你就能玩转:

  • 主控数据驱动 PIO(如动态 PWM、协议适配)

  • 多寄存器交互(如延时、复位、反向处理)

  • 多状态机协同(配合 irq 与 mov isr/pins)

注:

  • 测试PC(Program Counter)这个,始终返回的是0,我用的micropython是1.24版,据查询资料,可能是官方为了性能等原因考虑,没有提供该功能(pico提供,micropython未实现),未验证。

http://www.lryc.cn/news/2385459.html

相关文章:

  • [docker]更新容器中镜像版本
  • 第十七次CCF-CSP算法(含C++源码)
  • 打造一个支持MySQL查询的MCP同步插件:Java实现
  • 黑马k8s(十五)
  • Axure项目实战:智慧运输平台后台管理端-订单管理1(多级交互)
  • 解决 cursor 中不能进入 conda 虚拟环境
  • 微信小程序请求扣子(coze)api的例子
  • C++ 实现二叉树的后序遍历与中序遍历构建及层次遍历输出
  • 基于大模型的髋关节骨关节炎预测与治疗方案研究报告
  • qiankun解决的问题
  • JavaScript从入门到精通(一)
  • 快速失败(fail-fast)和安全失败(fail-safe)的区别
  • 虚拟环境中的PyQt5 Pycharm设置参考
  • AI 笔记 - 模型优化 - 注意力机制在目标检测上的使用
  • AUTOSAR图解==>AUTOSAR_SRS_LIN
  • UML 时序图 使用案例
  • 华为昇腾使用ollama本地部署DeepSeek大模型
  • 多态的总结
  • Windows 高分辨率屏幕适配指南:解决界面过小、模糊错位问题
  • tvalid寄存器的理解
  • C++八股 —— 手撕定时器
  • K8S-statefulset-mysql-ha
  • 【方案分享】展厅智能讲解:基于BLE蓝牙Beacon的自动讲解触发技术实现
  • web常见的攻击方式有哪些?如何防御?
  • 力扣:《螺旋矩阵》系列题目
  • 发电厂进阶,modbus TCP转ethernet ip网关如何赋能能源行业
  • 深入了解linux系统—— 操作系统的路径缓冲与链接机制
  • Ansible快速入门指南
  • 华为2025年校招笔试真题手撕教程(一)
  • 第9.2讲、Tiny Decoder(带 Mask)详解与实战