3. SAM GPIO与PWM模块实战

在直流电机开环调速中,SAM 系列 MCU 通常需要同时完成三件事:用 GPIO 控制电机驱动器的方向与使能,用 TC/TCC 产生频率与占空比可调的 PWM,并在需要互补输出时插入死区,避免上下桥臂直通。本节以 SAM D21/SAM C21 常见的 TCC 模块为例,给出可直接参考的配置思路与示例参数。

一、GPIO:方向与使能的“静态控制层”

方向信号(DIR)和使能信号(EN)属于慢速逻辑,通常由普通 GPIO 输出驱动。以常见的 H 桥驱动器为例,DIR 决定电机正反转,EN 决定驱动器是否输出。上电默认应让 EN 为无效电平,避免电机意外启动。假设使用 SAM D21 的 PA14 接 DIR、PA15 接 EN,且驱动器 EN 高有效,则初始化顺序为:先配置为输出并写入安全电平,再使能外设时钟。

// 示例:SAM D21 GPIO 方向/使能初始化(寄存器级)
// PA14 = DIR, PA15 = EN,EN 高有效
PORT->DIRSET.reg = (1u << 14) | (1u << 15); // 设为输出
PORT->OUTCLR.reg = (1u << 15);              // 先拉低 EN,安全态
PORT->OUTCLR.reg = (1u << 14);              // DIR = 0,默认正转
// 需要启动时:
PORT->OUTSET.reg = (1u << 15);              // EN = 1,使能驱动器
// 换向时:
PORT->OUTTGL.reg = (1u << 14);              // 翻转 DIR

这里的关键是“先安全、后使能”。若 DIR 与 EN 同时变化,建议先改 DIR,待电平稳定后再拉高 EN;换向时若电机电流较大,可先拉低 EN,延时几毫秒再翻转 DIR,最后重新使能,以减小冲击。GPIO 的驱动能力、上拉/下拉和引脚复用需按具体封装与驱动器手册确认,避免与 TCC 输出引脚冲突。

二、TCC:互补PWM与死区插入的核心

SAM 的 TCC 模块支持双通道互补输出(WO[0]/WO[1]),并内置死区插入。以 TCC0 为例,假设系统时钟 48 MHz,目标 PWM 频率 20 kHz,则周期计数值为 48 MHz / 20 kHz = 2400。若采用双斜率或单斜率模式,需注意计数范围与比较值的对应关系。下面给出单斜率、中心对齐关闭的简化配置:

// 示例:TCC0 互补PWM,20 kHz,初始占空比 50%
// 时钟源:GCLK0 = 48 MHz,分频 1
TCC0->CTRLA.reg = TCC_CTRLA_PRESCALER_DIV1 | TCC_CTRLA_ENABLE;
TCC0->WAVE.reg = TCC_WAVE_WAVEGEN_DSBOTH; // 双斜率,互补
TCC0->PER.reg = 2400;                     // 周期
TCC0->CC[0].reg = 1200;                   // 占空比 50%
TCC0->CC[1].reg = 1200;                   // 互补通道比较值
// 死区插入:约 500 ns
TCC0->DTRIG.reg = TCC_DTRIG_TRG0EN;       // 可选触发
TCC0->DBGCTRL.reg = 0;
TCC0->DRVCTRL.reg = TCC_DRVCTRL_DTIEN0 | TCC_DRVCTRL_DTIEN1;
TCC0->DCFG.reg = TCC_DCFG_DTINV0 | TCC_DCFG_DTINV1; // 按需反相
// 死区时间寄存器:DTVAL = 死区时钟数
TCC0->DCFG.reg |= (24 << TCC_DCFG_DTPER_Pos); // 示例值,需按手册换算

死区时间的计算必须结合 TCC 的时钟源与分频。若死区时钟为 48 MHz,则 1 个计数约 20.8 ns,500 ns 约需 24 个计数。实际写入 DCFG 的 DTPER 字段时,要确认该字段的位宽与编码方式,不同 SAM 型号可能不同。死区过小会导致上下桥臂直通,过大则会畸变输出电压、降低有效占空比,因此应结合驱动器手册的 trise/tfall 与关断延时选取。

GPIO 控制层 PA14 → DIR PA15 → EN 先安全电平,后使能 TCC0 互补PWM PER = 2400(20 kHz @48 MHz) CC[0]=CC[1]=1200(50%) 死区插入 DTIEN0/1 ≈ 500 ns H桥驱动器 IN1 / IN2 互补输入 DIR / EN 逻辑 输出至直流电机 互补PWM与死区波形示意(占空比50%,死区已放大) WO[0] WO[1] 死区 ≈500 ns 注:波形为示意,死区宽度已放大以便观察;实际死区由 DCFG.DTPER 与时钟分频决定。

三、开环调速:占空比与方向联动

开环调速的本质是“给定占空比 → 平均电压 → 转速”。在 20 kHz、50% 占空比下,若电机供电 12 V,则平均电压约 6 V。改变 CC[0] 即可改变占空比:CC[0]=600 对应 25%,CC[0]=1800 对应 75%。方向由 GPIO 的 DIR 决定,EN 保持高电平。实际调试时,建议先用固定 50% 占空比确认波形与死区正常,再逐步改变占空比观察转速变化。

需要特别注意的是,互补 PWM 的“有效占空比”会因死区而略有损失。若死区为 500 ns、周期为 50 μs,则死区占比约 1%,对低速影响较小;但在高频或小占空比时,死区可能导致输出非线性。此时可通过软件补偿:在低占空比区间适当增大 CC 值,或降低 PWM 频率以减小死区相对影响。

四、调试与验证要点

建议按以下顺序验证:第一,用示波器观察 WO[0]/WO[1] 是否为互补、死区是否在 300~800 ns 之间;第二,测量 EN 与 DIR 的电平是否符合预期;第三,接入电机后,从 20% 占空比逐步升至 80%,记录转速与电流变化。若出现上下桥臂发热、电流尖峰或电机抖动,应优先检查死区是否足够、DIR/EN 时序是否冲突,以及 TCC 输出引脚是否被其他外设复用。

示例参数(48 MHz、20 kHz、2400 周期、500 ns 死区)仅用于说明配置方法,实际项目需根据驱动器手册、电机参数和 SAM 型号的 TCC 寄存器定义重新计算与验证。