guoqing_ 2024-02-13 01:15 采纳率: 46.2%
浏览 4

stm32 pwm输出 宽频调制

stm32f103C8 pwm输出 但连接两个电机后(通过L298N)发现可以控制方向但是转速没有变化


#include "pwm.h"
#include "stm32f10x.h" 
#include "stm32f10x_tim.h"
 
void AIN_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    //AIN1
    RCC_APB2PeriphClockCmd(AIN1_GPIO_CLK,ENABLE);         //开启时钟
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽输出
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;     //50MHz
    GPIO_InitStruct.GPIO_Pin = AIN1_GPIO_PIN;
    GPIO_Init(AIN1_GPIO_PORT ,&GPIO_InitStruct);
    GPIO_SetBits(AIN1_GPIO_PORT,GPIO_Pin_All);            //初始化            
    //AIN2
    RCC_APB2PeriphClockCmd(AIN2_GPIO_CLK,ENABLE);
    GPIO_InitStruct.GPIO_Pin = AIN2_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(AIN2_GPIO_PORT ,&GPIO_InitStruct);
    GPIO_SetBits(AIN2_GPIO_PORT,GPIO_Pin_All);
    //BIN1
    RCC_APB2PeriphClockCmd(BIN1_GPIO_CLK,ENABLE);
    GPIO_InitStruct.GPIO_Pin = BIN1_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BIN1_GPIO_PORT ,&GPIO_InitStruct);
    GPIO_SetBits(BIN1_GPIO_PORT,GPIO_Pin_All);
    //BIN2
    RCC_APB2PeriphClockCmd(BIN2_GPIO_CLK,ENABLE);
    GPIO_InitStruct.GPIO_Pin = BIN2_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BIN2_GPIO_PORT ,&GPIO_InitStruct);
    GPIO_SetBits(BIN2_GPIO_PORT,GPIO_Pin_All);
}
static void GENERAL_TIM_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    //输出比较通道1GPIO初始化
    RCC_APB2PeriphClockCmd(GENERAL_TIM_CH1_GPIO_CLK, ENABLE);
    GPIO_InitStructure.GPIO_Pin   = GENERAL_TIM_CH1_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;    // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GENERAL_TIM_CH1_PORT, &GPIO_InitStructure);
    //输出比较通道2GPIO初始化
    RCC_APB2PeriphClockCmd(GENERAL_TIM_CH2_GPIO_CLK, ENABLE);
    GPIO_InitStructure.GPIO_Pin   = GENERAL_TIM_CH2_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;    // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GENERAL_TIM_CH2_PORT, &GPIO_InitStructure);
}
static void GENERAL_TIM_Mode_Config(void)
{
    /*--------------------时基结构体初始化-------------------------*/
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; // 将变量声明移动到函数开头
    TIM_OCInitTypeDef  TIM_OCInitStructure; // 将变量声明移动到函数开头

    // 开启定时器时钟,即内部时钟CK_INT=72M
    GENERAL_TIM_APBxClock_FUN(GENERAL_TIM_CLK, ENABLE);

    // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period = GENERAL_TIM_PERIOD;  
    // 驱动CNT计数器的时钟 = Fck_int/(psc+1)
    TIM_TimeBaseStructure.TIM_Prescaler = GENERAL_TIM_PSC;  
    // 初始化定时器
    TIM_TimeBaseInit(GENERAL_TIM, &TIM_TimeBaseStructure);

    /*--------------------输出比较结构体初始化-------------------*/      
    // 配置为PWM模式1
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    // 输出使能
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    // 输出通道电平极性配置
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    // 设置占空比大小GENERAL_TIM_CH1_PULSE=2000
    TIM_OCInitStructure.TIM_Pulse = GENERAL_TIM_CH1_PULSE;
    TIM_OC1Init(GENERAL_TIM, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);
    // 设置占空比大小GENERAL_TIM_CH2_PULSE=4000
    TIM_OCInitStructure.TIM_Pulse = GENERAL_TIM_CH2_PULSE;
    TIM_OC2Init(GENERAL_TIM, &TIM_OCInitStructure);
    TIM_OC2PreloadConfig(GENERAL_TIM, TIM_OCPreload_Enable);
    // 使能计数器
    TIM_Cmd(GENERAL_TIM, ENABLE);    
}

