打印

新手一枚,求助

[复制链接]
534|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
binoo7|  楼主 | 2019-6-5 15:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
IO, pi, TI, gp, GPIO
我现在用STM32+L297+L298控制两项步进电机,现在输出PWM波没有问题,可是电机转动一顿一顿的不流畅,而且我调节频率的时候感觉有问题,求各位大神帮忙看一下哪里有问题了
#include "MOTOR.h"

/*

      两个电机管脚分配
                        step3       step2   
                        PD13        PC6
                        dirction3   dirction2
                        PD15        PC7
                        en3         en2
                        PD14        PC8
                       
*/

//      en3         en2
//                        PD14        PC8
//   dirction3      dirction2
//                  PD15        PC7
        void MOTOR_En_Dir(void)
                 {
         GPIO_InitTypeDef  GPIO_InitStructure;
                          //3#使能端设置
                                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
                       
                                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);         //开启gpioD时钟
                                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;                                       //gpiod.14
                                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    //推挽输出
                                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   //IO口速度为50MHz
                                 GPIO_Init(GPIOD, &GPIO_InitStructure);                                                 //初始化
                    //3#方向设置
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);         //开启GPIOD时钟
                                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;                                       //GPIOD.15
                                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    //推挽输出
                                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   //IO口速度为50MHz
                                 GPIO_Init(GPIOD, &GPIO_InitStructure);                                                 //初始化
                          //3#输出比较设置   TIM4_CH2
                                        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);   //开启GPIOD时钟
                                        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;              //GPIOD.13
                                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         //复用推挽输出
                                        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //IO口速度为50MHz
                                        GPIO_Init(GPIOD, &GPIO_InitStructure);                  //初始化
                          //2#使能设置
                           RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);         //开启GPIOC时钟
                                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                                       //GPIOC.8
                                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    //推挽输出
                                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   //IO口速度为50MHz
                                 GPIO_Init(GPIOC, &GPIO_InitStructure);                                                 //初始化
                          //2#方向设置
                           RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);         //开启GPIOC时钟
                                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                                       //GPIOC.7
                                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    //推挽输出
                                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   //IO口速度为50MHz
                                 GPIO_Init(GPIOC, &GPIO_InitStructure);                                                 //初始化
                                //2#输出比较设置   TIM4_CH2
                                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);   //开启GPIOC时钟
                                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;               //GPIOC.6
                                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         //复用推挽输出
                                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //IO口速度为50MHz
                                GPIO_Init(GPIOC, &GPIO_InitStructure);                  //初始化
                          
                               
//                                GPIO_ResetBits(GPIOD,GPIO_Pin_14);
//                                GPIO_ResetBits(GPIOC,GPIO_Pin_8);
                         GPIO_SetBits(GPIOC,GPIO_Pin_7);      
                         GPIO_SetBits(GPIOD,GPIO_Pin_15);
                         GPIO_SetBits(GPIOD,GPIO_Pin_14);      
                         GPIO_SetBits(GPIOC,GPIO_Pin_8);
                 }
///*
// * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
// * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
// * 另外三个成员是通用定时器和高级定时器才有.
// *-----------------------------------------------------------------------------
// *typedef struct
// *{ TIM_Prescaler            都有
// *        TIM_CounterMode                             TIMx,x[6,7]没有,其他都有
// *  TIM_Period               都有
// *  TIM_ClockDivision        TIMx,x[6,7]没有,其他都有
// *  TIM_RepetitionCounter    TIMx,x[1,8,15,16,17]才有
// *}TIM_TimeBaseInitTypeDef;
// *-----------------------------------------------------------------------------
// */

