认识电机

直流电机

直流电机(Direct Current Machine)是指能将直流电能转换成机械能(直流电动机)或将机械能转换成直流电能(直流发电机)的旋转电机。
它是能实现直流电能和机械能互相转换的电机。当它作电动机运行时是直流电动机,将电能转换为机械能;作发电机运行时是直流发电机,将机械能转换为电能。主要用于电动工具、洗衣机、空气净化器、玩具等小家电中,用于传输转矩和增加设备的灵活性。
image.png

直流减速电机

直流减速电机,即齿轮减速电机,是在普通直流电机的基础上,加上配套齿轮减速箱。齿轮减速箱的作用是,提供较低的转速,较大的力矩。同时,齿轮箱不同的减速比可以提供不同的转速和力矩。这大大提高了,直流电机在自动化行业中的使用率。

N20减速电机是一种广泛应用于电子设备、玩具、工业机器人、医疗器械、包装设备、办公设备、家用电器等领域的精密减速电机。它的电机结构紧凑、精度高、噪音小、承载能力强,可以在高速运转时保持平稳的运行状态,广泛应用于各种需要高精度、高效率、高可靠性的场合。

如下图所示, 我们可以看到N20减速电机其实是在普通电机的基础上增加了齿轮减速箱,从而实现了降低转速增大扭矩的目的.
03-电机驱动 - 图3

减速器的原理

要想理解减速器的原理, 我们先来回顾一下初二物理的杠杆原理。如下图所示,在杠杆的一端放置一个球,我们要撬动这个球,假设F不变,如何才能轻松的撬动这个球呢? 我们就需要来计算力矩,力矩的公式:力矩=力臂*力
image.png

  • 力矩(torque)是描述一个力如何使物体产生旋转的物理量。
  • 力臂是力与旋转轴之间的垂直距离。
  • 当力臂增大时,同样大小的力将产生更大的力矩,从而使物体更容易旋转。这就是为什么使用扳手时,手柄越长,旋转螺丝或螺母就越容易的原因。

如下图所示,我将当前案例的力臂划分出来。当F不变,我们增加力臂,就可以轻松将球撬动. 这也就是为什么有人吹牛,给我一个支点我能撬起月球.
image.png
明白了上面的原理, 下面我们再来分析一下电机的减速器, 上面介绍的是一个比较复杂的减速器,下面我们以两个齿轮为例,来解释一下为什么增加了减速箱之后,电机转速降低,力矩增大.
image.png
当电机转动之后,绿色小圆产生的力矩为M1 = FR, 那么红色圆输出的力矩为:M2 = F2R

下图是一张更加精密的减速电机齿轮箱

03-电机驱动 - 图7

在本次课程中,我们所使用的是这种TT马达, 它同样是普通电机加上减速齿轮构造而成.

223.png
接线方式如下:
224.png
225.png
image.png

驱动芯片介绍

03-电机驱动 - 图12
注意: 模块已经默认是启动的状态,所以EEP引脚不焊, ULT引脚如不需要,也可以不焊

PWM方式控制

下面我们来介绍一下如何使用PWM方式驱动电机, 电机连接在驱动模块上面, 每个电机由两路PWM控制.
若想电机转动, 我们只需要将其中一路PWM复制, 另外一路PWM置为0即可

  1. 正转: PWM1=pwm, PWM2=0
  2. 反转: PWM1=0, PWM2=pwm

下图为电机转动时, 电流的流向图
image.png

电路原理图

image.png

示例代码

PWM控制

  1. timer_channel_output_pulse_value_config(TIMER4, TIMER_CH_2, 0);
  2. timer_channel_output_pulse_value_config(TIMER4, TIMER_CH_3,pwm);