void GENERAL_TIM_Init(void)
{
    GENERAL_TIM_Mode_Config();
    GENERAL_TIM_GPIO_Config(); 
}
/*正负表示正转和反转,0表示停止
    PERIOD = 8000-1固定
    */
void GENERAL_TIM_Change_PULSE(int lun, int direction, int input_PULSE)
{
    
    int PULSE = (GENERAL_TIM_PERIOD + 1) * input_PULSE / 100;//input_PULSE设置为最高为100
 
    if(lun == 1)
    {
//        TIM_SetCompare1(TIM2, input_PULSE);
        GENERAL_TIM->CCR1 = PULSE;    
        if(direction == 0)//停止
        {
            GPIO_WriteBit(AIN1_GPIO_PORT,AIN1_GPIO_PIN,Bit_RESET);
            GPIO_WriteBit(AIN2_GPIO_PORT,AIN2_GPIO_PIN,Bit_RESET);
        }
        else if(direction == 1)//正转
        {
            GPIO_WriteBit(AIN1_GPIO_PORT,AIN1_GPIO_PIN,Bit_RESET);
            GPIO_WriteBit(AIN2_GPIO_PORT,AIN2_GPIO_PIN,Bit_SET);
        }
        else if(direction == -1)//反转
        {
            GPIO_WriteBit(AIN1_GPIO_PORT,AIN1_GPIO_PIN,Bit_SET);
            GPIO_WriteBit(AIN2_GPIO_PORT,AIN2_GPIO_PIN,Bit_RESET);
        }
    }
    if(lun == 2)
    {
//        TIM_SetCompare2(TIM2, input_PULSE);
        GENERAL_TIM->CCR2 = PULSE;
        if(direction == 0)//停止
        {
            GPIO_WriteBit(BIN1_GPIO_PORT,BIN1_GPIO_PIN,Bit_RESET);
            GPIO_WriteBit(BIN2_GPIO_PORT,BIN2_GPIO_PIN,Bit_RESET);
        }
        else if(direction == 1)//正转
        {
            GPIO_WriteBit(BIN1_GPIO_PORT,BIN1_GPIO_PIN,Bit_RESET);
            GPIO_WriteBit(BIN2_GPIO_PORT,BIN2_GPIO_PIN,Bit_SET);
        }
        else if(direction == -1)//反转
        {
            GPIO_WriteBit(BIN1_GPIO_PORT,BIN1_GPIO_PIN,Bit_SET);
            GPIO_WriteBit(BIN2_GPIO_PORT,BIN2_GPIO_PIN,Bit_RESET);
        }
    }
}
 
 
 
