本项目以 NXP MCXA153(ARM Cortex-M0+ 内核)微控制器为核心,构建了一个具备高频 PWM 调速、串口指令交互以及状态保护功能的完整直流电机控制方案。
相关资料
Let'sdo2025年第4期基于单片机的直流电机控制-过程贴-电子产品世界论坛这个是过程贴,具体内容再这里
核心亮点高频驱动:20kHz PWM 信号,有效消除电机运行时的机械噪音。
实时交互:内置自定义串口命令行界面(CLI),支持动态参数调整。
安全保护:具备参数越界校验及急停(STBY)逻辑。
模块化架构:硬件抽象层(HAL)与应用逻辑分离,易于移植到双向平衡车或四驱平台。
系统框图
系统的逻辑层次如下:
PC[PC 串口调试助手] -- UART (115200) --> MCU[NXP MCXA153 MCU]
MCU -- PWM (20kHz) --> Driver[TB6612FNG 驱动模块]
MCU -- GPIO (AIN1/AIN2/STBY) --> Driver
Driver -- 高电流驱动 --> Motor[直流电机]
Power[12V 外部电源] --> Driver
Power -- 降压 --> MCU
硬件设计与接口电路连接原理
系统采用 TB6612FNG 双 H 桥驱动器。相比传统的 L298N,它具有更高的效率和更低的发热量。
详细引脚映射表| P1_0 | GPIO Output | AIN1 | 方向控制信号 1 |
| P1_2 | GPIO Output | AIN2 | 方向控制信号 2 |
| P1_1 | GPIO Output | STBY | 待机/使能控制 (High=工作) |
| P3_14 | CTimer PWM | PWMA | 速度控制 (20kHz 占空比调节) |
| GND | Ground | GND | 共地连接 |
| 3.3V | Power | VCC | 逻辑电源 |
主要参数情况
通过对底层定时器的精细配置,系统达到了以下性能指标:
1. PWM 驱动参数载波频率:20 \text{ kHz} (避免人耳听觉干扰)
分辨率:600 级 (占空比步进约 0.17\%)
时钟源:12 \text{ MHz} 系统时钟
| 串口波特率 | 115200 bps | 8-N-1 配置 |
| 命令响应延迟 | < 20 ms | 实时解析 |
| 输入电压 (VM) | 6.0V - 12.0V | 取决于电机规格 |
| 逻辑电压 (VCC) | 3.3V | MCU 标准电平 |
实现步骤第一阶段:底层配置 (Config Tools)
引脚复用:在 MCUXpresso Config Tools 中将 P3_14 配置为 CTimer 的 Match 输出。
时钟树:配置系统主频,确保 CTimer 获得稳定的 12MHz 时钟源。
PWM 生成:计算 Match 寄存器的周期值。
周期值公式:Period\_Count = \frac{Clock\_Freq}{PWM\_Freq} - 1
方向逻辑:编写 Motor_Direction() 函数,控制 AIN1 和 AIN2 的电平组合(10 为正转,01 为反转)。
利用 strtok 函数解析串口收到的字符串缓冲区。
实现 motor <speed> 命令,将 0-100 的数值映射到 PWM 占空比。
使用示波器观察 PWM 波形。
进行负载测试,观察 TB6612FNG 在长时间运行下的发热情况。
核心代码片段PWM 占空比动态调整
/* * 设置电机速度 (0-100%)命令解析逻辑
* 20kHz 频率下,g_pwmPeriod 为 599
*/
void Motor_SetSpeed(uint8_t speedPercent)
{
if (speedPercent > 100) speedPercent = 100;
// 计算周期计数值
uint32_t pwmPeriod = (timerClock / 20000) - 1U;
// 计算占空比 (注意:根据驱动器逻辑,可能需要反转占空比或直接对应)
// 脉冲宽度 = 周期 * (100 - 百分比) / 100
uint32_t pulsePeriod = (pwmPeriod + 1U) * (100 - speedPercent) / 100;
CTIMER_SetupPwmPeriod(CTIMER, CTIMER_MAT_PWM_PERIOD_CHANNEL,
CTIMER_MAT_OUT, pwmPeriod, pulsePeriod, false);
}
void handle_command(char *line)
{
char *cmd = strtok(line, " ");
if (strcmp(cmd, "motor") == 0) {
char *val = strtok(NULL, " ");
if (val) {
uint8_t speed = (uint8_t)atoi(val);
Motor_SetSpeed(speed);
PRINTF("OK: Speed set to %d%%\r\n", speed);
}
} else if (strcmp(cmd, "stop") == 0) {
GPIO_PinWrite(STBY_GPIO, STBY_PIN, 0); // 紧急停止
PRINTF("OK: Motor Halted.\r\n");
}
}
效果演示1. 串口控制台输出
>> help2. 预期运行表现
Available commands: motor <0-100>, left, right, stop, start
>> start
>> motor 50
OK: Speed set to 50%
>> right
OK: Direction changed.
低速阶段 (10%-30%):电机启动平稳,由于频率高,无明显电流噪声。
高速阶段 (80%-100%):电机转速达到额定值,波形稳定。
方向切换:执行 left 或 right 时,电机平滑减速后反转(建议在软件层加入缓冲逻辑)。
3.b站演示视频
我要赚赏金
