STM32驱动带编码器的直流减速电机
文章目录
- STM32驱动带编码器的直流减速电机
- 硬件材料
- MG310 直流减速电机
- 直流电机原理
- 减速器
- 实物接线
- 霍尔编码器
- TB6612电机驱动
- 接线说明
- 程序设计
- 定时器生成PWM驱动电机
- 速度计算
- 实验结果
- 程序下载
硬件材料
- 主控板:STM32F407ZG
- 直流减速电机:MG310(霍尔编码)
- 电机驱动:TB6612
- 7.4V电源
MG310 直流减速电机
直流电机原理
直流电机(DC Motor)的基本原理是基于电磁感应和电磁力。其工作原理可以归结为利用电流通过线圈在磁场中产生力,从而驱动电机转动。以下是直流电机的详细原理和工作机制:
-
定子(Stator):
永磁体或电磁体,产生静态磁场。 -
转子(Rotor):
也称为电枢(Armature),通常是一个带有线圈的铁芯,位于定子磁场中,并且能够自由转动。 -
换向器(Commutator):
半圆形导体片,连接在转子轴上,与电刷接触,用于切换电流方向,确保转矩方向恒定。 -
电刷(Brushes):
通常由碳材料制成,固定在电机外壳上,与换向器接触,将外部电源的电流传递到转子线圈。
当直流电流通过电刷和换向器进入转子线圈时,依据右手定则,电流在磁场中会产生洛伦兹力。电流方向和磁场方向决定了力的方向,具体如下:
1)电流通过线圈: 线圈的一部分电流从换向器和电刷流入,流经线圈,然后通过另一组换向器和电刷流出。
2)力的产生: 根据弗莱明左手定则,在磁场中的电流承受洛伦兹力,力的方向与电流方向和磁场方向成垂直。在线圈的两边产生相反方向的力,形成一个转矩,使转子旋转。
3)换向器的作用: 随着转子旋转,换向器不断地切换电流方向,以保持转子线圈中电流方向相同,从而维持持续的转矩方向。
减速器
减速器是机械传动系统中的一种重要部件,其主要作用是降低转速并增加转矩。
- 降低转速:
减速器的主要功能是将输入轴的高速旋转转变为输出轴的低速旋转。这是通过齿轮传动来实现的,输入轴连接到高速齿轮,通过多个齿轮级的传动,输出轴的转速被降低。 - 增加转矩:
当转速降低时,输出轴的转矩(扭矩)会相应增加。这是由于功率守恒定律,即在理想情况下,输入功率等于输出功率。减速器通过增加输出转矩,使得负载能被有效驱动。
实物接线
从上图可知,直流电机其实只有两个线(最边上两条),怎么这个电机有6个线,而且还有两个大焊点呢?其实,根据上面的图解也知道,那两个焊点分别和黄线和棕线是连接在一起的。也就是说只有6个线,而6P排线中,中间的四根线(红绿白黑)是编码器的线,只是用于测速,和直流电机本身没有联系。
霍尔编码器
编码器是一种将角位移或者角速度转换成一连串电数字脉冲的旋转式传感器,我们可以通过编码器测量到底位移或者速度信息。
其中,霍尔编码器通过检测磁性目标的运动来生成位置和速度信息,具体步骤如下:
-
磁场变化检测:
当磁性目标(如磁环或磁铁)随轴旋转时,霍尔传感器检测到磁场的变化。 -
霍尔效应生成信号:
霍尔传感器将磁场变化转换为电压信号。这些电压信号的波形取决于磁性目标的极性和旋转速度。 -
信号处理:
信号处理电路将霍尔传感器生成的模拟信号处理为数字脉冲信号。这些脉冲信号的频率与旋转速度成正比,脉冲的数量与旋转角度成正比。 -
输出信号:
处理后的数字脉冲信号通过输出接口传输到单片机。单片机根据这些信号计算转速、位置和方向。
因为编码器输出的是标准的方波,我们可以使用单片机(STM32 STM8 51等)直接读取。在软件中的处理方法是分两种,自带编码器接口的单片机如STM32,可以直接使用硬件计数。而没有编码器接口的单片机如51单片机,可以通过外部中断读取,比如把编码器A相输出接到单片机的外部中断输入口,这样就可通过跳变沿触发中断,然后在对应的外部中断服务函数里面,通过B相的电平来确定正反转。如当A相来一个跳变沿的时候,如果B相是高电平就认为是正转,低电平就认为是反转。
TB6612电机驱动
TB6612具有大电流MOSFET-H桥结构,双通道电路输出,可同时驱动2个电机。和 L298N 的使用基本一致的。而且,相比 L298N 的热耗性和外围二极管续流电路,它无需外加散热片,外围电路简单,只需外接电源滤波电容就可以直接驱动。
接线说明
TB6612是可以一次控制两个电机的(A和B),AB的接线是一样的,这边为了方便,只针对一个电机。下面是接线说明,同一行的两两相接。
TB6612 | 单片机 | 电机 | 电源 |
---|---|---|---|
VM | 7~12V | ||
GND | 共地 | ||
VCC | 3.3V | ||
STBY | 3.3V | ||
PWMA | PWM(PE9) | ||
AIN1 | GPIO(PD2) | ||
AIN2 | GPIO(PD3) | ||
AO1 | 电机电源+ | ||
AO2 | 电机电源- | ||
PWM(PB4) | 编码器A相 | ||
PWM(PB5) | 编码器B相 | ||
编码器电源+ | 3.3~5V | ||
编码器电源- | GND |
程序设计
定时器生成PWM驱动电机
一般来说,TB6612 可以支持较宽范围的 PWM 频率。不同电机对 PWM 频率的响应不同,较高的频率可以使电机运行更加平滑,但过高的频率可能导致驱动器的效率降低。一般推荐的 PWM 频率范围为 10kHz 到 100kHz。
这边用定时器1的通道1口生成 PWM 波形
void TIM1_PWM_Init(u32 arr,u32 psc) //PWM引脚初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //TIM8时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //使能PORTC时钟
GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1);
GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1);
GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1);
GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14; //GPIO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化PC口
//Sets the value of the auto-reload register cycle for the next update event load activity
//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Period = arr;
//Sets the pre-divider value used as the TIMX clock frequency divisor
//设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_Prescaler =psc;
//Set the clock split :TDTS = Tck_tim
//设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_ClockDivision = 1;
//Up counting mode
//向上计数模式
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TIMEBASEINITSTRUCT
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//Select Timer mode :TIM Pulse Width Modulation mode 1
//选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//Compare output enablement
//比较输出使能
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
//Output polarity :TIM output polarity is higher
//输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse=arr/2;
//Initialize the peripheral TIMX based on the parameter specified in TIM_OCINITSTRUCT
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
TIM_OC4Init(TIM1, &TIM_OCInitStructure);
// Advanced timer output must be enabled
//高级定时器输出必须使能这句
TIM_CtrlPWMOutputs(TIM1,ENABLE);
//CH1 is pre-loaded and enabled
//CH1预装载使能
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
// Enable the TIMX preloaded register on the ARR
//使能TIMx在ARR上的预装载寄存器
TIM_ARRPreloadConfig(TIM1, ENABLE);
//使能TIM1
TIM_Cmd(TIM1, ENABLE);
}
速度计算
速度 = 脉冲数 ∗ 轮胎周长 读取周期 ∗ 轮胎每转一圈的脉冲数 速度=\frac{脉冲数*轮胎周长}{读取周期*轮胎每转一圈的脉冲数} 速度=读取周期∗轮胎每转一圈的脉冲数脉冲数∗轮胎周长
其中,轮胎每转一圈的脉冲数取决于编码器的分辨率,可由下面公式进行计算:
轮胎每转一圈的脉冲数 = 倍频 ∗ P P R ∗ 减速比 轮胎每转一圈的脉冲数=倍频*PPR*减速比 轮胎每转一圈的脉冲数=倍频∗PPR∗减速比
然后可以看下 MG310 产品具体参数
MG310的编码器倍频为4,PPR为13,减速比为20,那么最后可以计算轮胎每转一圈的脉冲数为:
轮胎每转一圈的脉冲数 = 4 ∗ 13 ∗ 20 = 1040 轮胎每转一圈的脉冲数=4*13*20=1040 轮胎每转一圈的脉冲数=4∗13∗20=1040
轮胎的参数如下
我设置速度读取周期为10ms,也就是0.01,最后的速度公式简化为:
速度 = 0.01 秒内产生的脉冲数 ∗ 0.048 ∗ π 0.01 ∗ 1040 速度=\frac{0.01秒内产生的脉冲数*0.048*\pi}{0.01*1040} 速度=0.01∗10400.01秒内产生的脉冲数∗0.048∗π
单位为 m / s m/s m/s
代码:
void speedCal(void)
{
float speed = 0;
speed = (Read_Encoder(3)*0.048f*3.14f)/(10.4f);
printf("速度值为:%f m/s\r\n",speed);
}
实验结果
程序下载
https://download.csdn.net/download/u011895157/89421733