```c
#ifndef PWM_H
#define PWM_H
 
#include "stm32f10x.h"
 
// 这里我们使用通用定时器TIM2
 
#define            GENERAL_TIM                   TIM2
#define            GENERAL_TIM_APBxClock_FUN     RCC_APB1PeriphClockCmd
#define            GENERAL_TIM_CLK               RCC_APB1Periph_TIM2
// PWM 信号的频率 F = TIM_CLK/{(ARR+1)*(PSC+1)}
// 占空比是 PULSE / (PERIOD+1)
#define            GENERAL_TIM_PERIOD            (8000-1)
#define            GENERAL_TIM_PSC               (9-1)
#define            GENERAL_TIM_CH1_PULSE         2000
#define            GENERAL_TIM_CH2_PULSE         4000
 
#define            GENERAL_TIM_IRQ               TIM2_UP_IRQn
#define            GENERAL_TIM_IRQHandler        TIM2_UP_IRQHandler
 
//输出通道1
#define            GENERAL_TIM_CH1_GPIO_CLK      RCC_APB2Periph_GPIOA
#define            GENERAL_TIM_CH1_PORT          GPIOA
#define            GENERAL_TIM_CH1_PIN           GPIO_Pin_0
//输出通道2
#define            GENERAL_TIM_CH2_GPIO_CLK      RCC_APB2Periph_GPIOA
#define            GENERAL_TIM_CH2_PORT          GPIOA
#define            GENERAL_TIM_CH2_PIN           GPIO_Pin_1
//对PA0初始化---AIN1
#define            AIN1_GPIO_CLK                 RCC_APB2Periph_GPIOB
#define            AIN1_GPIO_PORT                 GPIOB
#define               AIN1_GPIO_PIN                 GPIO_Pin_14
//对PA1初始化---AIN2
#define            AIN2_GPIO_CLK                 RCC_APB2Periph_GPIOB
#define            AIN2_GPIO_PORT                GPIOB
#define            AIN2_GPIO_PIN                 GPIO_Pin_15
 
//对PB0初始化---BIN1
#define            BIN1_GPIO_CLK                 RCC_APB2Periph_GPIOB
#define            BIN1_GPIO_PORT                 GPIOB
#define            BIN1_GPIO_PIN                 GPIO_Pin_13
//对PB1初始化---BIN2
#define            BIN2_GPIO_CLK                 RCC_APB2Periph_GPIOB
#define            BIN2_GPIO_PORT                 GPIOB
#define            BIN2_GPIO_PIN                 GPIO_Pin_12
 
void AIN_GPIO_Config(void);
void GENERAL_TIM_Init(void);
void GENERAL_TIM_Change_PULSE(int lun, int direction, int input_PULSE);
 
#endif
```c
#include "stm32f10x_tim.h"
#include "delay.h"
#include "oled.h"
#include "pwm.h"
int main(void)
{
    delay_init();
    //OLED_Init();
    AIN_GPIO_Config();
  GENERAL_TIM_Init();
  GENERAL_TIM_Change_PULSE(2,-1,1);
    while(1)
    {
   //GENERAL_TIM_Change_PULSE(1,1,90);
     
    
      //OLED_ShowChinese(18,0,3,16,1);//景
        //OLED_Refresh();
        
    }
}



  • 写回答

6条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-02-13 01:17
    关注

    引自免费微信小程序:皆我百晓生

    根据您提供的代码片段,您正在尝试使用STM32F103C8T6的TIM2定时器产生PWM信号来控制通过L298N驱动的两个电机。您的问题是尽管能够控制电机的方向,但转速无法改变。

    从代码上看,您已经实现了基本的PWM输出配置,并且在GENERAL_TIM_Change_PULSE函数中调整了CCR寄存器(即占空比)以期望改变电机速度。但是,在main函数中,您只调用了对第二个电机进行反转并设置一个固定占空比的操作:

    GENERAL_TIM_Change_PULSE(2,-1,1);
    

    这将使第二个电机始终以固定的低占空比运行,因此不会观察到转速变化。

    要解决转速无法调节的问题,请确保在while循环中动态地调用GENERAL_TIM_Change_PULSE函数,并传递不同的input_PULSE值以实现转速控制。例如:

    int main(void)
    {
        delay_init();
        //OLED_Init();
        AIN_GPIO_Config();
        GENERAL_TIM_Init();
    
        while(1)
        {
            // 调整以下行中的input_PULSE值以改变电机转速
            int desired_speed = 50; // 可以是0-100之间的任何值,代表百分比
            GENERAL_TIM_Change_PULSE(1, 1, desired_speed); // 控制第一个电机正转,速度为desired_speed%
            GENERAL_TIM_Change_PULSE(2, -1, desired_speed); // 控制第二个电机反转,速度也为desired_speed%
    
            // 若有需要可以在这里加入其他控制逻辑或延时
        }
    }
    

    另外,请检查硬件连接是否正确,以及L298N驱动器是否正常工作,因为如果驱动器部分有问题也可能导致转速无法调整。同时,确认您的PWM频率和电机本身的响应频率匹配,过高或过低的PWM频率可能无法有效控制电机转速。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月13日