完整教程:K230基础-PWM控制介绍及应用

第三章 PWM控制-K230精准时序输出

本章目标
掌握 K230 的 PWM(脉宽调制)系统架构,理解频率、占空比、分辨率等核心概念,学会在 MicroPython 中配置和使用 PWM 模块,实现 LED 呼吸灯、舵机控制、电机调速、音频输出 等经典应用。


1. PWM 基础概念

1.1 什么是 PWM?

PWM(Pulse Width Modulation,脉宽调制) 是一种通过调节脉冲宽度(高电平持续时间) 来控制平均输出电压/功率的技术。

  • 周期(Period):一个完整脉冲的时间(T = 1 / 频率)
  • 占空比(Duty Cycle):高电平时间 / 周期(0% ~ 100%)
  • 频率(Frequency):单位时间内脉冲个数(Hz)

核心思想
通过快速开关(如 1kHz),利用负载惯性(人眼、电机、舵机)实现“模拟量”控制。


1.2 PWM 典型应用场景

应用推荐频率说明
LED 亮度调节100Hz ~ 1kHz人眼无闪烁,平滑调光
舵机控制50Hz(20ms)标准舵机周期
直流电机调速1kHz ~ 20kHz频率越高,噪声越小
蜂鸣器发声1kHz ~ 5kHz不同频率对应不同音调
DAC 模拟输出10kHz+配合 RC 低通滤波

2. K230 PWM 系统架构

2.1 硬件资源

K230 提供 多个独立 PWM 通道(通常 8 个或更多),每个通道:

  • 独立设置频率、占空比
  • 支持极性反转(高有效/低有效)
  • 支持死区控制(用于电机 H 桥)
  • 时钟源可选(系统时钟分频)

关键优势
多通道独立运行,不占用 CPU 资源,适合并行控制多个设备。


2.2 FPIOA 映射(必须配置!)

PWM 输出必须通过 FPIOA 映射到物理引脚!

常见 PWM FPIOA 功能编号:

功能名FPIOA 编号说明
PWM0_OUT80PWM 通道 0
PWM1_OUT81PWM 通道 1
PWM2_OUT82PWM 通道 2
PWM7_OUT87PWM 通道 7

重要
不同开发板默认引脚不同!请查阅原理图或官方文档。


3. MicroPython PWM 配置与使用

3.1 导入模块

from fpioa_manager import fm
from machine import PWM

3.2 初始化流程(四步法)

步骤1:FPIOA 映射
fm.register(pin_number, fm.fpioa.PWMx_OUT) # x = 0~7
步骤2:创建 PWM 对象
pwm = PWM(PWM.PWMx, freq=1000, duty=50, pin=pin_number)
步骤3(可选):动态调整参数
pwm.freq(2000) # 设置频率为 2000Hz
pwm.duty(75) # 设置占空比为 75%
步骤4:关闭 PWM
pwm.deinit() # 释放资源,停止输出

4. 实战项目一:LED 呼吸灯

4.1 硬件连接

  • LED 阳极 → 限流电阻 → 物理引脚 12
  • LED 阴极 → GND

假设:Pin12 默认未被占用,支持 PWM 输出


4.2 完整代码

from fpioa_manager import fm
from machine import PWM
import utime
# === 1. FPIOA 映射 ===
fm.register(12, fm.fpioa.PWM0_OUT) # 映射 Pin12 到 PWM0
# === 2. 初始化 PWM ===
pwm = PWM(PWM.PWM0, freq=1000, duty=0, pin=12) # 初始占空比0%
print("开始呼吸灯效果...")
# === 3. 呼吸灯循环 ===
try:
while True:
# 逐渐变亮
for i in range(0, 101, 2): # 0% → 100%,步长2
pwm.duty(i)
utime.sleep_ms(20)
# 逐渐变暗
for i in range(100, -1, -2): # 100% → 0%,步长-2
pwm.duty(i)
utime.sleep_ms(20)
except KeyboardInterrupt:
print("程序被中断")
finally:
pwm.deinit() # 清理资源
print("PWM 已关闭")

优化技巧

  • 使用 sin() 函数实现更平滑的亮度变化
  • 调整 freqsleep_ms 控制呼吸速度

5. 实战项目二:舵机控制(SG90)

5.1 舵机原理

  • 控制信号:50Hz PWM(周期 20ms)
  • 脉宽范围
    • 0.5ms → 0°
    • 1.5ms → 90°(中位)
    • 2.5ms → 180°

占空比计算

  • 0.5ms / 20ms = 2.5%
  • 1.5ms / 20ms = 7.5%
  • 2.5ms / 20ms = 12.5%

