Freertos-小车开发笔记 2 --编码电机使用

目录

前言

一、TB6612电机驱动板

1.TB6612 模块介绍

2.TB6612 芯片原理图介绍与控制说明

3.tb6612--D153B 模块接线说明

二、编码电机驱动后轮

1.编码电机初始化

2.编码电机初始化

总结

 

前言

通过编码点击控制小车的后轮转动,通过舵机改变前轮的转向。


一、TB6612电机驱动板

采用tb6612电机作为编码电机的驱动板,该驱动板只需要1个pwm信号和两个IO口即可控制一个编码电机.

编码器电机为直流减速电机,一般直流电机的转速都是一分钟几千上万转的,所以一般需要安装减速器。减 速器是一种相对精密的机械零件,使用它的目的是降低转速,增加转矩。减速后的直

流电机力矩增大、可控性更强。按照传动级数不同可分为单级和多级减速器;按照传动类型可分为齿轮减速器、蜗杆减速器和行星齿轮减速器。

齿轮减速箱体积较小,传递扭矩大,但是有一定的回程间隙。蜗轮蜗杆减机的主要特点是具有反向自锁功能,可以有较大的减速比,但是一般体积较大,传动效率不高,精度不高。行星减速机其优点是结构比较紧凑,回程间隙小、精度较高,使用寿命很长,额定输出扭矩可以做的很大,但价格略贵。

Freertos-小车开发笔记 2 --编码电机使用_第1张图片

Freertos-小车开发笔记 2 --编码电机使用_第2张图片

1、TB6612 模块介绍

(1)TB6612 是东芝半导体公司生产的的一款直流电机驱动器件,它具有大电

流的 MOSFET-H 桥结构,双通道电路输出,可同时驱动两个电机。如果我们需

要驱动两个电机,只需要一块 TB6612 芯片即可。

(2)相比 L298N 的热耗性和外围二极管续流电路,它无需外加散热片,外围

电路简单,只需要外接电源滤波电容就可以直接驱动电机,利于减小系统尺寸。

(3)对于 PWM 信号输入频率范围,高达 100kHz 的频率更是足以满足我们大部

分的需求了。

(4)TB6612 的主要参数:

最大输入电压:VM = 15V

最大输出电流:Iout=1.2A(平均)或=3.2A(峰值)

具有正反转、短路刹车、停机功能模式

内置过热保护和低压检测电路

Freertos-小车开发笔记 2 --编码电机使用_第3张图片

2、TB6612 芯片原理图介绍与控制说明

Freertos-小车开发笔记 2 --编码电机使用_第4张图片

功能引脚连接示意图:

Freertos-小车开发笔记 2 --编码电机使用_第5张图片

在使用的过程中,VM 需要比较大的电压,如 12V,而且 VCC 还需要接 5V。

VM 是用来给电机供电的,VCC 是给芯片供电的,切记勿要接错,否则将会烧坏芯

片。在控制电机时,AO1、AO2、BO1、BO2 连接电机的两个引脚,PWMA、PWMB 输

入 PWM 信号(一般为 10kHz 的 PWM 信号),AIN1、AIN2、BIN1、BIN2 用来控制电

机的运动方向。STBY 端是一个使能信号端,当 STBY=1 时,正常工作,输入 PWM

信号,电机可正常运行;当 STBY=0 时,电机驱动处于待机状态,输入信号,电

机不会运行。该芯片中的两个 GND 引脚,需一个接电源地,一个接单片机地。

Freertos-小车开发笔记 2 --编码电机使用_第6张图片

3.tb6612--D153B 模块接线说明

Freertos-小车开发笔记 2 --编码电机使用_第7张图片

注意:STBY引脚需要接高电平才可以驱动电机工作,否则输入了pwm信号也无法驱动电机。

二、编码电机驱动后轮

1.编码电机初始化

        驱动2个编码电机需要采用4个普通的IO口和两路pwm信号,普通的GPIO口采用的是_GPIOB:GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15,设置工作摸式为推挽输出模式。
        采用定时器3TIM3的通道3和通道4来作为Pwm信号源,计数模式:向上计数,采用PWM模式1,当定时器计数小于TIM_Pulse时,定时器对应IO输出有效电平。
TB6612_Init(7199, 0); //电机驱动外设初始化 使用定时器3 PB12 PB13 PB14 PB15

