m0_73978548 2026-03-12 16:31 采纳率: 50%
浏览 2

直流电机正转会根据psc的值决定

#include "stm32f10x.h"                  // Device header


void PWM_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    TIM_InternalClockConfig(TIM2);
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period =  100-1;//ARR
    TIM_TimeBaseStructure.TIM_Prescaler =  0; //psc
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
    
    TIM_OCInitTypeDef TIM_OCInitStructure;                                
    TIM_OCStructInit(&TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1 ;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OC3Init(TIM2, &TIM_OCInitStructure);
    
    TIM_Cmd(TIM2,ENABLE);
}

void PWM_SetCompare3(uint16_t Compare)
{
    TIM_SetCompare3(TIM2,Compare);
}

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Motor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    PWM_Init();
}

void Motor_SetSpeed(int8_t Speed)
{
    if(Speed >=0)
    {
        GPIO_SetBits(GPIOA,GPIO_Pin_4);
        GPIO_ResetBits(GPIOA,GPIO_Pin_5);
        PWM_SetCompare3(Speed);
    }
    else
    {
        GPIO_SetBits(GPIOA,GPIO_Pin_5);
        GPIO_ResetBits(GPIOA,GPIO_Pin_4);
        PWM_SetCompare3(-Speed);
    }
}

为什么psc我设为36的时候Speed=20可以转,设为1的时候Speed=20却不能转,这两种反转Speed=-20的时候却可以

  • 写回答

1条回答 默认 最新

  • 檀越@新空间 2026-03-12 16:32
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你提到的 直流电机正转 的问题,与 PWM(脉宽调制)的配置有关。你提供的代码中,PWM 初始化部分使用了 TIM_Prescaler = 0 或者 36,这会影响 PWM 的频率和占空比,从而影响电机的速度控制。


    ✅ 问题分析

    在你的代码中:

    TIM_TimeBaseStructure.TIM_Prescaler =  0; //psc
    

    这个参数决定了定时器的时钟分频系数。如果 TIM_Prescaler 设置为 0,那么定时器的时钟频率是系统时钟频率(通常是 72MHz),而 TIM_Period = 100-1 表示计数器从 0 到 99,所以 PWM 的周期是:

    $$ \text{PWM 周期} = \frac{(TIM_Prescaler + 1) \times (TIM_Period + 1)}{\text{System Clock}} $$

    情况一:TIM_Prescaler = 0(即 PSC=0)

    • 系统时钟假设为 72 MHz。
    • PWM 频率 = $ \frac{72,000,000}{(0+1) \times (100)} = 720,000 , \text{Hz} $

    情况二:TIM_Prescaler = 36(即 PSC=36)

    • PWM 频率 = $ \frac{72,000,000}{(36+1) \times (100)} = \frac{72,000,000}{3700} \approx 19,459 , \text{Hz} $

    🔍 为什么 PSC=36Speed=20 可以转动,但 PSC=1 时不能?

    这是因为 PWM 的占空比和频率对电机的影响不同

    1. 占空比计算

    PWM 的占空比 = TIM_OCInitStructure.TIM_Pulse / TIM_Period

    • PSC=0Period=99Pulse=20,占空比 = $ \frac{20}{100} = 20% $
    • PSC=36Period=99Pulse=20,占空比同样是 20%

    2. 频率对电机的影响

    • 高频 PWM(如 PSC=0):占空比虽然相同,但由于频率高,电流变化快,可能导致电机无法稳定运行,甚至无法启动。
    • 低频 PWM(如 PSC=36):占空比相同,但频率低,电机更容易响应,因此更容易启动。

    🔄 为什么反转 Speed=-20 时可以转动?

    这是因为反转控制逻辑中,GPIO 引脚被设置为反向,可能触发了电机的反向运行,即使 PWM 占空比较低也能运行。


    ✅ 解决方案

    为了使电机在 PSC=1 时也能正常运行,建议采取以下措施:

    1. 调整 PWM 参数,确保频率适合电机驱动

    加粗重点:
    建议将 TIM_Prescaler 设为 36 左右,以降低 PWM 频率,提高电机驱动稳定性。

    2. 增加最小占空比限制

    加粗重点:
    Motor_SetSpeed 函数中添加最小速度限制,防止占空比过小导致电机无法启动。

    3. 修改后的代码如下:

    void Motor_SetSpeed(int8_t Speed)
    {
        if(Speed >=0)
        {
            GPIO_SetBits(GPIOA, GPIO_Pin_4);
            GPIO_ResetBits(GPIOA, GPIO_Pin_5);
            
            // 添加最小速度限制
            if(Speed < 10) Speed = 10;
            PWM_SetCompare3(Speed);
        }
        else
        {
            GPIO_SetBits(GPIOA, GPIO_Pin_5);
            GPIO_ResetBits(GPIOA, GPIO_Pin_4);
            
            // 添加最小速度限制
            if(-Speed < 10) Speed = -10;
            PWM_SetCompare3(-Speed);
        }
    }
    

    📌 总结

    | 问题 | 原因 | 解决方案 | |------|------|----------| | PSC=1Speed=20 不转 | PWM 频率过高,电机无法响应 | 将 PSC 改为 36,降低 PWM 频率 | | PSC=36Speed=20 能转 | PWM 频率适中,电机能响应 | 保持 PSC=36 | | 反转 Speed=-20 时能转 | 反转逻辑触发了电机运行 | 无需修改 |


    如果你希望进一步优化电机控制,可以考虑使用 PID 控制或增加滤波电路来改善 PWM 波形质量。需要的话我可以提供相关代码示例。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月12日