TB6612是双电机驱动,上图
VM:5V-10V电压
VCC:3.3V、5V
PWMA:接单片机io口,通过定时器输出PWM,要看芯片手册。
AIN1、AIN2:接单片机IO口
AO1AO2:接电机口
STBY:输入高电平工作,输入低电平不工作
单片机控制AIN1、AIN2、BIN1、BIN2控制电机正反转,控制PWMA、PWMB控制电机转速。
霍尔编码器是在一定直径的圆板上等分地布置有不同的磁极。霍尔码盘与电动机同轴,电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号 (通常相差90°,我们称为AB相),上图
M+、M-控制电机转动
A、B接单片机脉冲接口,TIMx_CH1,TIMx_CH2
stm32引脚定时器输出PWM波,使用IO复用功能,T2-T5四个通用计时器均可输出4路PWM(CH1-CH4),支持TIM功能的引脚有PA0-PA3、PA6-PA7、PB0-PB1、PB6-PB9
void TIM3_PWM_Init(unsigned int arr,unsigned int psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period=arr;
TIM_TimeBaseStructure.TIM_Prescaler=psc;
TIM_TimeBaseStructure.TIM_ClockDivision=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OC1Init(TIM3,&TIM_OCInitStructure);
TIM_OC2Init(TIM3,&TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
TIM_Cmd(TIM3,ENABLE);
}
定时器相关知识:
以stm32f10xxx系列MCU为例,有高级控制定时器(TIM1、TIM8),通用计时器(TIM2-TIM5)和基本计时器(TIM6、TIM7).
高级计时器:由一个16位自动重装载计时器组成,由一个可编程的预分频器驱动,可测量输入信号的脉冲宽度(输入捕获),产生输出波形(输出比较,pwm)。有四个独立通道-输入捕获-输出比较-pwm生成-单脉冲模式输出。高级定时器的时钟来自输入为APB2的一个倍频器的频率。
寄存器:
TIMx_CNT计数器寄存器
TIMx_PSC预分频器寄存器
TIMx_ARR自动重装载寄存器:计数器从0计数到自动加载值,然后清零(向上计数)
TIMx_RCR重复次数寄存器:当计数次数到达设置的重复计数次数时,产生更新事件,否则每次计时器溢出时才产生更新事件
TIMx_CR1控制寄存器
回到编码器:霍尔编码器是增量式编码器,有AB两相输出,电机转动一圈,通过霍尔传感器AB两相输出脉冲,根据特定时间内脉冲数计算出电机瞬时速度。通过定时器外设的输入捕获功能,进行脉冲计数。代码如下
void Encoder_Init_TIM4(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENBALE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_fLOATING;
GPIO_Init(GPIOB,&GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period=arr;
TIM_TimeBaseStructure.TIM_Prescaler=psc;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);
TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
TIM_ICStructInit(&TIM_TimeBaseStructure);
TIM_ICInitStructure.TIM_ICFilter=10;
TIM_ICInit(TIM4,&TIM_ICInitStructure);
TIM_Cmd(TIM4,ENABLE);
}
int Read_Encoder_TIM4(void)
{
int Encoder_TIM;
Encoder_TIM=TIM4->CNT;
if(Encoder_TIM>0xefff)Encoder_TIM=Encoder_TIM-0xefff;
TIM4->CNT=0;
return Encoder_TIM;
}