/**************************************************************************
函数功能:TB6612初始化函数
入口参数:定时器3计数上限 定时器3预分频系数
返回  值:无
电机1 PB12 PB13 电机2 PB14 PB15
**************************************************************************/
void TB6612_Init(int arr, int psc)
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义一个引脚初始化的结构体
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue; //定义一个定时中断的结构体	
	TIM_OCInitTypeDef TIM_OCInitTypeStrue; //定义一个PWM输出的结构体
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟,GPIOB挂载在APB2时钟下,在STM32中使用IO口前都要使能对应时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能通用定时器3时钟
	
	//TB6612控制方向引脚
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //引脚输入输出模式为推挽输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //引脚输出速度为50MHZ
	GPIO_Init(GPIOB, &GPIO_InitStructure); //根据上面设置好的GPIO_InitStructure参数,初始化引脚
	
	GPIO_ResetBits(GPIOB, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //初始化设置引脚低电平

	//TB6612PWM输出引脚
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;//引脚0
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽输出模式,定时器功能为B1引脚复用功能
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //定义该引脚输出速度为50MHZ
	GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化引脚GPIOB1
	
	TIM_TimeBaseInitStrue.TIM_Period=arr; //计数模式为向上计数时,定时器从0开始计数,计数超过到arr时触发定时中断服务函数
	TIM_TimeBaseInitStrue.TIM_Prescaler=psc; //预分频系数,决定每一个计数的时长
	TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up; //计数模式:向上计数
	TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV1; //一般不使用,默认TIM_CKD_DIV1
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStrue); //根据TIM_TimeBaseInitStrue的参数初始化定时器TIM3
	
	TIM_OCInitTypeStrue.TIM_OCMode=TIM_OCMode_PWM1; //PWM模式1,当定时器计数小于TIM_Pulse时,定时器对应IO输出有效电平
	TIM_OCInitTypeStrue.TIM_OCPolarity=TIM_OCNPolarity_High; //输出有效电平为高电平
	TIM_OCInitTypeStrue.TIM_OutputState=TIM_OutputState_Enable; //使能PWM输出
	TIM_OCInitTypeStrue.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
	TIM_OC3Init(TIM3, &TIM_OCInitTypeStrue);
	TIM_OC4Init(TIM3, &TIM_OCInitTypeStrue); //根TIM_OCInitTypeStrue参数初始化定时器3通道4

  //TIM_CtrlPWMOutputs(TIM3,ENABLE);	//MOE 主输出使能
	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); //CH3预装载使能  使能后改变TIM_Pulse(即PWM)的值立刻生效,不使能则下个周期生效
	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); //CH4预装载使能  使能后改变TIM_Pulse(即PWM)的值立刻生效,不使能则下个周期生效
	
	TIM_ARRPreloadConfig(TIM3, ENABLE); //TIM3预装载使能
	
	TIM_Cmd(TIM3, ENABLE); //使能定时器TIM3
}

 2.编码电机初始化

注意:编码器模式只能采用TIMx的通道1和通道2

Freertos-小车开发笔记 2 --编码电机使用_第8张图片

本次实验采用的TIM2和TIM4来获取2个编码电机的计数值,TIM2的通道1和通道2为PA0和PA1引脚。TIM4的通道1和通道2为PB6和PB7引脚。编码器初始化代码如图:

/**************************************************************************
函数功能:编码器1初始化函数
入口参数:无
返回  值:无
**************************************************************************/
void MotorEncoder1_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; //定义一个引脚初始化的结构体  
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定义一个定时器初始化的结构体
	TIM_ICInitTypeDef TIM_ICInitStructure; //定义一个定时器编码器模式初始化的结构体
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能CPIOB时钟
 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;	//TIM4_CH1、TIM4_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);	//根据GPIO_InitStructure的参数初始化GPIO

	TIM_TimeBaseStructure.TIM_Period = 0xffff; //设定计数器自动重装值
	TIM_TimeBaseStructure.TIM_Prescaler = 0; // 预分频器 
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //选择时钟分频:不分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct的参数初始化定时器TIM4
	
	TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); //使用编码器模式3:CH1、CH2同时计数,为四分频
	TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入
	TIM_ICInitStructure.TIM_ICFilter = 10;  //设置滤波器长度
	TIM_ICInit(TIM4, &TIM_ICInitStructure); //根TIM_ICInitStructure参数初始化定时器TIM4编码器模式
	
	TIM_ClearFlag(TIM4, TIM_FLAG_Update);//清除TIM的更新标志位
	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //更新中断使能
	TIM_SetCounter(TIM4,0); //初始化清空编码器数值
	
	TIM_Cmd(TIM4, ENABLE); //使能定时器4
}

/**************************************************************************
函数功能:编码器2初始化函数
入口参数:无
返回  值:无GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM2, ENABLE); //Timer2全部重映射
**************************************************************************/
void MotorEncoder2_Init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
  TIM_ICInitTypeDef TIM_ICInitStructure;  
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器4的时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PB端口时钟
	
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;	//端口配置
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);					      //根据设定参数初始化GPIOB
  
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 
  TIM_TimeBaseStructure.TIM_Period = 65535; //设定计数器自动重装值
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM向上计数  
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
	
  TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
  TIM_ICStructInit(&TIM_ICInitStructure);
  TIM_ICInitStructure.TIM_ICFilter = 10;	//滤波10
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
  
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
  //Reset counter
  TIM_SetCounter(TIM2,0);
  TIM_Cmd(TIM2, ENABLE); 
}

 2.编码电机初始化

Freertos-小车开发笔记 2 --编码电机使用_第9张图片

 

Freertos-小车开发笔记 2 --编码电机使用_第10张图片

 

Freertos-小车开发笔记 2 --编码电机使用_第11张图片

 

Freertos-小车开发笔记 2 --编码电机使用_第12张图片

Freertos-小车开发笔记 2 --编码电机使用_第13张图片

 

Freertos-小车开发笔记 2 --编码电机使用_第14张图片

 

4cf189608972245cfcfba1635de2f3fa.png

使能定时器2和4中断,编码器模式采用的是编码器3的模式,也就是4倍频模式,采用freertos软件定时器的方式每10ms采集一次定时器的计数值来判断编码器的读数,从而来改变PWM的输出值来控制编码电机的速度。

10ms读取一次编码器(即100HZ),电机减速比为20,霍尔编码器精度13,AB双相组合得到4倍频
则转1圈编码器读数为20*13*4=1040,电机转速=Encoder*100/1040r/s


总结

到此就完成看了编码电机的初始化和编码器初始化,编码器测速见下一篇文章。

 

你可能感兴趣的:(单片机,物联网,stm32,嵌入式硬件)