打印
[应用相关]

【转】STM32之DRV8834电机驱动(PWM方式)

[复制链接]
1939|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
实验前提
1、在进行本文步骤前,请先阅读以下博文:
1)《STM32之DRV8834电机驱动(IO方式)》:http://blog.csdn.net/feilusia/article/details/52853951


2、在进行本文步骤前,请先实现以下博文:

1)《STM32之系统滴答定时器》:http://blog.csdn.net/feilusia/article/details/52835711


2)《STM32之timer2的精准延时》:http://blog.csdn.NET/feilusia/article/details/54434274
3)《STM32之timer3产生PWM》:http://blog.csdn.Net/feilusia/article/details/53634882

五、基础知识
暂无



六、实验步骤
1、编写并添加电机驱动

3)工程中添加GUA_DRV8834.c



4)在MDK设置中添加驱动源文件路径



2、在应用层中调用
1)添加头文件(main.c中)
[cpp] view plain copy


  • #include "GUA_DRV8834.h"  


2)添加驱动初始化代码(main.c的main函数中)

[cpp] view plain copy


  • //电机初始化   
  • GUA_DRV8834_Init();  


3)添加测试代码(main.c中)


①添加一个电机转一圈的测试代码(main.c中)
[cpp] view plain copy


  • //******************************************************************************              
  • //name:             GUA_Test            
  • //introduce:        测试代码           
  • //parameter:        none                  
  • //return:           none           
  • //author:           甜甜的大香瓜                  
  • //email:            897503845@qq.com      
  • //QQ group          香瓜单片机之STM8/STM32(164311667)                    
  • //changetime:       2017.02.12                       
  • //******************************************************************************  
  • #define GUA_DRV8834_STEP_PER_CIRCLE                  (GUA_U32)(15331)   //电机转动一圈的步数   
  • static void GUA_Test(void)  
  • {  
  •   GUA_U8 nGUA_Ret = 0;  
  •       
  •     //配置电机参数  
  •     stGUA_Motor_Config.DirectionSteps = GUA_DRV8834_STEP_PER_CIRCLE;    //步数,4字节   
  •     stGUA_Motor_Config.PulsePerSecond = 1000;                                                   //速度,2字节   
  •     stGUA_Motor_Config.Size = 0x00;                                                                     //步长,1字节                          
  •     stGUA_Motor_Config.Status = GUA_MOTOR_CONFIG_STATUS_ACTIVE;             //电机启动,1字节  
  •   
  •     //启动电机  
  •     GUA_DRV8834_Move(&stGUA_Motor_Config);  
  •       
  •     //时刻查询电机运行时间,到时则停止  
  •     while(1)  
  •     {  
  •         nGUA_Ret = GUA_DRV8834_CheckMoveResidueTime();  
  •         if(nGUA_Ret == GUA_CHECK_MOVE_RESIDUE_TIME_RESULT_ENDING)  
  •         {  
  •             GUA_DRV8834_Stop(&stGUA_Motor_Config);  
  •         }     
  •     }     
  • }     

由于我使用的电机除了电机自带的减速,还有外壳上的减速,因此一圈为15331步。
②添加测试代码的调用(main.c的main函数中)

[cpp] view plain copy


  • //测试代码   
  • GUA_Test();   

测试代码要放在初始化之后。


七、注意事项
暂无。

八、实验结果


仿真并设置断点在测试代码处,可发现电机转动至停止一共约15S多,这是因为一圈为15331步,速度设置为1000步每秒,计算可得约为15.331S。
因此实验成功。


沙发
yiyigirl2014| | 2017-2-24 21:31 | 只看该作者
楼主,代码呢,谁吃了?
我给你补上。
//******************************************************************************            
//name:             DRV8834.c           
//introduce:        DRV8834驱动   
         
//changetime:       2016.10.18     
//******************************************************************************   
#include "stm32f10x.h"
#include "DRV8834.h"
#include "GUA_SysTick.h"

/*********************宏定义************************/   
#define DRV8834_STEP_PER_CIRCLE                  (int32)(15331)   //电机转动一圈的步数

#ifndef U8  
typedef unsigned char U8;  
#endif  
  
#ifndef U16  
typedef unsigned short U16;  
#endif  

#ifndef U32  
typedef unsigned long U32;  
#endif  

#ifndef int32  
typedef signed long int32;  
#endif

//引脚宏定义
#define GUA_DRV8834_SLEEP                                                                                GPIOA
#define GUA_DRV8834_SLEEP_PIN                                                                GPIO_Pin_7

