[应用相关] 【转】STM32之DRV8834电机驱动(PWM方式)

[复制链接]
2235|6
 楼主| 风萧寒 发表于 2017-2-24 12:38 | 显示全部楼层 |阅读模式
实验前提
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 | 显示全部楼层
楼主,代码呢,谁吃了?
我给你补上。
  1. //******************************************************************************            
  2. //name:             DRV8834.c           
  3. //introduce:        DRV8834驱动   
  4.          
  5. //changetime:       2016.10.18     
  6. //******************************************************************************   
  7. #include "stm32f10x.h"
  8. #include "DRV8834.h"
  9. #include "GUA_SysTick.h"

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

  12. #ifndef U8  
  13. typedef unsigned char U8;  
  14. #endif  
  15.   
  16. #ifndef U16  
  17. typedef unsigned short U16;  
  18. #endif  

  19. #ifndef U32  
  20. typedef unsigned long U32;  
  21. #endif  

  22. #ifndef int32  
  23. typedef signed long int32;  
  24. #endif

  25. //引脚宏定义
  26. #define GUA_DRV8834_SLEEP                                                                                GPIOA
  27. #define GUA_DRV8834_SLEEP_PIN                                                                GPIO_Pin_7

  28. #define GUA_DRV8834_M1                                                                                        GPIOB
  29. #define GUA_DRV8834_M1_PIN                                                                        GPIO_Pin_10

  30. #define GUA_DRV8834_M0                                                                                        GPIOB
  31. #define GUA_DRV8834_M0_PIN                                                                        GPIO_Pin_11

  32. #define GUA_DRV8834_DIR                                                                                        GPIOB
  33. #define GUA_DRV8834_DIR_PIN                                                                        GPIO_Pin_1

  34. #define GUA_DRV8834_STEP                                                                                GPIOB
  35. #define GUA_DRV8834_STEP_PIN                                                                GPIO_Pin_0

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

  39. /*********************内部函数************************/
  40. static void DRV8834_IO_Init(void);
  41. static void DRV8834_Set_Direction(int nDirection);
  42. static void DRV8834_Set_Size(U8 nSize);

  43. //******************************************************************************            
  44. //name:             DRV8834_IO_Init           
  45. //introduce:        电机驱动的IO初始化         
  46. //parameter:        none                 
  47. //return:           none         
  48. //author:           甜甜的大香瓜                 
  49. //email:            897503845[url=home.php?mod=space&uid=752448]@qq.com[/url]     
  50. //QQ group          香瓜单片机之STM8/STM32(164311667)                  
  51. //changetime:       2016.10.18                     
  52. //******************************************************************************
  53. static void DRV8834_IO_Init(void)
  54. {       
  55.         //IO结构体
  56.         GPIO_InitTypeDef GPIO_InitStructure;
  57.                
  58.         //时钟使能
  59.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);        
  60.        
  61.         //SLEEP配置
  62.         GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_SLEEP_PIN;                 
  63.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  64.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  65.         GPIO_Init(GUA_DRV8834_SLEEP, &GPIO_InitStructure);       
  66.        
  67.         //M1配置
  68.         GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_M1_PIN;                 
  69.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  70.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  71.         GPIO_Init(GUA_DRV8834_M1, &GPIO_InitStructure);       
  72.        
  73.         //M0配置
  74.         GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_M0_PIN;                 
  75.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  76.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  77.         GPIO_Init(GUA_DRV8834_M0, &GPIO_InitStructure);       

  78.         //DIR配置
  79.         GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_DIR_PIN;                 
  80.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  81.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  82.         GPIO_Init(GUA_DRV8834_DIR, &GPIO_InitStructure);       
  83.        
  84.         //STEP配置
  85.         GPIO_InitStructure.GPIO_Pin = GUA_DRV8834_STEP_PIN;                 
  86.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  87.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  88.         GPIO_Init(GUA_DRV8834_STEP, &GPIO_InitStructure);       
  89. }

  90. //******************************************************************************        
  91. //name:             DRV8834_Control
  92. //introduce:        DRV8834的配置      
  93. //parameter:        nDRV8834_control:需要配置的参数;nDRV8834_control_vaule:配置的数值         
  94. //return:           none      
  95. //author:           甜甜的大香瓜                 
  96. //email:            897503845@qq.com     
  97. //QQ group          香瓜单片机之STM8/STM32(164311667)                  
  98. //changetime:       2016.10.18                     
  99. //******************************************************************************
  100. void DRV8834_Control(U8 nDRV8834_control, U8 nDRV8834_control_vaule)
  101. {
  102.   switch(nDRV8834_control)
  103.   {
  104.     //睡眠模式选择
  105.     case DRV8834_CONTROL_SLEEP:
  106.     {                  
  107.       //睡眠
  108.       if(nDRV8834_control_vaule == DRV8834_CONTROL_SLEEP_ON)
  109.       {
  110.         GPIO_WriteBit(GUA_DRV8834_SLEEP, GUA_DRV8834_SLEEP_PIN, Bit_RESET);                //SLEEP 0      
  111.       }
  112.       
  113.       //禁止睡眠
  114.       if(nDRV8834_control_vaule == DRV8834_CONTROL_SLEEP_OFF)
  115.       {
  116.         GPIO_WriteBit(GUA_DRV8834_SLEEP, GUA_DRV8834_SLEEP_PIN, Bit_SET);                        //SLEEP 1      
  117.       }
  118.       
  119.       break;         
  120.     }

  121.     //步数选择
  122.     case DRV8834_CONTROL_MICROSTEP:
  123.     {                  
  124.       //满步(M1=0, M0=0)
  125.       if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_FULL)
  126.       {
  127.         GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_RESET);                                        //M1  0        
  128.         GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_RESET);                                        //M0  0      
  129.       }
  130.       
  131.       //1/2步(M1=0, M0=1)
  132.       if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_2)
  133.       {
  134.         GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_RESET);                                        //M1  0        
  135.         GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_SET);                                                //M0  1      
  136.       }
  137. /*      
  138.       //1/4步(M1=0, M0=Z)
  139.       if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_4)
  140.       {
  141.         GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_RESET);                                        //M1  0        
  142.         GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, GPIO_MODE_OUT_OD_HIZ_FAST);        // M0  Z      
  143.       }
  144. */
  145.       //1/8步(M1=1, M0=0)
  146.       if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_8)
  147.       {
  148.         GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_SET);                                                //M1  1      
  149.         GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_RESET);                                        //M0  0      
  150.       }
  151.       
  152.       //1/16步(M1=1, M0=1)
  153.       if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_16)
  154.       {
  155.         GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_SET);                                                //M1  1        
  156.         GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, Bit_SET);                                                //M0  1      
  157.       }
  158. /*
  159.       //1/32步(M1=1, M0=Z)
  160.       if(nDRV8834_control_vaule == DRV8834_CONTROL_MICROSTEP_1_32)
  161.       {
  162.         GPIO_WriteBit(GUA_DRV8834_M1, GUA_DRV8834_M1_PIN, Bit_SET);                                                //M1  1        
  163.         GPIO_WriteBit(GUA_DRV8834_M0, GUA_DRV8834_M0_PIN, GPIO_MODE_OUT_OD_HIZ_FAST);        // M0  Z      
  164.       }  
  165. */      
  166.       break;         
  167.     }

  168.     //方向选择
  169.     case DRV8834_CONTROL_DIR:
  170.     {                  
  171.       //正向
  172.       if(nDRV8834_control_vaule == DRV8834_CONTROL_DIR_POSITIVE)
  173.       {
  174.         GPIO_WriteBit(GUA_DRV8834_DIR, GUA_DRV8834_DIR_PIN, Bit_RESET);                                        //DIR 0               
  175.       }
  176.       
  177.       //反向
  178.       if(nDRV8834_control_vaule == DRV8834_CONTROL_DIR_NEGATIVE)
  179.       {
  180.         GPIO_WriteBit(GUA_DRV8834_DIR, GUA_DRV8834_DIR_PIN, Bit_SET);                                                //DIR 1   
  181.       }
  182.       
  183.       break;         
  184.     }

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

  193.       //拉低STEP
  194.       if(nDRV8834_control_vaule == DRV8834_CONTROL_STEP_LOW)
  195.       {
  196.         GPIO_WriteBit(GUA_DRV8834_STEP, GUA_DRV8834_STEP_PIN, Bit_RESET);                                //STEP 0               
  197.       }

  198.       //拉高STEP
  199.       if(nDRV8834_control_vaule == DRV8834_CONTROL_STEP_HIGH)
  200.       {
  201.         GPIO_WriteBit(GUA_DRV8834_STEP, GUA_DRV8834_STEP_PIN, Bit_SET);                                        //STEP 1               
  202.       }      
  203.       
  204.       break;         
  205.     }   

  206.     //其他
  207.     default:
  208.     {
  209.       break;         
  210.     }                     
  211.   }   
  212. }

  213. //******************************************************************************        
  214. //name:             DRV8834_Set_Direction        
  215. //introduce:        DRV8834的电机设置方向   
  216. //parameter:        nDirection:1为正向,0为反向      
  217. //return:           none      
  218. //author:           甜甜的大香瓜                 
  219. //email:            897503845@qq.com     
  220. //QQ group          香瓜单片机之STM8/STM32(164311667)                  
  221. //changetime:       2016.10.18                     
  222. //******************************************************************************
  223. static void DRV8834_Set_Direction(int nDirection)
  224. {
  225.   //方向
  226.   switch(nDirection)
  227.   {
  228.     //电机转轴朝上,逆时针,反向
  229.     case MOTOR_CONFIG_DIRECTION_NEGATIVE:
  230.     {
  231.       DRV8834_Control(DRV8834_CONTROL_DIR, DRV8834_CONTROL_DIR_NEGATIVE);        
  232.       break;      
  233.     }  

  234.     //电机转轴朝上,顺时针,正向   
  235.     case MOTOR_CONFIG_DIRECTION_POSITIVE:
  236.     {
  237.       DRV8834_Control(DRV8834_CONTROL_DIR, DRV8834_CONTROL_DIR_POSITIVE);        
  238.       break;      
  239.     }

  240.     //其他
  241.     default:
  242.     {
  243.       break;         
  244.     }
  245.   }
  246. }

  247. //******************************************************************************        
  248. //name:             DRV8834_Set_Size        
  249. //introduce:        DRV8834的电机设置步长   
  250. //parameter:        nSize:0为整步,1为半步      
  251. //return:           none      
  252. //author:           甜甜的大香瓜                 
  253. //email:            897503845@qq.com     
  254. //QQ group          香瓜单片机之STM8/STM32(164311667)                  
  255. //changetime:       2016.10.18                     
  256. //******************************************************************************
  257. static void DRV8834_Set_Size(U8 nSize)
  258. {
  259.   //步长大小
  260.   switch(nSize)
  261.   {
  262.     //整步
  263.     case MOTOR_CONFIG_SIZE_FULL:
  264.     {
  265.       DRV8834_Control(DRV8834_CONTROL_MICROSTEP, DRV8834_CONTROL_MICROSTEP_FULL);         
  266.       break;      
  267.     }
  268.   
  269.     //半步
  270.     case MOTOR_CONFIG_SIZE_1_2:
  271.     {
  272.       DRV8834_Control(DRV8834_CONTROL_MICROSTEP, DRV8834_CONTROL_MICROSTEP_1_2);         
  273.       break;      
  274.     }
  275.    
  276.     //其他
  277.     default:
  278.     {
  279.       break;         
  280.     }
  281.   }
  282. }

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

  308.   //设置步长
  309.   DRV8834_Set_Size(nSize);

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

  312.   
  313.   //电机转动
  314.   while(nSteps && (pMotor_Config->Status == MOTOR_CONFIG_STATUS_ACTIVE))
  315.   {
  316.     //计算
  317.     nSteps--;                                                           //计算剩余步数
  318.     pMotor_Config->DirectionPosition += nDirection*1;                   //每走1步,计算一次位移
  319.     pMotor_Config->StepsCount++;                                        //计算走过的步数
  320.       
  321.     //STEP低
  322.     DRV8834_Control(DRV8834_CONTROL_STEP, DRV8834_CONTROL_STEP_LOW);
  323.    
  324.     //延时
  325.     GUA_Delay_us(nPulse_duration);
  326.    
  327.     //STEP高
  328.     DRV8834_Control(DRV8834_CONTROL_STEP, DRV8834_CONTROL_STEP_HIGH);
  329.    
  330.     //延时
  331.     GUA_Delay_us(nPulse_duration);
  332.   }
  333.   
  334.   //清除状态
  335.   pMotor_Config->DirectionSteps = 0;
  336.   pMotor_Config->Status = MOTOR_CONFIG_STATUS_IDLE;
  337.   
  338.   //睡眠
  339.   DRV8834_Control(DRV8834_CONTROL_SLEEP, DRV8834_CONTROL_SLEEP_ON);   

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

  346. //******************************************************************************        
  347. //name:             DRV8834_Init        
  348. //introduce:        DRV8834的初始化      
  349. //parameter:        none      
  350. //return:           none      
  351. //author:           甜甜的大香瓜                 
  352. //email:            897503845@qq.com     
  353. //QQ group          香瓜单片机之STM8/STM32(164311667)                  
  354. //changetime:       2016.10.18                     
  355. //******************************************************************************
  356. void DRV8834_Init(void)
  357. {
  358.   //IO初始化
  359.   DRV8834_IO_Init();       
  360.        
  361.   //睡眠
  362.   DRV8834_Control(DRV8834_CONTROL_SLEEP, DRV8834_CONTROL_SLEEP_ON);

  363.   //nENBL使能
  364.   DRV8834_Control(DRV8834_CONTROL_OUTPUTS, DRV8834_CONTROL_OUTPUTS_ENABLE);
  365.   
  366.   //STEP低
  367.   DRV8834_Control(DRV8834_CONTROL_STEP, DRV8834_CONTROL_STEP_INIT);
  368. }