5.2 硬件连接

  • 舵机信号线 → 物理引脚 13
  • 舵机 VCC → 5V(注意:K230 GPIO 为 3.3V,舵机需独立供电!)
  • 舵机 GND → 开发板 GND

5.3 完整代码

from fpioa_manager import fm
from machine import PWM
import utime
# === 1. FPIOA 映射 ===
fm.register(13, fm.fpioa.PWM1_OUT) # 映射 Pin13 到 PWM1
# === 2. 初始化 PWM(50Hz)===
pwm = PWM(PWM.PWM1, freq=50, duty=0, pin=13)
# === 3. 舵机角度函数 ===
def set_servo_angle(angle):
"""
设置舵机角度 (0° ~ 180°)
对应占空比: 2.5% ~ 12.5%
"""
if angle <
0:
angle = 0
elif angle >
180:
angle = 180
# 线性映射:0°→2.5%, 180°→12.5%
duty = 2.5 + (angle / 180.0) * 10.0
pwm.duty(int(duty)) # 注意:duty() 接受整数
print("舵机测试:0° → 90° → 180° → 90° → 0°")
try:
angles = [0, 90, 180, 90, 0]
for angle in angles:
print(f"转动到 {angle
}°")
set_servo_angle(angle)
utime.sleep_ms(1000) # 保持1秒
except KeyboardInterrupt:
pass
finally:
pwm.deinit()
print("舵机控制结束")

⚠️ 重要提醒

  • 舵机需要 5V 供电,不可直接用 K230 3.3V 供电!
  • 信号线可直接连接(3.3V TTL 兼容 5V 输入)

6. 高级技巧与性能优化

6.1 使用 Timer 实现非阻塞 PWM 控制

避免 sleep_ms() 阻塞主循环:

from machine import Timer
def breath_led(timer):
global brightness, direction
brightness += direction * 2
if brightness >= 100:
brightness = 100
direction = -1
elif brightness <= 0:
brightness = 0
direction = 1
pwm.duty(brightness)
# 初始化
brightness = 0
direction = 1
pwm = PWM(PWM.PWM0, freq=1000, duty=0, pin=12)
# 启动定时器(每50ms调用一次)
Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=50, callback=breath_led)
# 主循环可执行其他任务
while True:
# do other things...
utime.sleep_ms(1000)

6.2 多通道 PWM 并行控制

# 控制两个 LED 呼吸(相位相反)
fm.register(12, fm.fpioa.PWM0_OUT)
fm.register(13, fm.fpioa.PWM1_OUT)
pwm0 = PWM(PWM.PWM0, freq=1000, duty=0, pin=12)
pwm1 = PWM(PWM.PWM1, freq=1000, duty=100, pin=13) # 初始相反
while True:
for i in range(0, 101, 2):
pwm0.duty(i)
pwm1.duty(100 - i) # 相反效果
utime.sleep_ms(20)

7. 常见问题与调试

❌ 问题1:PWM 无输出

排查

  • 是否调用 fm.register()
  • FPIOA 编号是否正确(PWMx_OUT)?
  • 引脚是否被其他外设占用?
  • 是否调用 pwm.duty() 设置非零值?

❌ 问题2:舵机抖动/不转

排查

  • 供电是否独立且充足(5V/1A+)?
  • 占空比是否在 2.5%~12.5% 范围内?
  • 频率是否为 50Hz?
  • 信号线接触是否良好?

❌ 问题3:频率不准

原因

  • 系统时钟未校准
  • 频率超出硬件支持范围(查阅数据手册)
  • 占空比分辨率限制

解决

# 查看实际设置的频率(部分平台支持)
print(pwm.freq()) # 可能返回实际值,非设置值

8. 性能边界与限制

参数K230 MicroPython 限制
最高频率~1MHz(实测约 500kHz 稳定)
占空比分辨率通常 0~100 整数(1% 步进)
通道数8 个独立通道
同步控制不支持多通道硬件同步

如需更高精度(如音频 DAC),建议使用 I2S + DACC 语言裸机开发


本章你已掌握

  • PWM 原理与应用场景
  • K230 PWM + FPIOA 配置流程
  • LED 呼吸灯实现
  • 舵机精确角度控制
  • 非阻塞定时器控制
  • 多通道并行 PWM
  • 常见问题排查

下一步预告
第四章:UART 串口通信 —— 与 PC、蓝牙模块、ESP8266 通信,实现无线控制与数据传输!


posted on 2025-09-25 18:26  slgkaifa  阅读(104)  评论(0)    收藏  举报

导航