#define GUA_DRV8834_M1                                                                                        GPIOB
#define GUA_DRV8834_M1_PIN                                                                        GPIO_Pin_10

#define GUA_DRV8834_M0                                                                                        GPIOB
#define GUA_DRV8834_M0_PIN                                                                        GPIO_Pin_11

#define GUA_DRV8834_DIR                                                                                        GPIOB
#define GUA_DRV8834_DIR_PIN                                                                        GPIO_Pin_1

#define GUA_DRV8834_STEP                                                                                GPIOB
#define GUA_DRV8834_STEP_PIN                                                                GPIO_Pin_0

/*********************内部变量************************/  
//MOTOR_CONFIG stMotor_Config = {0x00000000,1500, 0x00, 0x00000000, MOTOR_CONFIG_STATUS_IDLE, 0x00000000}; //初始化电机参数为0步,1500个脉冲每秒的速度,整步,本次电机转动时长,空闲,当前为0位置
MOTOR_CONFIG stMotor_Config = {6000, 500, 0x00, 0x00000000, MOTOR_CONFIG_STATUS_IDLE, 0x00000000}; //初始化电机参数为0步,1500个脉冲每秒的速度,整步,本次电机转动时长,空闲,当前为0位置

/*********************内部函数************************/
static void DRV8834_IO_Init(void);
static void DRV8834_Set_Direction(int nDirection);
static void DRV8834_Set_Size(U8 nSize);

//******************************************************************************            
//name:             DRV8834_IO_Init           
//introduce:        电机驱动的IO初始化         
//parameter:        none                 
//return:           none         
//author:           甜甜的大香瓜                 
//email:            897503845[url=home.php?mod=space&uid=752448]@qq.com[/url]     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.10.18                     
//******************************************************************************
static void DRV8834_IO_Init(void)
{       
        //IO结构体
        GPIO_InitTypeDef GPIO_InitStructure;
               
        //时钟使能
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);        
       
        //SLEEP配置
        GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_SLEEP_PIN;                 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GUA_DRV8834_SLEEP, &GPIO_InitStructure);       
       
        //M1配置
        GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_M1_PIN;                 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GUA_DRV8834_M1, &GPIO_InitStructure);       
       
        //M0配置
        GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_M0_PIN;                 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GUA_DRV8834_M0, &GPIO_InitStructure);       

        //DIR配置
        GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_DIR_PIN;                 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GUA_DRV8834_DIR, &GPIO_InitStructure);       
       
        //STEP配置
        GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_STEP_PIN;                 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GUA_DRV8834_STEP, &GPIO_InitStructure);       
}

//******************************************************************************        
//name:             DRV8834_Control
//introduce:        DRV8834的配置      
//parameter:        nDRV8834_control:需要配置的参数;nDRV8834_control_vaule:配置的数值         
//return:           none      
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.10.18                     
//******************************************************************************
void DRV8834_Control(U8 nDRV8834_control, U8 nDRV8834_control_vaule)
{
  switch(nDRV8834_control)
  {
    //睡眠模式选择
    case DRV8834_CONTROL_SLEEP:
    {                  
      //睡眠
      if(nDRV8834_control_vaule == DRV8834_CONTROL_SLEEP_ON)
      {
        GPIO_WriteBit(GUA_DRV8834_SLEEP, GUA_DRV8834_SLEEP_PIN, Bit_RESET);                //SLEEP 0      
      }
      
      //禁止睡眠
      if(nDRV8834_control_vaule == DRV8834_CONTROL_SLEEP_OFF)
      {
        GPIO_WriteBit(GUA_DRV8834_SLEEP, GUA_DRV8834_SLEEP_PIN, Bit_SET);                        //SLEEP 1      
      }
      
      break;         
    }

    //步数选择
    case DRV8834_CONTROL_MICROSTEP:
    {                  
      //满步(M1=0, M0=0)
      if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_FULL)
      {
        GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_RESET);                                        //M1  0        
        GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_RESET);                                        //M0  0      
      }
      
      //1/2步(M1=0, M0=1)
      if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_2)
      {
        GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_RESET);                                        //M1  0        
        GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_SET);                                                //M0  1      
      }
/*      
      //1/4步(M1=0, M0=Z)
      if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_4)
      {
        GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_RESET);                                        //M1  0        
        GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, GPIO_MODE_OUT_OD_HIZ_FAST);        // M0  Z      
      }
*/
      //1/8步(M1=1, M0=0)
      if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_8)
      {
        GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_SET);                                                //M1  1      
        GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_RESET);                                        //M0  0      
      }
      
      //1/16步(M1=1, M0=1)
      if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_16)
      {
        GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_SET);                                                //M1  1        
        GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_SET);                                                //M0  1      
      }
