使用 Arduino IDE 开发 STM32 完整教程前言STM32 系列单片机性能强劲，但传统开发方式配置复杂、门槛较高。借助 Arduino_Core_STM32 项目，我们可以在 Arduino IDE 中轻松开发 STM32 程序，既能享受 Arduino 简洁的编程体验，又能使用 STM32 的强大性能和丰富的 Arduino 库资源。本教程将详细介绍从环境配置到程序下载的完整流程。一、Arduino_Core_STM32 简介1.1 什么是 Arduino_Core_STM32Arduino_Core_STM32 是 ST 官方推出的 STM32 Arduino 核心支持包，通过将 STM32 官方 HAL 库进行封装，使其能够适配 Arduino 开发框架。GitHub 地址: https://github.com/stm32duino/Arduino_Core_STM32支持范围: 涵盖 STM32 多个系列（F0/F1/F3/F4/F7/G0/G4/H7/L0/L4/L5 等）STM32 支持系列1.2 与其他固件的区别网上流传的另一款固件 Arduino_STM32( GitHub: https://github.com/rogerclarkmelbourne/Arduino_STM32 )仅支持 F1 和 F4 系列，且已不再维护。强烈建议使用官方的 Arduino_Core_STM32。二、环境搭建2.1 安装 Arduino IDE首先从官网下载并安装 Arduino IDE（本教程基于 2.x 版本）：https://www.arduino.cc/en/software2.2 添加 STM32 开发板支持方法一：在线安装（推荐网络条件好的用户）打开 Arduino IDE，进入 文件 → 首选项在 其他开发板管理器地址 栏中添加以下 URL：https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json如果同时使用其他开发板，多个地址之间用英文逗号分隔。首选项设置打开 工具 → 开发板 → 开发板管理器开发板管理器入口搜索 STM32 MCU based boards，找到 STM32 MCU based boards by STMicroelectronics，点击安装搜索 STM32安装 STM32 包方法二：离线安装（推荐国内用户）由于网络原因，在线下载可能失败，可采用离线安装方式：步骤 1：下载 JSON 配置文件访问 https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json将文件保存到 C:\Users\用户名\AppData\Local\Arduino15 目录（将"用户名"替换为你的 Windows 用户名）步骤 2：下载必要的支持包根据 JSON 文件中的链接，下载以下 5 个文件：组件下载链接STM32 核心https://github.com/stm32duino/Arduino_Core_STM32/releases/download/2.7.1/STM32-2.7.1.tar.bz2ARM GCC 编译器https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v12.2.1-1.2/xpack-arm-none-eabi-gcc-12.2.1-1.2-win32-x64.zipOpenOCD 调试工具https://github.com/xpack-dev-tools/openocd-xpack/releases/download/v0.12.0-1/xpack-openocd-0.12.0-1-win32-x64.zipCMSIShttps://github.com/stm32duino/ArduinoModule-CMSIS/releases/download/5.7.0/CMSIS-5.7.0.tar.bz2STM32Toolshttps://github.com/stm32duino/Arduino_Tools/releases/download/2.2.1/STM32Tools-2.2.1-windows.tar.bz2提示: 如果 GitHub 访问困难，可使用镜像站点下载。步骤 3：放置支持包文件将下载的 5 个文件放入 C:\Users\用户名\AppData\Local\Arduino15\staging\packages 目录支持包文件位置步骤 4：完成安装在 Arduino IDE 首选项中添加开发板管理器地址（同方法一）打开开发板管理器，搜索 stm32找到 STM32 MCU based boards 并安装三、下载工具配置3.1 安装 STM32CubeProgrammer如需使用 ST-Link 或串口下载程序，需要安装 ST 官方编程工具：下载地址: https://www.st.com/zh/development-tools/stm32cubeprog.html#get-software安装完成后，将安装路径添加到系统 PATH 环境变量中添加环境变量3.2 安装 ST-Link 驱动驱动下载地址: https://www.st.com/zh/development-tools/st-link-v2.html#tools-software下载后安装即可ST-Link 驱动下载四、编写示例程序以下是一个简单的 LED 闪烁程序，控制 PC13 引脚连接的 LED（多数 STM32 最小系统板载 LED 连接此引脚）：void setup() { pinMode(PC13, OUTPUT); } void loop() { digitalWrite(PC13, HIGH); delay(1000); digitalWrite(PC13, LOW); delay(1000); }五、程序下载5.1 开发板选择在 Arduino IDE 中选择对应的开发板型号：工具 → 开发板 → STM32 MCU based boards选择与你的芯片匹配的开发板（如 Generic STM32F1 series → STM32F103C8T6）选择开发板系列选择具体型号5.2 使用 ST-Link 下载（推荐）硬件连接STM32ST-Link V23V33.3VSWIOSWDIOSWCLKSWCLKGNDGNDST-Link V2ST-Link 接线配置步骤BOOT 跳线设置: BOOT0 和 BOOT1 均接 0（默认位置）BOOT 跳线设置为 0下载方式选择: 工具 → Upload method → STLink选择 STLink 下载方式编译上传: 按 Ctrl + U 或点击上传按钮上传按钮5.3 使用串口下载硬件连接由于 STM32 最小系统板通常不带串口芯片（Micro-USB 口仅用于供电），需使用 USB 转串口模块：STM32USB 转串口模块3V33.3VTXRXRXTXGNDGND注意: 部分开发板 TX/RX 引脚为 A9/A10，请根据实际板型确认USB 转串口模块配置步骤BOOT 跳线设置: BOOT0 接 1，BOOT1 接 0复位操作: 接线完成后，手动按下复位键下载方式选择: 工具 → Upload method → Serial选择 Serial 下载方式选择串口号: 工具 → 端口 → 选择对应的 COM 口编译上传: 按 Ctrl + U 或点击上传按钮六、常见问题6.1 GitHub 访问问题如无法访问 GitHub，可使用镜像站点下载资源。6.2 驱动安装问题如设备管理器中无法识别 ST-Link 或串口设备，请检查驱动是否正确安装。6.3 上传失败检查 BOOT 跳线设置是否正确尝试按下复位键后重新上传确认开发板型号选择正确七、引脚定义参考不同型号 STM32 的引脚定义有所不同，可在 Arduino_Core_STM32 的文档中查询：https://github.com/stm32duino/Arduino_Core_STM32/tree/master/docs常用引脚类型：数字引脚: PA0~PA15, PB0~PB15, PC0~PC15 等模拟引脚: A0~A15（部分型号）特殊功能引脚: TX/RX(Serial), SDA/SCL(I2C), MOSI/MISO/SCK(SPI) 等参考资料Arduino_Core_STM32 官方仓库：https://github.com/stm32duino/Arduino_Core_STM32官方 Wiki：https://github.com/stm32duino/Arduino_Core_STM32/wikiSTM32CubeProgrammer 下载：https://www.st.com/zh/development-tools/stm32cubeprog.html祝你开发顺利！
之前基于树莓派RP2350设计过一个方块碰撞的游戏，支持物理按键控制，得益于ESP32的加持，可玩性更强了。于是，一个支持物理按键 + 手机Web双重控制的方块躲避小游戏就诞生了！这玩意儿最骚的操作是，你既可以像传统游戏机一样，用两个物理按键“哒哒哒”地玩；也可以掏出手机，连!上它自己发的WiFi，在网页上点点点来控制。甚至还能显示DHT11传上来的实时温湿度，假装自己很高端。视频展示: https://www.bilibili.com/video/BV1p14vzXEVL/接线图ESP32开发板 x 1DHT11温湿度传感器 x 10.96寸OLED小屏 x 1按键 x 2面包板、杜邦线若干接线图我就直接用文字版了，一目了然：ESP32 → 外设 --------------------- GPIO26 → DHT11数据脚 GPIO9 → OLED SDA GPIO10 → OLED SCL GPIO27 → 左按键 GPIO28 → 右按键 3.3V/GND → 共用电源折腾的重点：Web控制是怎样炼成的这部分是整个项目最有趣的地方。过程很简单：ESP32通电后会自己建一个名叫 SUROY_AP 的WiFi热点 (密码: 88888888)。手机连上这个WiFi。打开浏览器，访问OLED屏幕上显示的IP地址（通常是 192.168.4.1）。Duang！一个控制界面就出来了。为了让这个界面在手机上不那么丑，我还特地手搓了一点响应式CSS，背景还带个渐变，聊胜于无嘛，哈哈。分数、温湿度都能在网页上实时刷新，科技感（廉价感）这不就上来了吗？聊聊技术实现和踩过的坑写代码的过程还算顺利，但坑嘛，肯定是有的，不然还叫什么DIY！大坑一：游戏卡成PPT！一开始天真了，以为直接让ESP32等着网络请求就行，结果游戏逻辑和网络服务打架，一有人连WiFi，游戏就卡得像PPT。解决方案：把网络服务改成非阻塞模式。简单说就是，有人连接我才理你，没人连接我就专心跑游戏，互不耽误。为了更直观地展示这个双控制流程，我画了个简单的图：大坑二：手机点太快，ESP32反应不过来网页上快速连点“左”,“右”，命令发得太快，ESP32处理不过来就容易丢命令，导致操作失误。解决方案：搞了个简单的命令队列 (就是上图那个流程)。Web发来的命令不直接执行，先扔进一个队列里，游戏主循环再按顺序一个个取出来处理，稳得一批。还有些小坑：比如MicroPython自带的JSON库有时候不太听话，最后干脆自己拼字符串了；不同手机浏览器千奇百怪，调CSS兼容性调到头秃……不说了，都是泪。玩起来咋样？主观体验！物理按键：没得说，指哪打哪，延迟超低，有种玩小霸王的感觉。清脆的按键声，是硬核玩家的浪漫！Web控制：方便是真方便，躺在床上就能玩。延迟肯定比物理按键高一点（毕竟隔着WiFi），大概50-100ms，但玩这种小游戏完全足够了。混合模式：最逗的是可以俩人一起玩，一人按键一人搓手机，看谁先把谁坑死，哈哈！聚会时绝对是个整活小能手。下一步还想怎么折腾？目前还只是个V1.0的玩具，脑子里已经有一堆想加的功能了：加个蜂鸣器，搞点BGM和音效搞个难度选择，越往后方块掉越快断电也能保存最高分的排行榜(终极梦想) 联机对战！总结一下“物联网”——它不只是让设备连个网那么简单，而是能把硬件的即时反馈和软件的灵活交互真正融合起来，创造出很多新奇的玩法。用MicroPython开发效率是真的高，从有想法到实现，一个周末足矣。对于想学习ESP32开发的朋友来说，这是个很好的入门项目。对于老手来说，这个双控制模式的思路也许能给你一些启发。开源地址: https://github.com/zsuroy/iblock-dodge-esp32代码已经整理好，放上来了，注释写得应该还算清楚，欢迎各位大佬围观、Star、Fork三连！本文同步更新到 DFRobot 社区。
引言月初，收到了DFRobot的新产品 FireBeetle2-ESP32-C5 开发板，ESP32系列在开发者社区中有着广泛的应用，这是一款基于ESP32-C5芯片的高性能物联网开发板，可玩性极高，本文将探讨在MicroPython环境下的智能配网实现，在此抛砖引玉。开箱啦这块板子延续DFRobot的设计风格，很是精美，还配套了扩展IO板。参数信息：主频高达240MHz的RISC-V单核处理器384KB SRAM + 320KB ROM + 4MB Flash支持2.4GHz和5GHz双频Wi-Fi 6，乐鑫首款双频Wi-Fi 6芯片，速率最高可达150Mbps支持Type-C、5V DC及太阳能充电，集成电池电量监测和3.3V可控电源输出、低功耗蓝牙协议：Bluetooth 5、Bluetooth mesh，速率最高可达2 MbpsIO资源数字I/O x18LED PWM 控制器 6个通道SPI x1UART x3 (LP UART x1)I2C x2 (LP I2Cx1)I2S x1红外收发器：发送通道 x5、接收通道 x51x 12 位 SAR ADC， 7个通道DMA 控制器，3个接收通道和3个发送通道详细参数可以查看官方WIKI: https://wiki.dfrobot.com.cn/SKU_DFR1236_Firebeetle_2_ESP32_C5_Development_Board_IO_Expansion_Kit环境搭建笔者所用设备及工具如下设备: MacBook Air M3 - MacOS 15.6.1 (24G90)工具: PyCharm Pro + Tabby环境: MicroPython + esptool使用官方 esptool 工具，该工具基于 Python 开发，需要具备 Python 开发环境。尤其需要注意的是本次评测的开发板ECO1，正式量产版本的是ECO2，因此烧录工具版本号最大支持esptool.py<=4.9.dev8，别问我为什么知道。固件下载地址: https://wiki.dfrobot.com.cn/ESP32_MicroPython_Usage_Tutorial注：烧录时建议从扩展板取下。# 创建项目路径 mkdir suroy/wifi_manager # 创建虚拟环境 (python版本需要>=3.7) python3 -m venv venv # 激活环境 source venv/bin/activate # 安装依赖项 pip install # 擦出flash esptool.py erase_flash # 烧录固件(记得修改设备名和文件路径) # 串口设备名: /dev/cu.usbmodem101 # 固件文件路径: firmware_eco1.bin esptool.py --chip esp32c5 -p /dev/cu.usbmodem101 -b 460800 --before default_reset --after hard_reset write_flash --flash_mode dio --flash_size 4MB --flash_freq 80m --erase-all 0x2000 firmware_eco1.bin WI-FI配网实现设计思路传统的物联网设备WiFi配网通常有以下几种方式：硬编码配网：直接在代码中写入WiFi信息Serial配网：通过串口命令行配置SmartConfig：通过手机APP发送WiFi信息AP配网：设备创建热点，用户连接后配置我选择实现AP配网方案，因为它用户体验好，不需要额外APP，且代码实现相对简单。主要工作流程一键配网流程首次使用：设备自动进入AP模式手机连接：连接到 SOUROY_AP 热点（密码：88888888）访问配置页：浏览器访问 http://192.168.4.1选择WiFi：从下拉列表选择要连接的网络输入密码：输入WiFi密码完成配网：设备自动保存配置并连接注：若无响应，建议直接 reset 重试快速应用到项目开源地址: https://github.com/zsuroy/smartlink-mp获取并上传驱动# 克隆仓库 git clone https://github.com/zsuroy/smartlink-mp # 上传仓库中的 wifi_manager.py 文件到 esp32编写入口import time from machine import Pin # ====WI-FI 配网==== from wifi_manager import WiFiManager wm = WiFiManager("SUROY_AP", "88888888") # 初始Wi-Fi热点配置 if not wm.connect(): led.off() print("配网完成...") # ====WI-FI 配网==== while True: led.on() time.sleep(0.5) led.off() time.sleep(0.5)使用简单，仅需要 # ====WI-FI 配网==== 中的代码即可。总结智能配网方案常见于Arduino和基于IDF开发的版本，而本文基于MicroPython实现了一套轻量级易于集成的方案，解决了IoT开发中的一大痛点，但说实话，这只是打开了第一道门，后续还可以有许多的改进方面，在此抛砖引玉，给各位大佬足够的发挥空间。
各位Maker朋友们，大家好！今天给大家分享一个我最近在Beetle-RP2350上捣鼓出来的小玩意儿——一个简单却充满复古情怀的方块躲避游戏。借助RP2350的强大性能和灵活的IO，再配上一块小巧的OLED屏幕，随时随地都能体验一把掌上游戏的乐趣！硬件连接这次用到的硬件很简单：RP2350开发板0.96寸OLED屏幕(SSD1306)：小巧精致，用来显示游戏画面刚刚好。两个按键：控制玩家左右移动，手感清脆。温湿度传感器 (DHT11，可选)：顺手加了个环境信息显示，纯属Bonus连接方式如下，一看就明白：GP5 ---- SCL(OLED)GP4 ---- SDA(OLED)GP9 ---- K1(左)GP26 --- K2(右)GP8 ---- Data (DHT11)温馨提示：所有模块都采用3.3V供电。⚡按键另一端接地，代码里启用了内部上拉电阻，省去了外部电阻的麻烦。软件实现基于MicroPython进行开发，丰富的库支持让开发过程非常顺畅。主要实现了以下功能：玩家控制：通过两个按键控制屏幕底部小方块的左右移动。障碍物生成与移动：从屏幕顶部随机生成方块并向下移动，速度可控。碰撞检测：实时检测玩家是否与下落的障碍物发生碰撞。得分系统：成功躲避一个障碍物，得分+1。游戏结束与重置：碰撞后游戏结束，显示最终得分，等待一段时间后自动重置。 Game Over!OLED屏幕显示：清晰地显示游戏画面、得分以及（可选的）温湿度信息。代码我就不在这里赘述了，已经整理好放在附件里了，大家可以直接下载到Beetle-RP2350上运行体验 里面有详细的注释，方便大家理解和修改。仓库地址: https://github.com/zsuroy/block-dodge-rp2350效果展示B站: 基于RP2350的MicroPython方块小游戏：在指尖舞动像素未来展望这只是个非常基础的版本，未来还有很多可以扩展的地方：更丰富的障碍物类型：大小不一、速度各异，甚至会突然转向的障碍物，增加挑战性。不同的游戏模式：例如加速模式、限时模式等等，带来更多样的玩法。音效支持：加入简单的音效，比如碰撞时的“Duang”，得分时的“叮”，让游戏更有代入感。排行榜功能：如果能联网，搞个本地或者在线排行榜，看看谁是真正的躲避高手！希望这个小项目能给大家带来一些灵感，也欢迎各位大佬一起交流完善，提出宝贵的意见和建议，让我们一起让这个小游戏变得更有趣！
引言近期有幸体验了DFRobot推出的Beetle-RP2350微型开发板，这款仅硬币大小的开发板给我留下了深刻印象。作为一款基于树莓派RP2350微控制器的产品，它拥有以下核心特性：双核双架构，Arm Cortex-M33或Hazard3 RISC-V内核150MHz主频，520KB RAM，2MB flash。浏览了一下社区中关于Arduino生态的内容较为丰富，但出于对MicroPython的偏好，我决定采用MicroPython作为开发环境。本文将介绍在MacOS系统下搭建开发环境的完整过程，并通过基准测试其性能表现。前期准备开发环境如下系统: MacOS Catalina 10.15.7IDE: PyCharm Pro + MicroPython + Tabby(终端工具)硬件: Beetle-RP2350相关资料官方资料: https://www.raspberrypi.com/documentation/microcontrollers/silicon.html#rp2350固件地址:https://micropython.org/download/?mcu=rp2350https://micropython.org/download/RPI_PICO2/MicroPython 教程地址: https://docs.micropython.org/en/latest/rp2/quickref.html环境搭建根据 MicroPython 官方文档指导，可以将RP2350连上USB进入大容量设备模式（类似于U盘），将下载好的固件( RPI_PICO2-20250415-v1.25.0.uf2)拷贝进去即烧录成功自动重启。进入大容量模式：按住 BOOT 不放 + 点按 RST拖动拷贝固件到 RP2350 盘符，完成之后会自动弹出该盘符按下 RST 复位上机测试点灯测试from machine import Pin import time LED = Pin(25, Pin.OUT) while True: LED.on() time.sleep(1) LED.off() time.sleep(1)跑分测试摘录了以下RP2350和RP2040的性能表格，但是实际我这边测试出来与给出有点出入，仅供参考，建议以C/C++进行基准测试。测试涵盖：基础运算性能（整数/浮点）复杂算法处理（Mandelbrot集计算）高精度计算（π值计算）BenchMark: https://github.com/shaoziyang/micropython_benchmarks注: 时间单位ms, 越小则性能越好。BenchMark:''' Simple benchmark for micropython and circuitpython. Compare the performance of different MCUs by performing operations such as addition, multiplication, exponentiation, complex numbers, and pi. ''' import sys import gc try: from time import ticks_ms, ticks_diff import machine TEST_ENV = 'micropython' def freq(): try: f = machine.freq() // 1000000 except: f = machine.freq()[0] // 1000000 return f except: from time import monotonic_ns def ticks_ms(): return monotonic_ns() // 1000000 def ticks_diff(T2, T1): return T2 - T1 try: import board TEST_ENV = 'circuitpython' import microcontroller def freq(): return microcontroller.cpu.frequency // 1000000 except: TEST_ENV = 'OTHER' try: import psutil def freq(): return psutil.cpu_freq().max except: def freq(): return 'unknow' def memory(): try: r = gc.mem_free() + gc.mem_alloc() except: try: r = psutil.virtual_memory().total except: r = 'unkonw' return r PLATFORM = sys.platform VERSION = sys.version FREQ = freq() MEMORY = memory() def run_test(func, *param): gc.collect() try: t1 = ticks_ms() if param == None: func() else: func(*param) t2 = ticks_ms() dt = ticks_diff(t2, t1) print('Calculation time:', dt, 'ms\n') return dt except: print('Error occurred during operation!') def mandelbrot_test(p): iter = p[0] def in_set(c): z = 0 for i in range(iter): z = z * z + c if abs(z) > 4: return False return True r = '' for v in range(31): for u in range(81): if in_set((u / 30 - 2) + (v / 15 - 1) * 1j): r += ' ' else: r += '#' r += '\n' if len(p) > 1 and p[1]: print(r) def pi_test(p): iter = p[0] extra = 8 one = 10 ** (iter + extra) t, c, n, na, d, da = 3 * one, 3 * one, 1, 0, 0, 24 while t > 1: n, na, d, da = n + na, na + 8, d + da, da + 32 t = t * n // d c += t return c // (10 ** extra) def add_test(p): for i in range(p[0]): C = p[1] + p[2] def mul_test(p): for i in range(p[0]): C = p[1] * p[2] def div_test(p): for i in range(p[0]): C = p[1] / p[2] def pow_test(p): for i in range(p[0]): C = p[1] ** p[2] INT_ADD_TEST_LIST = ('Integer addition {} times', add_test, [12345678, 56781234], 10000, 100000, 1000000) INT_MUL_TEST_LIST = ('Integer multiplication {} times', mul_test, [12345678, 56781234], 10000, 100000, 1000000) INT_DIV_TEST_LIST = ('Integer division {} times', div_test, [99999991, 45481], 10000, 100000, 1000000) FLOAT_ADD_TEST_LIST = ('Float addition {} times', add_test, [12345678.1234, 56781234.5678], 10000, 100000, 1000000) FLOAT_MUL_TEST_LIST = ( 'Float multiplication {} times', mul_test, [12345678.1234, 56781234.5678], 10000, 100000, 1000000) FLOAT_DIV_TEST_LIST = ('Float division {} times', div_test, [99999991.2345, 45481.1357], 10000, 100000, 1000000) POWER_TEST_LIST = ('Power calculation {} times', pow_test, [1234.5678, 2.3456], 10000, 100000, 1000000) MAND_TEST_LIST = ('Mandelbrot iterating {} times', mandelbrot_test, [], 100, 500, 5000) PI_TEST_LIST = ('Pi Calculation {} bits', pi_test, [], 1000, 5000, 10000, 100000, 200000) TEST_LIST = ( INT_ADD_TEST_LIST, INT_MUL_TEST_LIST, INT_DIV_TEST_LIST, FLOAT_ADD_TEST_LIST, FLOAT_MUL_TEST_LIST, FLOAT_DIV_TEST_LIST, POWER_TEST_LIST, MAND_TEST_LIST, PI_TEST_LIST ) tr = [] def run(): global tr for TEST in TEST_LIST: for item in TEST: if type(item) == int: print(TEST[0].format(item)) p = TEST[2].copy() p.insert(0, item) r = run_test(TEST[1], p) tr.append([TEST[0].format(item), str(r)]) def print_result(): r1 = '| item | Platform | Version | Frequency | Memory |' r2 = '| - | - | - | - | - |' r3 = '| {} | {} | {} | {} | {} |'.format('result', PLATFORM, VERSION, FREQ, MEMORY) for i in range(len(tr)): r1 += ' {} |'.format(tr[i][0]) r2 += ' - |' r3 += ' {} |'.format(tr[i][8]) print(r1) print(r2) print(r3) ############################################################################### print('\n\n') print('##############') print('# Begin test #') print('##############') print('\nEnvironment:', TEST_ENV) print('Platform:', PLATFORM) print('Version:', VERSION) print('Frequency:', FREQ) print('Memory:', MEMORY) print() run() print('\nTest finished.') print('==============') print_result()串口运行结果日志:Calculation time: 4259 ms Integer multiplication 10000 times Calculation time: 161 ms Integer multiplication 100000 times Calculation time: 1628 ms Integer multiplication 1000000 times Calculation time: 16284 ms Integer division 10000 times Calculation time: 62 ms Integer division 100000 times Calculation time: 639 ms Integer division 1000000 times Calculation time: 6400 ms Float addition 10000 times Calculation time: 69 ms Float addition 100000 times Calculation time: 708 ms Float addition 1000000 times Calculation time: 7094 ms Float multiplication 10000 times Calculation time: 70 ms Float multiplication 100000 times Calculation time: 710 ms Float multiplication 1000000 times Calculation time: 7108 ms Float division 10000 times Calculation time: 71 ms Float division 100000 times Calculation time: 720 ms Float division 1000000 times Calculation time: 7208 ms Power calculation 10000 times Calculation time: 116 ms Power calculation 100000 times Calculation time: 1174 ms Power calculation 1000000 times Calculation time: 11755 ms Mandelbrot iterating 100 times Calculation time: 2608 ms Mandelbrot iterating 500 times Calculation time: 9103 ms Mandelbrot iterating 5000 times Calculation time: 81708 ms Pi Calculation 1000 bits Calculation time: 349 ms Pi Calculation 5000 bits Calculation time: 21192 ms Pi Calculation 10000 bits Calculation time: 58155 ms Pi Calculation 100000 bits跑分结论大致如下：CircuitPython(适用于大多数场景): 浮点运算速度快、内存占用低，运行复杂算法（如分形、高精度计算），推荐科学计算、图形渲染等场景。MicroPython: 整数运算速度快（如嵌入式控制、传感器数据处理），短任务响应更敏感（如快速初始化）。尾言通过本次完整的开发体验，Beetle-RP2350展现出了优异的性能表现和开发便利性。其双核架构在保持低功耗的同时，提供了显著的性能提升。MicroPython生态的成熟度也使得快速原型开发成为可能。对于嵌入式开发者而言，这款开发板在物联网终端、智能控制等领域都具有广阔的应用前景。后续计划：将进行环境监测系统实验，欢迎关注项目更新。题外话本文同步更新DFRobot社区: https://mc.dfrobot.com.cn/thread-325015-1-1.html#pid609120
正值摸鱼之际，收到邀约参与CSDN香橙派开发板评测活动。开箱啦前期准备● Device: MacbookAir 2017● OS: MacOS 10.15.7 Catalina● Board: OrangePi AiPro● Tools: Tabby, PyCharm Pro, Safari，Chrome● Others:○ RGB LED ○ Camera: USB 720P(with mic) ○ Micro USB 数据线 ○ [OrangePi_AI_Pro_昇腾_用户手册_v0.3.1.pdf](http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-AIpro.html) 概览OrangePi AIpro(8T)采用昇腾AI技术路线，可广泛适用于AI边缘计算、深度视觉学习及视频流AI分析、视频图像分析、自然语言处理、智能小车、机械臂、人工智能、无人机、云计算、AR/VR、智能安防、智能家居等领域，覆盖 AIoT各个行业。Orange Pi AIpro支持Ubuntu、openEuler操作系统，满足大多数AI算法原型验证、推理应用开发的需求。 CPU4核64位处理器+ AI处理器(8TOPS算力)GPU集成图形处理器内存LPDDR4X：8GB，速率：3200Mbps存储• SPI FLASH：32MB• SATA/NVME SSD（M.2接口2280）• eMMC插槽：32GB/64GB/128GB/256GB（可选），eMMC5.1 HS400• TF插槽WIFI+蓝牙Wi-Fi 5双频2.4G和5GBT4.2/BLE以太网收发器10/100/1000Mbps以太网显示• 2xHDMI2.0 Type-A TX 4K@60FPS• 1x2 lane MIPI DSI via FPC connector摄像头2x2-lane MIPI CSI camera interface，兼容树莓派摄像头USB• USB 3.0 HOST x2• USB Type-C 3.0 HOST x1• Micro USB x1 串口打印功能音频3.5mm耳机孔音频输入/输出40PIN40PIN 功能扩展接口，支持以下接口类型：GPIO、UART、I2C、SPI、 I2S、PWM支持的操作系统Ubuntu、openEuler登录香橙派离线串口登录便携屏借给师弟打ROS玩坏了，于是本文启动采用串口，登录之后连接WIFI，此后即可通过SSH连接。1. 安装沁恒的CH340驱动（之前测评过沁恒CH32系开发板，确实不错），注意根据自己系统下载，我是Mac，安装完毕之后建议重启电脑。2. 将MicroUSB接口与香橙派相连（可参考文档2.9.1）3. 取下所有连接的负载（特别是USB相关的），若不取下可能会导致串口收发数据异常，导致首次登录帐号密码始终输入不正确，这是作者接入USBCamera的教训。4. 打开串口调试工具，使用TTY模式连接串口，在此作者使用 Tabby 进行连接，波特率为115200。Tabby is an infinitely customizable cross-platform terminal app for local shells, serial, SSH and Telnet connections。用户名：HwHiAiUser 密码：Mind@123注意：首次登录无法直接使用root帐号登录。5. 连接WIFI详细步骤参考用户手册3.5.2小节，可以自行配置静态IP，若需公网访问请移步IPV6，DDNS，内网穿透（FRP）等资料。# 搜索热点 nmcli dev wifi # 连接 sudo nmcli dev wifi connect Suroy_5G password uguess # 查看IP地址 ip addr show wland0联网SSH登录使用 Tabby 根据串口调试获取到的IP地址连接即可，后文的测试均是通过SSH连接进行。简单功能体验USB摄像头使用 fswebcam 测试 USB 摄像头sudo fswebcam -d /dev/video0 --no-banner -r 1280x720 -S 5 ./image.jpg命令参数说明：a) -d 选项用于指定 USB 摄像头的设备节点b) --no-banner 用于去除照片的水印c) -r 选项用于指定照片的分辨率d) -S 选项用设置于跳过前面的帧数e) ./image.jpg 用于设置生成的照片的名字和路径使用 Python 自带的 HTTP 服务器查看照片。python -m http.serverGPIO功能出厂镜像中已经预装了gpio_operate 工具用于设置 GPIO 管脚的输入与输出方向，也可将每个GPIO 管脚独立的设为 0 或 1。通过 gpio_operate -h 命令可以查看帮助，特别注意的是gpio_operate 工具必须使用 root 帐号执行。短接 SPI0 的 mosi 和 miso 两个引脚，运行 spidev_test 的输出结果如 下所示，可以看到TX 和 RX 的数据一致，自收自发测试成功，后续尝试一下ST7735的移植。SPI0的引脚图如下：AI模型推理体验启动Jupyter LabJupyter Lab 软件是一个基于 web 的交互式开发环境，集成了代码编辑器、终端、文件管理器等功能，使得开发者可以在一个界面中完成各种任务。开发团队提供有9个AI 应用样例，并调用了 Python 版本的AscendCL 编程接口实现。cd /home/HwHiAiUser/samples/notebooks/ # 注意切到root 用户先 ./start_notebook.sh在 Jupyter Lab 中双击打开样例的main.ipynb，在右侧窗口中会显示 main.ipynb 文件中的内容，随后点击运行即可看到结果。漫画风照片转换可以看到其实CPU占用并不高，即使在做AI运算时也只有百分之几的占有率。OCR文字识别OCR文字识别声音识别应用开发实践基于香橙派的在线命令执行器(OPiOnCmder)一番体验下来，发现目前官方的硬件资料并不齐全，因此我花了一些时间做了这个项目。设计宗旨：解决香橙派硬件资源操作不便的问题 -- 通过Flask搭建WEB控制端实现硬件接口。开源地址: https://github.com/zsuroy/OPiOnCmder技术架构: Flask功能说明: 目前支持调节风伞转速及GPIO控制，其他的硬件功能先欢迎Fork，PR共同助力生态建设～开发工具● Pycharm Professional● MacOS 10.15快速安装体验# 1.1 克隆仓库 git clone https://github.com/zsuroy/OPiOnCmder.git # 1.2 克隆仓库（若1.1不可用时使用此国内加速链接） git clone https://mirror.ghproxy.com/https://github.com/zsuroy/OPiOnCmder.git # 2. 准备环境 cd OPiOnCmder python -m venv venv source venv/bin/activate pip install -r requirements.txt # 3. 启动 python app.py效果演示现有IO资源RGB灯使用IO口视频地址: https://www.bilibili.com/video/BV1znTAeXEtV总结OrangePi AiPro表现出色，尤其在基于华为晟腾芯片的AI功能方面。漫画风图片生成、OCR和语音转文本功能表现优异，资源占用率低，处理速度快，准确率高。利用Flask开发的硬件控制应用展示了其在物联网和边缘计算方面的潜力，开发便捷，响应迅速。总体来说，OrangePi AiPro具备强大的AI处理能力和良好的扩展性，适合多种应用场景，但硬件接口的文档支持有待提升。
记录 STM32 + STM32CubeIDE + FreeRTOS 实时操作系统移植学习中的一些心得体会。本文涉及知识有 FreeRTOS 中事件组、任务通知、定时器、中断管理等概念和常用API及部分经典案例。[...]
记录 STM32 + STM32CubeIDE + FreeRTOS 实时操作系统移植学习中的一些心得体会。由于篇幅有限，本文主要介绍 FreeRTOS 中系统状态、任务调度管理、消息队列、信号量、互斥量等概念和常用API及部分经典案例。[...]
使用STM32CubeIDE 进行 FreeRTOS 手动移植F103系列最小系统
前言FreeRTOS 是市场领先的面向微控制器和小型微处理器的实时操作系统 (RTOS)，与世界领先的芯片公司合作开发，支持 40 多种架构。FreeRTOS 通过 MIT 开源许可免费分发，包括一个内核和一组不断丰富的 IoT 库，适用于所有行业领域。FreeRTOS 的构建强调可靠性和易用性。本文主要是记录一下作者的开发踩坑日志～持续更新中...开发环境OS: MacOS CatalinaMCU: STM32f103c8t6STM32CubeIDE + HAL + GCCVSCODE + Embeded IDE + GCCKeil + ArmV5本文涉及到多种开发编译环境，参考学习请注意区分。源码下载一般主推的是 FreeRTOS V9.0 版本https://github.com/FreeRTOS/FreeRTOS-KernelFreeRTOS-Kernel是FreeRTOS的内核文件FreeRTOS-main里面文件很多，主要是看里面的Demohttps://sourceforge.net/projects/freertos/files/FreeRTOS注意下载速度慢可以切换下载服务器，参考 注意事项3 sourceforge.net 下载慢开始移植下载 FreeRTOS V9.0 源码创建 STMCubeMX 裸机工程初始化 PC13 输出 - LED点灯Systick: Tim2; (TimeBase 基准时钟)移植FreeRTOS系统STMCubeIDE打开创建的工程，新建目录 FreeRTOS将下载的 FreeRTOS 源码以下对应文件拷贝include 和 .c 文件适用于各种编译器和处理器，是通用的; portable 是接口文件，通常由汇编和 C 联合编写适配硬件的相关内容，需要精简。FreeRTOS/source/ 下的全部文件 -> 我们新建的项目 FreeRTOS 文件夹中精简 portable 文件夹GCC环境保留: MemMang(内存管理相关)、GCC或RVDS(编译器相关),其中内核选择CotrexM3(F103c8t6)Keil环境保留: MemMang、RVDS,Keil其实keil文件夹为空，内容同RVDS删减之后可以对比本节附图文件夹结构，确保没有遗漏增加 FreeRTOS 宏定义裁剪整个 FreeRTOS 所需的功能的宏，由于微处理器资源有限，适当裁剪可以发挥最大功效。源代码中 FreeRTOS/demo/ 中找 GCC 环境的工程例子CORTEX_STM32F103_GCC_RowleyCORTEX_STM32F103_Primer_GCC以上二选一即可，然后将其目录下的 FreeRTOSConfig.h 宏定义头文件复制到我们项目中 FreeRTOS/include/ 文件夹下添加编译选项选中项目 -> (右键)properties -> C/C++ General -> Paths and symbolsinclude path: 添加对应的 .h 头文件路径Source location: 添加手动创建的 .c 文件路径编译解决报错新增宏定义 FreeRTOSConfig.h/* Suroy: fix some error */ #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #define vPortSVCHandler SVC_Handler // 以下是变更原配置参数，否则时钟拉起不了 #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 //Suroy: 启用报错，于是关了 22.2.8 #define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) 注释掉 stm32f1xx_it.c 文件中的 SysTick_Handler 函数，与FreeRTOS宏定义产生冲突点亮一个LED频闪灯以下均是对 main.c 主程序进行的更改 /* USER CODE BEGIN Includes */ #include "FreeRTOS.h" #include "task.h" /* USER CODE END Includes */ //任务1 void vTask1( void *pvParameters ) { for( ;; ) { HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); vTaskDelay(500); // HAL_Delay(500); HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); vTaskDelay(500); } } // 任务2 void vTask2( void *pvParameters ) { for( ;; ) { } } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); //创建任务1 xTaskCreate(vTask1,"LED1",128,NULL,1,NULL); //创建任务2 xTaskCreate(vTask2,"LED2",128,NULL,1,NULL); //启动任务调度器 vTaskStartScheduler(); while (1) { // 运行不到这里来 } }工程源码二选一下载https://download.csdn.net/download/zsuroy/87428756 大佬请https://github.com/zsuroy/iFreeRTOS-template注意事项FreeRTOS 文件内容文件夹: FreeRTOS/portable 内容结构解析我们通常移植会保留三个该路径下的子文件夹 keil、MemMang、RVDS ，但是这里我踩坑发现其实 keil 文件夹下与 RVDS 文件夹下保留的内容其实作用一模一样的，均是 port.c 和 portmacro.h 文件，那么是不是我们可以仅保留其一呢？经我测试在 CubeIDE (MacOS + gcc) 下仅保留 gcc、MemMang 是可行的！如果是Keil环境，请留意keil下是否有文件存在。编译提示 undefined reference to xxx();e.g. undefined reference to xTaskCreate该问题是由于C/C++编译器在处理.h头文件的引入时，并为添加相应的 .c 资源文件所致解决方法:选中项目 -> (右键)properties -> C/C++ General -> Paths and symbolsinclude path: 添加对应的 .h 头文件路径Source location: 添加手动创建的 .c 文件路径sourceforge.net 下载速度慢挂代理是没有用的，其实速度慢的原因主要是因为官方自动给你选择了一个不知道是哪个偏远国家的下载节点。手动切换即可: 点击下载 -> 直接点击 Problems Download -> 选 Taiwan 或 Hongkong 或亚洲节点
前言之所以写这篇文章，是记录一下使用ESP8266实现HTTP请求的完整过程，网上教程实在太少了而且不详细，出问题都不好找，估计诸位都转 MQTT 去了调试环境WIFI模块: ESP8266-01s 串口工具: USB-to-ttl, Wch-Link(带串口功能)串口调试工具：安信可官方串口调试工具+XCom (Windows, 驱动Ch340)； Serial Monitor (MacOs, Vscode插件，有BUG) 问题踩坑驱动问题 USB to TTL的有两个版本，一个是CH340，一个是CP2102，对应驱动需要一致。关于固件下载USB to TTL: ESP8266的VCC需要接入USB to TTL的VCC引脚，不要接3.3V引脚，估计是供电不足；如果有稳压芯片可以直接上稳压3.3V；供电不足会导致串口收发数据异常、下载失败等问题。Wch-Link: 带的串口只有3.3V引脚，我试过了数据收发正常，但是固件下载失败；MacOS 环境下使用 Parallel Desktop 安装Win10虚拟机，在虚拟机内使用以上几款串口工具出现数据收发不完整，有时候会乱码，暂时无解；直接使用ASUS 真机 Win7系统，以上两款均数据收发正常。开始折腾更新固件不要用虚拟机！！！注意看以上的问题踩坑再操作。最新固件：于2023.1.31摘自安信可官网ESP8266/ESP32固件合集①、博安通 AT 固件（固件号：4MB(0883),1MB(0884)） 特性：操作简单，任何mcu均可直接接入 下载地址： 博安通出厂固件 更新时间：2019年12月22日 更新说明： v1.7.1.0 AT Firmware，内含 8Mbit 和 32Mbit 两个版本，请客户根据自己产品的flash大小来烧录，串口引脚为TXD,RXD注意看单位写的是8Mbit -> 1MB; 即对应两个版本1M版本和4M版本，本文使用的是ESP8266-01S，数据手册说明是1MB版本，下载解压后选固件1MB大小那个BIN。接线图使用 USB to TTL 进行更新: 接五根线就可以了，因为RST、EN已经内部上拉。ESP01S -> USB to TTLTX -> RXRX -> TXGND -> GNDVCC -> VCC (不是3.3引脚，就是VCC引脚)IO0 -> GND下载步骤导入下载解压出来的1MB固件bin格式，填写扇区地址 0x0勾选 DonotChBin，其他可以不用配置了，勾选后自动配置点击 Start 开始下载提示等待设备复位：此时断开ESP8266-01S的电源重新连下即可下载区别运行模式与下载模式使用串口调试工具，设置波特率：74880，以切换到系统日志模式。开机复位之后可以看到如下字样。boot mode: 1 下载模式 boot mode: 3 运行模式AT指令HTTP请求图上命令不需要最后的 \r\n\r\nAT指令 // 连接 AT+CIPSTART="TCP","suroy.cn",80 // 开启透传模式 AT+CIPMODE=1 // 开始发送，此时回复 **>** AT+CIPSEND // 以下是发送的协议内容 GET /ping.html HTTP/1.1 Host: suroy.cn Connection: Keep Alive // 退出透传(不加\r\n) +++ SSL有所不同 // 设置SSL buffer 大小（未设置这项导致SSL连接错误） AT+CIPSSLSIZE=4096 // 连接 AT+CIPSTART="SSL","suroy.cn",443 // 开启透传模式 AT+CIPMODE=1 // 开始发送，此时回复 **>** AT+CIPSEND // 以下是发送的协议内容 GET /ping.html HTTP/1.1 Host: suroy.cn Connection: Keep Alive // 退出透传(不加\r\n) +++ // 关闭连接 AT+CIPCLOSE HTTP协议说明以下是一个完整的GET请求协议，使用透传模式发送完整内容，包括空格、换行都不能少；行内空格，行末换行，结束有一个空行；注意此处未使用 \r\n 替换，因为\r\n 实际上发送出去时会经过转义导致发出去的并不是“ \r\n ”，所以直接输入换行进行发送。GET /ping.html HTTP/1.1 Host: suroy.cn Connection: Keep Alive 问题分析:47 45 54 20 2F 20 48 54 54 50 2F 31 2E 31 0D 0A 48 6F 73 74 3A 20 73 2E 73 75 72 6F 79 2E 63 6E 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A 20 4B 65 65 70 20 41 6C 69 76 65 0D 0A 0D 0A 5C 72 5C 6E 5C 72 5C 6E 这是本节首截图中发送出去的16进制，可以看到最后的\r\n被转义发出为 5C 72 5C 6E 5C 72 5C 6E 并非"\r\n"的 0D 0A，所以协议请求会失败；那么如何解决这个问题呢？直接使用单片机串口发送字符"\r\n"，单片机内部发送不存在此问题；当发送\r\n时使用16进制发送即“\r”(0D),"\n"(0A)附POST协议未测试POST / HTTP/1.1 Accept-Language: zh-CN,zh;q=0.9 Host: suroy.cn Connection: keep-alive Content-Length:26 Content-Type:application/x-www-form-urlencoded;charset=UTF-8 name=suroy&id=1 说明：跟get请求一样，第一行的协议类型为POST需要注意的是 POST需要发送两次，第一次不会返回任何东西，第二次会返回；Content-Length:26 必须声明请求体的字符长度常用资料集合ESP8266资料合集ESP8266开发工具ESP8266/ESP32固件合集