Timer 使用stm32和2个定时器生成无限pwm

Timer 使用stm32和2个定时器生成无限pwm,timer,stm32,pwm,servo,Timer,Stm32,Pwm,Servo,我有10个伺服电机,我想把它们全部推导出来。我用2个定时器中断,不同的定时器频率,为每个引脚产生不同的PWM频率。连接到伺服的引脚,我用每个引脚导出一个伺服, 。代码如下: 编辑: 生成的pwm对端口A中的5个引脚工作正常。但当我增加端口数时,stm32挂起。 如何增加引脚?由于您忽略了一些重要的细节,如MCU的零件号或所谓的,我只能在这里猜测 当您向它添加更多指令时,计时器中断可能无法在下一个指令到来之前完成。您可以降低中断频率,但放弃软件中断并使用硬件PWM发生器更有意义 STM32通用定时

我有10个伺服电机,我想把它们全部推导出来。我用2个定时器中断,不同的定时器频率,为每个引脚产生不同的PWM频率。连接到伺服的引脚,我用每个引脚导出一个伺服, 。代码如下: 编辑:

生成的pwm对端口A中的5个引脚工作正常。但当我增加端口数时,stm32挂起。
如何增加引脚?

由于您忽略了一些重要的细节,如MCU的零件号或所谓的,我只能在这里猜测

当您向它添加更多指令时,计时器中断可能无法在下一个指令到来之前完成。您可以降低中断频率,但放弃软件中断并使用硬件PWM发生器更有意义

STM32通用定时器最多有4个PWM输出

编辑:在前面的端口中,您提到您正在使用STM32F103RET。该MCU实际上有24个硬件PWM输出


请参阅参考手册中关于通用定时器的章节,或ST应用说明AN2403 STM32跨系列定时器概述中关于如何使用它们的第2.5节。

由于您省略了一些重要细节,如MCU的零件号或所谓的,我只能在这里猜测

当您向它添加更多指令时,计时器中断可能无法在下一个指令到来之前完成。您可以降低中断频率,但放弃软件中断并使用硬件PWM发生器更有意义

STM32通用定时器最多有4个PWM输出

编辑:在前面的端口中,您提到您正在使用STM32F103RET。该MCU实际上有24个硬件PWM输出


请参阅参考手册中关于通用定时器的章节,或ST应用说明AN2403 STM32跨系列定时器概述中关于如何使用它们的第2.5节。

如果您有多个伺服电机而不是PWM通道,那么您可以使用类似TL594的PWM发生器IC,请在web上找到它

如果您的多个伺服电机多于PWM通道,那么您可以使用像TL594这样的PWM发生器IC,请在web上找到它

你有三个选择!1使用编码器ic或2 pwm发生器ic或3仅使用多臂cortex

你有三个选择!1使用编码器ic或2 pwm发生器ic或3仅使用多臂cortex

添加了更多详细信息@berendi添加了更多详细信息@berendi
     void TIM2_IRQHandler(void)
     {      

if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) 
{
    TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);   

    GPIO_ResetBits(SERVO_PORT , FUEL_PIN);
    GPIO_ResetBits(SERVO_PORT , SPEED_PIN);
    GPIO_ResetBits(SERVO_PORT , RPM_PIN);
    GPIO_ResetBits(SERVO_PORT , AIR_PRESURE_PIN);
    GPIO_ResetBits(SERVO_PORT , OIL_ENGINE_PRESURE_PIN);
    GPIO_ResetBits(SERVO_PORT , OIL_GEARBOX_PRESURE_PIN);
    GPIO_ResetBits(SERVO_PORT , OIL_TEMPERATURE_PIN);
    GPIO_ResetBits(SERVO_PORT , COOLER_WATER_TEMPERATURE_PIN);

    //GPIO_ResetBits(GPIOD,GPIO_Pin_3);

    CurrentDegree = 0;           
}
}

void TIM4_IRQHandler(void)
{
if ( TIM_GetITStatus(TIM4 , TIM_IT_Update) != RESET ) 
{
    TIM_ClearITPendingBit(TIM4 , TIM_FLAG_Update);        

    CurrentDegree++; 
    if(CurrentDegree < Desired)
    {
        GPIO_SetBits(GPIOD , GPIO_Pin_3);
    }
    else
    {
        GPIO_ResetBits(GPIOD,GPIO_Pin_3);       
    } 

    if(CurrentDegree < GetSpeed())
    {
        GPIO_SetBits(SERVO_PORT , SPEED_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , SPEED_PIN);
    }

    if(CurrentDegree < GetRpm())
    {
        GPIO_SetBits(SERVO_PORT , RPM_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , RPM_PIN);
    }       

    if(CurrentDegree < GetFuel())
    {
        GPIO_SetBits(SERVO_PORT , FUEL_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , FUEL_PIN);
    }

    if(CurrentDegree < GetAirPresure())
    {
        GPIO_SetBits(SERVO_PORT , AIR_PRESURE_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , AIR_PRESURE_PIN);
    }       

    if(CurrentDegree < GetOilEnginePresure())
    {
        GPIO_SetBits(SERVO_PORT , OIL_ENGINE_PRESURE_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , OIL_ENGINE_PRESURE_PIN);
    }   

    if(CurrentDegree < GetOilGearboxPresure())
    {
        GPIO_SetBits(SERVO_PORT , OIL_GEARBOX_PRESURE_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , OIL_GEARBOX_PRESURE_PIN);
    }  

    if(CurrentDegree < GetOilTemperature())
    {
        GPIO_SetBits(SERVO_PORT , OIL_TEMPERATURE_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , OIL_TEMPERATURE_PIN);
    } 

    if(CurrentDegree < GetCoolerWaterTemperature())
    {
        GPIO_SetBits(SERVO_PORT , COOLER_WATER_TEMPERATURE_PIN);
    }
    else
    {
        GPIO_ResetBits(SERVO_PORT , COOLER_WATER_TEMPERATURE_PIN);
    }     
   }     
 }