/*
      //1/32步(M1=1, M0=Z)
      if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_32)
      {
        GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_SET);                                                //M1  1        
        GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, GPIO_MODE_OUT_OD_HIZ_FAST);        // M0  Z      
      }  
*/      
      break;         
    }

    //方向选择
    case DRV8834_CONTROL_DIR:
    {                  
      //正向
      if(nDRV8834_control_vaule == DRV8834_CONTROL_DIR_POSITIVE)
      {
        GPIO_WriteBit(GUA_DRV8834_DIR, GUA_DRV8834_DIR_PIN, Bit_RESET);                                        //DIR 0               
      }
      
      //反向
      if(nDRV8834_control_vaule == DRV8834_CONTROL_DIR_NEGATIVE)
      {
        GPIO_WriteBit(GUA_DRV8834_DIR, GUA_DRV8834_DIR_PIN, Bit_SET);                                                //DIR 1   
      }
      
      break;         
    }

    //脉冲脚电平选择
    case DRV8834_CONTROL_STEP:
    {     
      //初始化时,拉低电平做好准备
      if(nDRV8834_control_vaule == DRV8834_CONTROL_STEP_INIT)
      {
        GPIO_WriteBit(GUA_DRV8834_STEP, GUA_DRV8834_STEP_PIN, Bit_RESET);                                //STEP 0               
      }

      //拉低STEP
      if(nDRV8834_control_vaule == DRV8834_CONTROL_STEP_LOW)
      {
        GPIO_WriteBit(GUA_DRV8834_STEP, GUA_DRV8834_STEP_PIN, Bit_RESET);                                //STEP 0               
      }

      //拉高STEP
      if(nDRV8834_control_vaule == DRV8834_CONTROL_STEP_HIGH)
      {
        GPIO_WriteBit(GUA_DRV8834_STEP, GUA_DRV8834_STEP_PIN, Bit_SET);                                        //STEP 1               
      }      
      
      break;         
    }   

    //其他
    default:
    {
      break;         
    }                     
  }   
}

//******************************************************************************        
//name:             DRV8834_Set_Direction        
//introduce:        DRV8834的电机设置方向   
//parameter:        nDirection:1为正向,0为反向      
//return:           none      
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.10.18                     
//******************************************************************************
static void DRV8834_Set_Direction(int nDirection)
{
  //方向
  switch(nDirection)
  {
    //电机转轴朝上,逆时针,反向
    case MOTOR_CONFIG_DIRECTION_NEGATIVE:
    {
      DRV8834_Control(DRV8834_CONTROL_DIR, DRV8834_CONTROL_DIR_NEGATIVE);        
      break;      
    }  

    //电机转轴朝上,顺时针,正向   
    case MOTOR_CONFIG_DIRECTION_POSITIVE:
    {
      DRV8834_Control(DRV8834_CONTROL_DIR, DRV8834_CONTROL_DIR_POSITIVE);        
      break;      
    }

    //其他
    default:
    {
      break;         
    }
  }
}

//******************************************************************************        
//name:             DRV8834_Set_Size        
//introduce:        DRV8834的电机设置步长   
//parameter:        nSize:0为整步,1为半步      
//return:           none      
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.10.18                     
//******************************************************************************
static void DRV8834_Set_Size(U8 nSize)
{
  //步长大小
  switch(nSize)
  {
    //整步
    case MOTOR_CONFIG_SIZE_FULL:
    {
      DRV8834_Control(DRV8834_CONTROL_MICROSTEP, DRV8834_CONTROL_MICROSTEP_FULL);         
      break;      
    }
  
    //半步
    case MOTOR_CONFIG_SIZE_1_2:
    {
      DRV8834_Control(DRV8834_CONTROL_MICROSTEP, DRV8834_CONTROL_MICROSTEP_1_2);         
      break;      
    }
   
    //其他
    default:
    {
      break;         
    }
  }
}

