You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

KL25Z开发板Keil环境下PWM伺服控制无响应问题排查

伺服电机PWM控制无响应问题修复(Freedom KL25Z)

问题概述

需实现PWM控制伺服电机:初始摆臂处于中位,每0.5秒转动30度。基于Freedom KL25Z开发板的C代码运行后,伺服摆臂完全无响应。

原代码

#include <MKL25Z4.H>
#include <stdio.h>
#include <math.h>

#include "utils.h"

int main (void) {
    SIM->SCGC5 |= 0x1000; /* enable clock to Port D */
    PORTD->PCR[2] = 0x0400; /* PTD1 used by TPM0 PIN DEL PRIMER SERVOMOTOR */
    SIM->SCGC6 |= 0x01000000; /* enable clock to TPM0 */
    SIM->SOPT2 |= 0x01000000; /* use MCGFLLCLK as timer counter clock */
    while (1) {
        TPM0->SC = 0; /* disable timer */
        TPM0->CONTROLS[3].CnSC = 0x20 | 0x08; /* edge-aligned, pulse high */
        TPM0->MOD = 299999; /* Set up modulo register for 50 Hz */
        TPM0->CONTROLS[3].CnV = 15000; /* Set up channel value for 5% dutycycle for 0 degree */
        TPM0->SC = 0x0C; /* enable TPM0 with prescaler /16 */
        Delay(5000000);
        TPM0->CONTROLS[3].CnV = 17499; /* Set up channel value for  for duty cycle 5.833 30 degree */
        Delay(5000000);
        TPM0->CONTROLS[3].CnV = 19999; /* Set up channel value for  duty cycle 6.66333 value 19999 60 degree servo*/
        TPM0->SC = 0x0C;
        Delay(5000000);
        TPM0->CONTROLS[3].CnV = 22500;
        TPM0->SC = 0x0C;
        Delay(5000000);
    }
}

问题分析与修复步骤

1. 定时器时钟未启用

原代码中TPM0->SC = 0x0C仅设置了分频系数(/16),但CMOD位(时钟模式)为0,定时器无法运行。需将CMOD设为01(使用内部时钟),正确的SC值应为0x0D(0x01 | 0x0C)。

2. PWM周期计算错误

伺服电机需要50Hz(20ms周期)的PWM信号:

  • 核心时钟MCGFLLCLK默认48MHz,分频/16后计数频率为48MHz /16 = 3MHz
  • 20ms对应计数值为3MHz * 0.02s = 60000,因此MOD寄存器应设为59999(计数值从0到MOD,共60000次),而非原代码的299999(对应10Hz周期)。

3. 引脚复用配置错误

原代码中PORTD->PCR[2] = 0x0400将引脚复用设为ALT2,但TPM0_CH3(对应PTD2)需设置为ALT3,正确配置为PORTD->PCR[2] = 0x0300。同时注释标注的PTD1为错误,需修正为PTD2。

4. CnV值计算错误

基于3MHz计数频率,伺服电机典型脉宽对应CnV值:

  • 中位(1.5ms):3MHz * 0.0015s = 4500
  • 30度(1.75ms):3MHz * 0.00175s = 5250
  • 60度(2ms):3MHz * 0.002s = 6000
  • 90度(2.25ms):3MHz * 0.00225s = 6750

5. 冗余配置优化

无需在while循环中重复配置定时器基础参数(SC、CnSC、MOD),只需初始化时配置一次,循环中仅修改CnV即可。

修复后的代码

#include <MKL25Z4.H>
#include "utils.h"

int main (void) {
    // 启用端口D时钟
    SIM->SCGC5 |= 0x1000;
    // 配置PTD2为TPM0_CH3(ALT3)
    PORTD->PCR[2] = 0x0300;
    // 启用TPM0时钟
    SIM->SCGC6 |= 0x01000000;
    // 设置定时器时钟源为MCGFLLCLK(48MHz)
    SIM->SOPT2 |= 0x01000000;

    // 初始化TPM0参数
    TPM0->SC = 0; // 先禁用定时器
    TPM0->CONTROLS[3].CnSC = 0x28; // 边沿对齐PWM,高有效(MSB:10, ELSB:01)
    TPM0->MOD = 59999; // 50Hz PWM周期(20ms)
    TPM0->SC = 0x0D; // 启用定时器,分频/16,内部时钟

    while (1) {
        TPM0->CONTROLS[3].CnV = 4500; // 中位(1.5ms脉宽)
        Delay(2500000); // 0.5秒延时(根据实际核心频率调整)
        
        TPM0->CONTROLS[3].CnV = 5250; // 30度
        Delay(2500000);
        
        TPM0->CONTROLS[3].CnV = 6000; // 60度
        Delay(2500000);
        
        TPM0->CONTROLS[3].CnV = 6750; // 90度
        Delay(2500000);
    }
}

额外说明

  • 延时函数Delay()的参数需根据实际核心频率调整,若核心为48MHz,循环计数约2500000次对应0.5秒(可通过示波器校准)。
  • 不同伺服电机的脉宽范围可能略有差异,可微调CnV值适配具体电机。

内容的提问来源于stack exchange,提问作者Shash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:45:22