定时器初始化示例

  1. #include "bsp_drv8833.h"
  2. #include <stdio.h>
  3. #define RCU_MOTOR_L1 RCU_GPIOA
  4. #define PORT_MOTOR_L1 GPIOA
  5. #define PIN_MOTOR_L1 GPIO_PIN_0
  6. #define TIMER_MOTOR_L1 TIMER4
  7. #define TIMER_MOTOR_CHANNEL TIMER_CH_0
  8. #define RCU_MOTOR_L2 RCU_GPIOA
  9. #define PORT_MOTOR_L2 GPIOA
  10. #define PIN_MOTOR_L2 GPIO_PIN_1
  11. #define TIMER_MOTOR_L2 TIMER4
  12. #define TIMER_MOTOR_L2_CHANNEL TIMER_CH_1
  13. #define RCU_MOTOR_R1 RCU_GPIOA
  14. #define PORT_MOTOR_R1 GPIOA
  15. #define PIN_MOTOR_R1 GPIO_PIN_2
  16. #define TIMER_MOTOR_R1 TIMER4
  17. #define TIMER_MOTOR_R1_CHANNEL TIMER_CH_2
  18. #define RCU_MOTOR_R2 RCU_GPIOA
  19. #define PORT_MOTOR_R2 GPIOA
  20. #define PIN_MOTOR_R2 GPIO_PIN_3
  21. #define TIMER_MOTOR_R2 TIMER4
  22. #define TIMER_MOTOR_R2_CHANNEL TIMER_CH_3
  23. #define MAX_PWM_VALUE 9999
  24. void bsp_drv8833_gpio_init(){
  25. rcu_periph_clock_enable(RCU_MOTOR_L1);
  26. gpio_af_set(PORT_MOTOR_L1,GPIO_AF_2,PIN_MOTOR_L1);
  27. gpio_mode_set(PORT_MOTOR_L1,GPIO_MODE_AF,GPIO_PUPD_PULLDOWN,PIN_MOTOR_L1);
  28. gpio_output_options_set(PORT_MOTOR_L1,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,PIN_MOTOR_L1);
  29. gpio_bit_write(PORT_MOTOR_L1,PIN_MOTOR_L1,RESET);
  30. rcu_periph_clock_enable(RCU_MOTOR_L2);
  31. gpio_af_set(PORT_MOTOR_L2,GPIO_AF_2,PIN_MOTOR_L2);
  32. gpio_mode_set(PORT_MOTOR_L2,GPIO_MODE_AF,GPIO_PUPD_PULLDOWN,PIN_MOTOR_L2);
  33. gpio_output_options_set(PORT_MOTOR_L2,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,PIN_MOTOR_L2);
  34. gpio_bit_write(PORT_MOTOR_L2,PIN_MOTOR_L2,RESET);
  35. /**********************************************************/
  36. rcu_periph_clock_enable(RCU_MOTOR_R1);
  37. gpio_af_set(PORT_MOTOR_R1,GPIO_AF_2,PIN_MOTOR_R1);
  38. gpio_mode_set(PORT_MOTOR_R1,GPIO_MODE_AF,GPIO_PUPD_PULLDOWN,PIN_MOTOR_R1);
  39. gpio_output_options_set(PORT_MOTOR_R1,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,PIN_MOTOR_R1);
  40. gpio_bit_write(PORT_MOTOR_R1,PIN_MOTOR_R1,RESET);
  41. rcu_periph_clock_enable(RCU_MOTOR_R2);
  42. gpio_af_set(PORT_MOTOR_R2,GPIO_AF_2,PIN_MOTOR_R2);
  43. gpio_mode_set(PORT_MOTOR_R2,GPIO_MODE_AF,GPIO_PUPD_PULLDOWN,PIN_MOTOR_R2);
  44. gpio_output_options_set(PORT_MOTOR_R2,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,PIN_MOTOR_R2);
  45. gpio_bit_write(PORT_MOTOR_R2,PIN_MOTOR_R2,RESET);
  46. }
  47. void bsp_drv8833_timer_init(){
  48. rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
  49. rcu_periph_clock_enable(RCU_TIMER4);
  50. timer_parameter_struct timer_parameter;
  51. timer_oc_parameter_struct timer_oc_parameter;
  52. timer_deinit(TIMER4);
  53. timer_struct_para_init(&timer_parameter);
  54. timer_parameter.period = 10000 - 1;
  55. timer_parameter.prescaler = 240 - 1;
  56. timer_init(TIMER4,&timer_parameter);
  57. // 输出参数的初始化
  58. timer_channel_output_struct_para_init(&timer_oc_parameter);
  59. timer_oc_parameter.outputstate = TIMER_CCX_ENABLE;
  60. // 通道配置
  61. timer_channel_output_config(TIMER4,TIMER_CH_0,&timer_oc_parameter);
  62. timer_channel_output_config(TIMER4,TIMER_CH_1,&timer_oc_parameter);
  63. timer_channel_output_config(TIMER4,TIMER_CH_2,&timer_oc_parameter);
  64. timer_channel_output_config(TIMER4,TIMER_CH_3,&timer_oc_parameter);
  65. // 初始占空比配置
  66. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_0,0);
  67. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_1,0);
  68. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_2,0);
  69. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_3,0);
  70. timer_channel_output_mode_config(TIMER4,TIMER_CH_0,TIMER_OC_MODE_PWM0);
  71. timer_channel_output_mode_config(TIMER4,TIMER_CH_1,TIMER_OC_MODE_PWM0);
  72. timer_channel_output_mode_config(TIMER4,TIMER_CH_2,TIMER_OC_MODE_PWM0);
  73. timer_channel_output_mode_config(TIMER4,TIMER_CH_3,TIMER_OC_MODE_PWM0);
  74. timer_channel_output_shadow_config(TIMER4,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
  75. timer_channel_output_shadow_config(TIMER4,TIMER_CH_1,TIMER_OC_SHADOW_ENABLE);
  76. timer_channel_output_shadow_config(TIMER4,TIMER_CH_2,TIMER_OC_SHADOW_ENABLE);
  77. timer_channel_output_shadow_config(TIMER4,TIMER_CH_3,TIMER_OC_SHADOW_ENABLE);
  78. timer_primary_output_config(TIMER4,ENABLE);
  79. timer_enable(TIMER4);
  80. }
  81. void bsp_drv8833_init(void){
  82. bsp_drv8833_gpio_init();
  83. bsp_drv8833_timer_init();
  84. }
  85. void bsp_drv8833_set(int left, int right){
  86. if(left > MAX_PWM_VALUE) left = MAX_PWM_VALUE;
  87. if(left < -MAX_PWM_VALUE) left = -MAX_PWM_VALUE;
  88. if(right > MAX_PWM_VALUE) right = MAX_PWM_VALUE;
  89. if(right < -MAX_PWM_VALUE) right = -MAX_PWM_VALUE;
  90. if(left > 0){
  91. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_0,left);
  92. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_1,0);
  93. }else{
  94. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_0,0);
  95. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_1,-left);
  96. }
  97. if(right < 0){
  98. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_2,0);
  99. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_3,right);
  100. }else{
  101. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_2,-right);
  102. timer_channel_output_pulse_value_config(TIMER4,TIMER_CH_3,0);
  103. }
  104. }
  105. void bsp_drv8833_test(){
  106. bsp_drv8833_init();
  107. int pwm = 0;
  108. while(1){
  109. pwm += 300;
  110. bsp_drv8833_set(pwm,pwm);
  111. delay_1ms(2000);
  112. if(pwm > MAX_PWM_VALUE) pwm = 0;
  113. printf("pwm: %d\n",pwm);
  114. }
  115. }