yiyigirl2014 发表于 2017-2-24 21:32 | 显示全部楼层
  1. //******************************************************************************            
  2. //name:             GUA_Test           
  3. //introduce:        测试代码         
  4. //parameter:        none                 
  5. //return:           none         
  6.                
  7. //******************************************************************************
  8. #define DRV8834_STEP_PER_CIRCLE                  (int32)(15331)   //电机转动一圈的步数
  9. static void GUA_Test(void)
  10. {   
  11.   while(1)
  12.   {
  13.     //X +360°
  14.     stMotor_Config.DirectionSteps = DRV8834_STEP_PER_CIRCLE;                          //X步数,4字节
  15.     stMotor_Config.PulsePerSecond = 700;                                              //X速度,2字节
  16.     stMotor_Config.Size = 0x00;                                                       //X步长,1字节
  17.     stMotor_Config.Status = MOTOR_CONFIG_STATUS_ACTIVE;                               //电机X启动,1字节
  18.    
  19.     DRV8834_Step_Move(&stMotor_Config);
  20.         }
  21. }       
yiyigirl2014 发表于 2017-2-24 21:35 | 显示全部楼层
本帖最后由 yiyigirl2014 于 2017-2-24 21:37 编辑

0J4344.600_看图王.jpg
yiyigirl2014 发表于 2017-2-24 21:41 | 显示全部楼层
yiyigirl2014 发表于 2017-2-24 21:42 | 显示全部楼层
zhuotuzi 发表于 2017-2-25 00:00 | 显示全部楼层
楼上的牛人提供的图拉轰。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

134

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部