不只是点亮LED:用MicroPython玩转STM32F407的GPIO、串口与虚拟磁盘
·
不只是点亮LED:用MicroPython玩转STM32F407的GPIO、串口与虚拟磁盘
当MicroPython固件成功烧录到STM32F407开发板后,许多开发者会陷入"然后呢?"的困惑阶段。本文将带你突破简单的LED控制,探索三个核心功能模块的深度应用: 多GPIO协同控制 、 硬件串口双向通信 和 虚拟磁盘文件管理 。通过实际代码示例和项目级解决方案,你将掌握如何将这些基础功能组合成实用项目。
1. GPIO控制:从单灯闪烁到多设备协同
1.1 基础引脚操作进阶
STM32F407的每个GPIO引脚都可以通过MicroPython直接控制。不同于简单的 LED.on() ,实际项目往往需要更精细的控制:
from machine import Pin
import time
# 配置多个引脚为输出模式
led_red = Pin('PF9', Pin.OUT)
led_green = Pin('PF10', Pin.OUT)
button = Pin('PA0', Pin.IN, Pin.PULL_UP)
# 带消抖的按钮检测
def check_button():
if button.value() == 0:
time.sleep_ms(20) # 消抖延迟
return button.value() == 0
return False
while True:
if check_button():
led_red.toggle()
led_green.value(not led_red.value()) # 红绿交替
关键技巧 :
- 使用
Pin.PULL_UP启用内部上拉电阻 - 机械按钮必须添加软件消抖
toggle()方法比手动取反更高效
1.2 引脚状态管理与事件驱动
对于复杂项目,建议采用面向对象的方式管理GPIO:
class LEDController:
def __init__(self, pins):
self.leds = [Pin(p, Pin.OUT) for p in pins]
self.patterns = {
'alarm': [1,0,1,0],
'progress': [1,1,0,0]
}
def run_pattern(self, name, speed=300):
for state in self.patterns[name]:
for i, led in enumerate(self.leds):
led.value(state if i < len(self.leds)/2 else not state)
time.sleep_ms(speed)
controller = LEDController(['PF9','PF10','PE13','PE14'])
controller.run_pattern('alarm')
2. 硬件串口:实现稳定可靠的数据通信
2.1 基础串口配置
STM32F407最多支持6个硬件串口,以下是UART1和UART2的协同工作示例:
from machine import UART
# 配置主调试串口 (UART1)
uart1 = UART(1, baudrate=115200, tx='PA9', rx='PA10')
# 配置设备通信串口 (UART2)
uart2 = UART(2, baudrate=9600, tx='PD5', rx='PD6', timeout=100)
def send_command(cmd):
uart2.write(cmd + '\r\n') # 添加终止符
return uart2.read().decode().strip()
# 双向通信示例
while True:
if uart1.any():
cmd = uart1.read().decode()
response = send_command(cmd)
uart1.write(response + '\n')
参数优化建议 :
| 参数 | 典型值 | 适用场景 |
|---|---|---|
| baudrate | 9600-115200 | 根据设备兼容性选择 |
| timeout | 50-500ms | 取决于设备响应速度 |
| txbuf/rxbuf | 256-1024 | 大数据量传输时增加 |
2.2 串口协议设计实践
实现简单的Modbus RTU协议框架:
def calc_crc(data):
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 0x0001:
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return crc.to_bytes(2, 'little')
def read_holding_registers(addr, count):
cmd = bytes([0x01, 0x03, addr>>8, addr&0xFF, count>>8, count&0xFF])
uart2.write(cmd + calc_crc(cmd))
return parse_response(uart2.read())
3. 虚拟磁盘:文件系统与持久化存储
3.1 高效文件操作技巧
MicroPython将开发板的Flash模拟为U盘,但需要注意特殊操作限制:
import os
import json
# 安全写入文件的最佳实践
def safe_write(filename, content):
temp_name = filename + '.tmp'
with open(temp_name, 'w') as f:
if isinstance(content, dict):
json.dump(content, f)
else:
f.write(content)
os.rename(temp_name, filename) # 原子操作
# 读取配置文件示例
try:
with open('config.json') as f:
config = json.load(f)
except:
config = {'brightness': 80, 'timeout': 30}
safe_write('config.json', config)
重要注意事项 :
绝对不要直接编辑/main.py,应该在其他位置编写完成后整体替换 定期使用os.sync()强制写入防止数据丢失 Flash寿命约10万次擦写,避免频繁小文件写入
3.2 实现数据记录器
结合GPIO和文件系统创建传感器数据记录器:
from pyb import ADC
adc = ADC('PA1') # 假设连接了温度传感器
log_interval = 60 # 每分钟记录一次
def log_sensor():
temp = adc.read() * 330 / 4095 # 转换为摄氏度
timestamp = '%04d-%02d-%02d %02d:%02d' % time.localtime()[:5]
with open('temp_log.csv', 'a') as f:
f.write(f'{timestamp},{temp:.1f}\n')
# 在main.py中添加定时器回调
tim = pyb.Timer(4)
tim.init(freq=1/log_interval)
tim.callback(lambda t: log_sensor())
4. 项目集成:智能环境监测终端
将前述技术整合为完整项目,实现:
- 通过GPIO控制多路LED状态指示
- 串口连接温湿度传感器(SHT30)
- 定时将数据保存到虚拟磁盘
- USB串口提供实时查询接口
核心代码框架 :
# 硬件初始化
sht30 = UART(2, baudrate=9600)
leds = LEDController(['PC13','PC14','PC15'])
data_file = 'env_data.csv'
def read_sensor():
sht30.write(b'\xF3\x2D\x0A') # SHT30读取命令
raw = sht30.read(6)
temp = -45 + 175*(raw[0]<<8|raw[1])/65535
hum = 100*(raw[3]<<8|raw[4])/65535
return temp, hum
def main_loop():
while True:
temp, hum = read_sensor()
safe_write(data_file, f'{time.time()},{temp:.1f},{hum:.1f}\n')
leds.run_pattern('progress' if hum >60 else 'normal')
time.sleep(60)
实际部署时发现,当采样间隔小于30秒时,文件系统会出现写入延迟。解决方法是将数据先缓存到内存,每小时集中写入一次,同时添加异常恢复机制:
data_cache = []
MAX_CACHE = 120 # 2小时数据
def save_cache():
global data_cache
try:
with open(data_file, 'a') as f:
f.writelines(data_cache)
data_cache = []
except:
pyb.LED(1).on() # 错误指示
通过这个完整案例,开发者可以掌握如何将MicroPython的基础功能转化为实际可用的嵌入式应用。
更多推荐



所有评论(0)