/* ----------------   PWM信号 周期和占空比的计算--------------- */
// ARR :自动重装载寄存器的值
// CLK_cnt:计数器的时钟,等于 Fck_int / (psc+1) = 72M/(psc+1)
// PWM 信号的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M
// 占空比P=CCR/(ARR+1)
//    step1      step2   
//                PD13       PC6
//    TIM4_CH2   TIM3_CH1
                void MOTOR2_Step(u16 arr,u16 psc)
                {
               
                        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
                        TIM_OCInitTypeDef  TIM_OCInitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  // 开启定时器时钟,即内部时钟CK_INT=72M
  GPIO_PinRemapConfig(GPIO_FullRemap_TIM3 , ENABLE);
/*--------------------时基结构体初始化-------------------------*/
       
  
       
        TIM_TimeBaseStructure.TIM_Period=arr;                           // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
        TIM_TimeBaseStructure.TIM_Prescaler= psc;                              // 驱动CNT计数器的时钟 = Fck_int/(psc+1)
        TIM_TimeBaseStructure.TIM_ClockDivision=0;                      // 时钟分频因子 ,配置死区时间时需要用到       
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;        // 计数器计数模式,设置为向上计数       
        TIM_TimeBaseStructure.TIM_RepetitionCounter=0;                  // 重复计数器的值,没用到不用管
        TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure);                // 初始化定时器

        /*--------------------输出比较结构体初始化-------------------*/       

       
       
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;             // 配置为PWM模式1
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;        // 输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;            // 输出通道电平极性配置       
        TIM_OCInitStructure.TIM_Pulse = 2;                                  // 输出比较通道 1
        TIM_OC1Init(TIM3, &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
        TIM_Cmd(TIM3, ENABLE);// 使能计数器

                }
               
void MOTOR3_Step(u16 arrc,u16 pscc)
                {
                TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure3;
          TIM_OCInitTypeDef  TIM_OCInitStructure3;
                       
  // 开启定时器时钟,即内部时钟CK_INT=72M
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
                GPIO_PinRemapConfig(GPIO_Remap_TIM4 , ENABLE);  
/*--------------------时基结构体初始化-------------------------*/
        //
       
  
                       
        TIM_TimeBaseStructure3.TIM_Period = arrc;          // 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
               
        TIM_TimeBaseStructure3.TIM_Prescaler=pscc ;                // 驱动CNT计数器的时钟 = Fck_int/(psc+1)       
                       
        TIM_TimeBaseStructure3.TIM_ClockDivision=2;        // 时钟分频因子 ,配置死区时间时需要用到       
                       
        TIM_TimeBaseStructure3.TIM_CounterMode=TIM_CounterMode_Up;        // 计数器计数模式,设置为向上计数       
       
        TIM_TimeBaseStructure3.TIM_RepetitionCounter=0;        // 重复计数器的值,没用到不用管
       
        TIM_TimeBaseInit( TIM4, &TIM_TimeBaseStructure3);  // 初始化定时器

        /*--------------------输出比较结构体初始化-------------------*/       
        TIM_OCInitStructure3.TIM_OCMode = TIM_OCMode_PWM1;             // 配置为PWM模式1
        TIM_OCInitStructure3.TIM_OutputState = TIM_OutputState_Enable; // 输出使能
        TIM_OCInitStructure3.TIM_OCPolarity = TIM_OCPolarity_High;           // 输出通道电平极性配置       
        TIM_OCInitStructure3.TIM_Pulse = 5;                            // 输出比较通道 2
        TIM_OC2Init(TIM4, &TIM_OCInitStructure3);
        TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
        TIM_Cmd(TIM4, ENABLE);                                         // 使能计数器
}

                void MOTOR_Init(void)
                {
                 //

                       
                        MOTOR_En_Dir();
                        MOTOR2_Step(8999,799);        //PWM频率=72000000/(9000*8)  =1Khz
                                                //PWM频率=72000000/(9000*80) =100hz
                                          //PWM频率=72000000/(9000*800)=10hz
                         
                        MOTOR3_Step(8999,799);        //PWM频率=72000000/(9000*8)  =1Khz
                                                //PWM频率=72000000/(9000*80) =100hz
                                          //PWM频率=72000000/(9000*800)=10hz
                       
                }
                 


使用特权

评论回复

相关帖子

沙发
binoo7|  楼主 | 2019-6-5 16:35 | 只看该作者
已经解决,占空比问题

使用特权

评论回复
评论
dirtwillfly 2019-6-5 22:02 回复TA
能者自答 
板凳
binoo7|  楼主 | 2019-6-5 16:49 | 只看该作者
TIM_TimeBaseStructure3.TIM_ClockDivision=2;        // 时钟分频因子 ,配置死区时间时需要用到 改成0
TIM_OCInitStructure3.TIM_Pulse = 5;改成arr的一半左右     即可

使用特权

评论回复
评论
dirtwillfly 2019-6-5 22:02 回复TA
感谢分享 
地板
binoo7|  楼主 | 2019-6-9 12:50 | 只看该作者
还有一个我不理解的地方,pwm也可以改变评率控制电机转速,为什么硬石的视频里要用输出比较呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

454

帖子

8

粉丝