前言:一个"疯狂"的想法
2013年,一个澳大利亚程序员 Damien George 做了一件当时很多人觉得不靠谱的事——他想把 Python 塞进单片机里。
不是那种跑 Linux 的树莓派,而是真正的裸金属单片机,RAM 只有几十 KB、Flash 只有几百 KB 的那种。
他在 Kickstarter 上发起了众筹,目标 1.5 万英镑。结果 1931 个人掏了钱,最终筹到了将近 10 万英镑。
这个项目就是 MicroPython。
十多年过去了,MicroPython 在 GitHub 上已经拿到了 21.6K Star,累计 18000+ 次提交,8800+ Fork。它从一个"学术实验"变成了嵌入式领域绕不开的存在——ESP32 官方支持它,树莓派 Pico 出厂就预装它,连乐高和欧洲航天局(ESA)都在用它。
今天这篇文章,我们来认真聊聊这个项目:它到底是什么,怎么实现的,能干什么,适合谁用,以及——作为一个写 C 的嵌入式工程师,你该怎么看待它。
一、MicroPython 到底是个什么东西?
一句话:MicroPython 是一个完整的 Python 3 解释器,专门为微控制器和资源受限的嵌入式系统重写。
注意几个关键词:
"完整的解释器" ——它不是什么"Python转C"的翻译器,也不是简化版的脚本引擎。它包含完整的词法分析器、语法解析器、编译器、字节码虚拟机、运行时系统和垃圾回收器,全部用 C99 从零写成。
"专门为微控制器重写" ——CPython(你电脑上跑的那个 Python)启动就要吃掉几十 MB 内存。MicroPython 能在 256KB Flash + 16KB RAM 的条件下跑起来。当然,如果你给它 512KB Flash + 128KB RAM 以上的配置,体验会好得多。
"Python 3" ——它实现了完整的 Python 3.4 语法,包括异常处理、with语句、yield from、生成器,还加入了 Python 3.5 的 async/await。核心数据类型一个不少:str、bytes、list、dict、set、tuple、类和实例,全都有。
二、它凭什么能在单片机上跑?
把 Python 塞进 192KB RAM 的芯片里,这件事本身就是一项工程壮举。MicroPython 用了大量底层优化技巧,这里挑几个核心的聊一聊:
指针标记(Pointer Tagging)
这是 MicroPython 最精妙的设计之一。在常规的 Python 实现里,哪怕一个小整数 1 也要在堆上分配一个对象。MicroPython 用了指针标记技术——把小整数、短字符串和小对象直接编码在一个机器字(32位或64位)里,根本不需要分配堆内存。
这意味着你做 x = 42 这种操作时,内存开销几乎为零。
30位填充浮点数(30-bit Stuffed Floats)
浮点数通常需要 4 字节甚至 8 字节的堆分配。MicroPython 提供了一种"30位填充浮点"模式,把浮点数直接塞进机器字里,完全不占用堆空间。精度会有所损失,但对大多数传感器数据处理场景足够了。
冻结字节码(Frozen Bytecode)
通过交叉编译器 mpy-cross,你可以把 Python 脚本预编译成字节码,直接"冻结"到固件的 Flash 里。运行时不需要任何 RAM 来存储代码本身(只有代码创建的动态对象才占 RAM)。这个机制让你在 Flash 充裕但 RAM 紧张的芯片上可以塞进很多功能。
紧凑的垃圾回收器
MicroPython 使用了一个简单、快速、健壮的标记-清除垃圾回收器。堆耗尽时抛出 MemoryError,栈溢出时抛出 RuntimeError——行为完全可预测,不会出现那种"不知道死在哪里"的情况。
原生代码发射器(Native Emitter)
除了字节码解释执行,MicroPython 还支持把代码直接编译成目标平台的机器码。对于 ARM Thumb 和 Xtensa 指令集,你甚至可以在 Python 里内联汇编——没错,在 Python 代码里写汇编。
三、支持哪些硬件?覆盖面超乎想象
MicroPython 项目在最新的 v1.27.0 版本中引入了"端口层级(Port Tier)"体系,把支持的硬件平台分成了三个等级。
Tier 1(一级支持,最成熟)
这些是开发最活跃、测试最充分的平台:
- ESP32 全系列:ESP32、ESP32-S2、ESP32-S3、ESP32-C3、ESP32-C6,以及最新的 ESP32-C5 和 ESP32-P4
- STM32 全系列:覆盖 F0、F4、F7、G0、G4、H5、H7、L0、L1、L4、N6、WB、WL,还有最新加入的 STM32U5xx
- RP2040 / RP2350:树莓派 Pico、Pico W 及各种第三方板
- NXP i.MX RT
- SAMD21 / SAMD51(Microchip/Atmel)
- Unix / Windows / macOS(是的,你也可以在电脑上跑 MicroPython,方便开发调试)
Tier 2(二级支持)
- Alif Semiconductor Ensemble(E3、E7)
- Nordic nRF51 / nRF52
- Renesas RA 系列
- WebAssembly
- Zephyr RTOS
Tier 3(社区维护)
固件下载页面列出了超过 50 个硬件厂商的板卡,从 Arduino、Adafruit、SparkFun,到国内熟悉的 WeAct、Waveshare、LILYGO、M5Stack、合宙,覆盖面极广。
四、5 分钟上手:从刷固件到点灯
说再多不如动手试。以最常见的 ESP32 和 Raspberry Pi Pico 为例,看看从零到跑通代码需要几步。
方式一:ESP32
第一步:下载固件
到 MicroPython 官网下载页(micropython.org/download),找到你的板子型号,下载 .bin 固件文件。
第二步:烧录固件
用 esptool.py 烧录。如果你没装过,先 pip install esptool,然后:
# 先擦除esptool.py --port /dev/ttyUSB0 erase_flash# 再烧录esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash 0x1000 firmware.bin
第三步:连接 REPL
用任何串口终端工具(Putty、minicom、Thonny 都行)连上板子,波特率 115200,你就能看到 Python 的 >>> 提示符了。
第四步:点灯!
from machine import Pinled = Pin(2, Pin.OUT)led.on()
就这三行。灯亮了。
方式二:Raspberry Pi Pico
更简单——按住 BOOTSEL 按钮插上 USB,电脑会识别出一个 U 盘,把 .uf2 固件文件拖进去,松手,完事。
打开 Thonny IDE,选择解释器为"MicroPython (Raspberry Pi Pico)",直接在底部 Shell 里敲代码就行。
五、不只是点灯——MicroPython 能做的事
MicroPython 提供了一套完整的硬件抽象库 machine 模块,基本覆盖了你日常需要的所有外设接口:
基础 GPIO 操作
from machine import Pin# 输出led = Pin(2, Pin.OUT)led.toggle()# 输入(带上拉)btn = Pin(0, Pin.IN, Pin.PULL_UP)print(btn.value())
PWM 控制
from machine import Pin, PWMpwm = PWM(Pin(15), freq=1000, duty=512) # 50% 占空比
I2C 通信
from machine import I2C, Pini2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)devices = i2c.scan()print("Found devices:", devices)
SPI 通信
from machine import SPI, Pinspi = SPI(1, baudrate=1000000, polarity=0, phase=0)spi.write(b'\x01\x02\x03')
ADC 采样
from machine import ADCadc = ADC(Pin(34))adc.atten(ADC.ATTN_11DB) # 满量程约 3.3Vprint(adc.read()) # 12-bit: 0~4095
WiFi 联网(ESP32)
import networkwlan = network.WLAN(network.STA_IF)wlan.active(True)wlan.connect('你的WiFi名', '密码')whilenot wlan.isconnected():passprint('IP:', wlan.ifconfig()[0])
异步编程(asyncio)
import asyncioasyncdefblink(pin, interval): led = Pin(pin, Pin.OUT)whileTrue: led.toggle()await asyncio.sleep_ms(interval)asyncdefmain():# 两个灯以不同频率闪烁,互不阻塞 asyncio.create_task(blink(2, 500)) asyncio.create_task(blink(15, 1000))whileTrue:await asyncio.sleep(10)asyncio.run(main())
这个 asyncio 模块是 MicroPython 处理并发的推荐方式——比中断回调和多线程都更安全、更好调试。
六、MicroPython vs C/C++:不是替代,而是分工
这是很多嵌入式工程师最关心的问题,也是最容易引发争论的话题。我们客观来说。
MicroPython 的优势
开发速度碾压级别的快。 写完代码保存,REPL 里直接 import 就能跑,不需要编译、链接、烧录、等待。改一行代码的调试周期从"分钟级"压缩到"秒级"。
交互式调试。 REPL 不只是一个运行入口,它是一个实时的调试工具。你可以在运行时查看任何变量、调用任何函数、扫描 I2C 总线、读取寄存器——所有操作都是即时的。这对硬件调试来说太方便了。
代码可读性。 Python 的可读性优势在团队协作和项目交接时尤为明显。一个实习生看 MicroPython 代码基本能看懂在做什么,但看一段寄存器操作级别的 C 代码就未必了。
跨平台移植。 得益于 HAL 抽象层,同一段 MicroPython 代码可以在 ESP32 和 STM32 之间几乎无缝迁移。
C/C++ 不可替代的场景
极限性能要求。 MicroPython 的执行速度大约是 C 的 1/10 到 1/100(取决于具体操作)。如果你在做高速 ADC 采样、实时电机控制、高帧率信号处理,Python 解释器的开销是不可接受的。
极限资源约束。 MicroPython 本身的固件就要占 256KB~1MB Flash。如果你用的是 Flash 只有 64KB 的小芯片(比如某些 STM32F0、STC8),根本塞不下。
硬实时要求。 垃圾回收器会导致不确定的暂停时间。对于需要微秒级确定性响应的场景(如电机 FOC 控制),这是硬伤。
量产成本敏感。 MicroPython 需要更大 Flash/RAM 的芯片,这在十万级量产时会反映在 BOM 成本上。
最佳实践:混合使用
实际上,很多成熟的项目采用的是混合策略:
- 用 MicroPython 做快速原型验证:验证传感器能不能读到数据、通信协议对不对、算法逻辑有没有问题
- 用 C 做最终产品:在验证通过后,把关键逻辑用 C 重写,追求性能和成本最优
- 或者直接用 MicroPython 的 C 扩展机制:把性能敏感的部分写成 C 模块,其余用 Python 胶水代码粘合
MicroPython 甚至支持内联汇编(目前支持 ARM Thumb 和 Xtensa 指令集),你可以在 Python 代码里直接嵌入汇编函数来处理最关键的热点路径。
七、v1.27.0:最新版本都更新了什么?
MicroPython 最新的稳定版是 2025 年 12 月发布的 v1.27.0,这是一个相当重磅的版本:
新增 ESP32-C5 和 ESP32-P4 支持。 ESP32-P4 是乐鑫最新的高性能芯片,可以独立运行,也可以搭配 ESP32-C5 或 C6 作为无线协处理器。MicroPython 第一时间提供了支持。
新增 STM32U5xx 支持。 STM32U5 是 ST 的超低功耗高性能系列,支持 USB、ADC、DAC、UART、I2C、SPI 和 RTC,适合电池供电的 IoT 应用。
测试套件大幅增强。 超过 590 个测试文件、18500+ 个测试用例,核心代码覆盖率达到 99.2%。这个数字对于一个嵌入式开源项目来说相当惊人。
引入端口层级体系。 明确了各平台的支持等级和维护承诺,让用户在选型时有更清晰的参考。
STM32G4 硬件 I2C、STM32N6 千兆以太网 等一系列具体改进也包含在这个版本中。
八、实战场景:谁在用 MicroPython?
MicroPython 早就不是"玩具"了。来看看几个真实的应用方向:
1. IoT 快速原型
这是 MicroPython 最大的主场。ESP32 + MicroPython + MQTT/HTTP,几十行代码就能做一个温湿度上报节点、一个远程开关控制器、一个简易的智能家居网关。对于验证产品概念(PoC),没有比这更快的方案了。
2. 教育领域
BBC micro:bit 项目让英国数百万中小学生通过 MicroPython 接触编程。树莓派基金会为 Pico 提供了大量 MicroPython 教学资源。Python 语法的低门槛让零基础的学生也能在几分钟内点亮第一颗 LED。
3. 科研与航天
欧洲航天局(ESA)资助了 MicroPython 的开发,因为他们想在太空任务中使用 Python。这不是开玩笑——在快速迭代、灵活可配置的卫星载荷控制场景中,MicroPython 的优势非常明显。
4. 创客与无人机
基于 ESP32-S3 的 pyDrone 项目用 MicroPython 实现飞控、传感器融合和图像处理。通过 Python 脚本就能定制自主飞行行为,大大降低了无人机二次开发的门槛。
5. 商业产品
LEGO 的 Mindstorms EV3 运行 MicroPython。SparkFun 在 2025 年一口气发布了 47 个同时支持 Python 和 MicroPython 的驱动库。Arduino 官方也提供了 MicroPython 固件。这些不是实验性质的尝试,而是面向消费者的正式产品。
九、开发工具生态
工欲善其事,必先利其器。MicroPython 的工具链已经相当成熟:
Thonny IDE ——面向初学者的首选。内置 MicroPython 支持,可以直接通过 USB 连接板卡,一键运行/上传代码,还能浏览板上文件系统。免费,跨平台。
mpremote ——官方命令行工具。文件管理、REPL 连接、固件信息查看、包安装,一个工具搞定。适合喜欢终端操作的老手。
mpy-cross ——交叉编译器。把 .py 编译成 .mpy 字节码文件,减少 RAM 占用,加快加载速度。
WebREPL ——通过 WiFi 连接板子的 REPL,不需要 USB 线。适合板子已经装进外壳或者放在远处的场景。
VS Code + Pymakr / MicroPico 插件 ——如果你是 VS Code 用户,这些插件可以提供代码高亮、自动完成、一键上传等功能。
micropython-lib ——官方维护的扩展库集合,提供了大量 CPython 标准库的 MicroPython 移植版,以及社区贡献的驱动和工具库。
十、入坑指南:几个过来人的建议
如果你决定试试 MicroPython,这里有几条实用建议:
先在电脑上学好 Python 基础。 MicroPython 和 CPython 的语法几乎完全一致。不要一上来就在单片机上学 Python,那样效率很低。先在电脑上把列表、字典、函数、类、异常处理这些基本概念搞清楚,再上手硬件会顺畅很多。
选硬件之前先查驱动。 这是 Wiki 里反复强调的一点。很多初学者先买一堆传感器模块回来,然后发现没有 MicroPython 驱动,只能干瞪眼。正确的做法是:先去 GitHub 搜搜有没有现成的驱动,确认了再买硬件。
并发编程用 asyncio,别急着上中断和多线程。 定时器回调、中断服务、多线程这些听起来很酷,但它们引入的竞态条件和资源冲突问题会让初学者崩溃。MicroPython 官方推荐使用 asyncio 做协作式多任务,安全、可控、好调试。
善用 REPL。 这是 MicroPython 相比 C 最大的体验差距之一。不确定某个 API 怎么用?直接在 REPL 里试。不确定 I2C 设备地址是多少?i2c.scan() 一下就知道了。把 REPL 当作你的实时调试器和文档查询工具。
了解内存限制。 MicroPython 毕竟跑在资源受限的平台上。避免创建大量临时对象,注意字符串拼接的内存开销,必要时用 gc.collect() 手动触发垃圾回收。官方文档有一篇专门讲"受限环境下的编程",建议认真读一遍。
十一、项目信息速查
| |
|---|
| |
| github.com/micropython/micropython |
| |
| |
| |
| |
| |
| ARM Cortex-M, Xtensa, RISC-V, x86, x86-64 |
| |
| 512KB Flash + 128KB RAM 以上 |
| |
| George Robotics, Espressif, Arduino, OpenMV, Planet Innovation |
写在最后
MicroPython 不会取代 C,就像 Python 没有取代 C++ 一样。但它确实改变了嵌入式开发的一部分——让快速验证想法变得更容易,让更多人能参与到硬件开发中来,让那些"想做个小东西但不想写 200 行初始化代码"的场景有了更好的选择。
对于专业的嵌入式工程师来说,MicroPython 是工具箱里的又一把趁手工具。你不一定每天用它,但当你需要快速验证一个传感器、调通一个通信协议、或者给客户做一个 Demo 的时候,它可能会帮你省下好几天的时间。
对于正在学习嵌入式的新人来说,MicroPython 是一个非常友好的入口。先用它理解硬件的工作方式,再去学 C 和寄存器操作,会比直接硬啃手册轻松得多。
21.6K Star,18000 次提交,十年磨一剑。这个项目值得你花时间了解一下。
国内访问 GitHub 有时不稳定,本文项目及固件国内下载链接,公众号后台回复【micropython】或【0034】即可获取。
如果你也在用 MicroPython 做项目,欢迎在评论区分享你的经验——踩过的坑比教程更有价值。