//******************************************************************************        
//name:             DRV8834_Step_Move        
//introduce:        DRV8834的电机控制     
//parameter:        pMotor_Config:电机核心参数结构体数据      
//return:           运行时间      
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.10.18                     
//******************************************************************************
U32 DRV8834_Step_Move(MOTOR_CONFIG *pMotor_Config)
{
  int32 nSteps = pMotor_Config->DirectionSteps;                         //保存步数                                                   
  int32 nDirection = (nSteps >= 0)?1:-1;                                //计算方向
  U8    nSize = pMotor_Config->Size;                                    //保存步长  
  U32   nPulse_duration = (500000L/pMotor_Config->PulsePerSecond);            //计算延时时间:1000000uS/每秒步数=需要几S,再/2为一个周期均分两段
       
  //唤醒
  DRV8834_Control(DRV8834_CONTROL_SLEEP, DRV8834_CONTROL_SLEEP_OFF);
  
  //获取步数
  nSteps = nSteps * nDirection;                                         //获取步数
   
  //设置方向
  DRV8834_Set_Direction(nDirection);

  //设置步长
  DRV8834_Set_Size(nSize);

  //清除步数计算值
  pMotor_Config->StepsCount = 0;

  
  //电机转动
  while(nSteps && (pMotor_Config->Status == MOTOR_CONFIG_STATUS_ACTIVE))
  {
    //计算
    nSteps--;                                                           //计算剩余步数
    pMotor_Config->DirectionPosition += nDirection*1;                   //每走1步,计算一次位移
    pMotor_Config->StepsCount++;                                        //计算走过的步数
      
    //STEP低
    DRV8834_Control(DRV8834_CONTROL_STEP, DRV8834_CONTROL_STEP_LOW);
   
    //延时
    GUA_Delay_us(nPulse_duration);
   
    //STEP高
    DRV8834_Control(DRV8834_CONTROL_STEP, DRV8834_CONTROL_STEP_HIGH);
   
    //延时
    GUA_Delay_us(nPulse_duration);
  }
  
  //清除状态
  pMotor_Config->DirectionSteps = 0;
  pMotor_Config->Status = MOTOR_CONFIG_STATUS_IDLE;
  
  //睡眠
  DRV8834_Control(DRV8834_CONTROL_SLEEP, DRV8834_CONTROL_SLEEP_ON);   

  //计算实际位移
  pMotor_Config->DirectionPosition %= DRV8834_STEP_PER_CIRCLE;                 //每DRV8834_STEP_PER_CIRCLE次为1圈,重新计数  
  
  //换算所用时间为ms为单位,实际走的步数*每步所花的ms数
  return(pMotor_Config->StepsCount*2*nPulse_duration/10);      
}

//******************************************************************************        
//name:             DRV8834_Init        
//introduce:        DRV8834的初始化      
//parameter:        none      
//return:           none      
//author:           甜甜的大香瓜                 
//email:            897503845@qq.com     
//QQ group          香瓜单片机之STM8/STM32(164311667)                  
//changetime:       2016.10.18                     
//******************************************************************************
void DRV8834_Init(void)
{
  //IO初始化
  DRV8834_IO_Init();       
       
  //睡眠
  DRV8834_Control(DRV8834_CONTROL_SLEEP, DRV8834_CONTROL_SLEEP_ON);

  //nENBL使能
  DRV8834_Control(DRV8834_CONTROL_OUTPUTS, DRV8834_CONTROL_OUTPUTS_ENABLE);
  
  //STEP低
  DRV8834_Control(DRV8834_CONTROL_STEP, DRV8834_CONTROL_STEP_INIT);
}

使用特权

评论回复
板凳
yiyigirl2014| | 2017-2-24 21:32 | 只看该作者
//******************************************************************************            
//name:             GUA_Test           
//introduce:        测试代码         
//parameter:        none                 
//return:           none         
               
//******************************************************************************
#define DRV8834_STEP_PER_CIRCLE                  (int32)(15331)   //电机转动一圈的步数
static void GUA_Test(void)
{   
  while(1)
  {
    //X +360°
    stMotor_Config.DirectionSteps = DRV8834_STEP_PER_CIRCLE;                          //X步数,4字节
    stMotor_Config.PulsePerSecond = 700;                                              //X速度,2字节
    stMotor_Config.Size = 0x00;                                                       //X步长,1字节
    stMotor_Config.Status = MOTOR_CONFIG_STATUS_ACTIVE;                               //电机X启动,1字节
   
    DRV8834_Step_Move(&stMotor_Config);
        }
}       

使用特权

评论回复
地板
yiyigirl2014| | 2017-2-24 21:35 | 只看该作者
本帖最后由 yiyigirl2014 于 2017-2-24 21:37 编辑

使用特权

评论回复
5
yiyigirl2014| | 2017-2-24 21:41 | 只看该作者

使用特权

评论回复
6
yiyigirl2014| | 2017-2-24 21:42 | 只看该作者

使用特权

评论回复
7
zhuotuzi| | 2017-2-25 00:00 | 只看该作者
楼上的牛人提供的图拉轰。

使用特权

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

本版积分规则

68

主题

134

帖子

3

粉丝