STM32 TB6612驱动的直流有刷减速电机

发布者:自在自由最新更新时间:2022-09-08 来源: csdn关键字:STM32 手机看文章 扫描二维码
随时随地手机看文章

电机的基本认识

这里呢,平衡小车最常用到的是直流编码有刷电机,直流的意思是使用直流电,给引脚通的是恒定电流;编码指的是电机自带编码盘,上面有两个相位正交的编码器,可以利用四倍频技术实现对电机位置和转速的精确追踪;有刷指的是电机内部自带换向器,电机转子每旋转180度,线圈中的电流即自动换向,不需要软件或者硬件驱动的控制。


这种电机通常有6个引脚:电源引脚:5V、GND,PWM输入引脚:IN1、IN2,编码器输出引脚:OUT1、OUT2。


PCB走线时要注意只有编码器引脚是信号线,可以走细一些,其他线建议走粗一些(30mil以上)。


电机驱动:TB6612

由于STM32的引脚只能提供3.3V电压,且功率输出能力很弱,因此需要功率放大器件对电机进行控制,并且为了保持控制的实时性,以及精准性,需要高速的功率控制器件,这就需要一款专用的电机驱动芯片


这里使用体积较小,同时有较大驱动能力的TB6612驱动芯片,可以同时驱动两路电机,利用其内部的高速H桥,向电机输出PWM波,控制其正传,反转,制动,自由转动(不加动力也不加阻尼力),以及转速的调节。


驱动芯片除了电源引脚以及使能引脚之外,还有各两组,两种功能的引脚:


来自MCU的3个引脚:1个PWM输入引脚,用于控制转速,2个控制引脚,用于控制正反,制动,空挡(不施加力)。


输出给电机的2个引脚:OUT1,OUT2,通过输出PWM波控制电机的全部功能,搭载较大电流。


驱动编写

通过对电机以及电机驱动的功能分析,我们知道了控制1个电机,需要3个引脚,1个输出PWM波用于控制速度,2个高速推挽输出,通过切换高低电平,即可实现对电机的驱动状态控制。


平衡车有2个电机需要控制,因此用于驱动电机的引脚有6个,2个是定时器的PWM功能映射的引脚。


这里我为了节省定时器资源,使用一个定时器TIM1,该定时器的1、4通道(分别对应PA8,PA11引脚),来输出两路频率相同,但是占空比互不影响,独立可调的PWM信号,然后另外找4个普通IO口,用于对电机状态进行控制。

TIM1映射

电机驱动

MOTOR.h

#ifndef __MOTOR_H

#define __MOTOR_H

#include //包含引脚转换的宏函数,便于编写代码


#define PWMA   TIM1->CCR1  //用于控制A电机的PWM占空比调节

#define AIN2   PBout(15)

#define AIN1   PBout(14)


#define PWMB   TIM1->CCR4  //用于控制B电机的PWM占空比调节

#define BIN1   PBout(13)

#define BIN2   PBout(12)


void MiniBalance_PWM_Init(u16 arr,u16 psc);

void MiniBalance_Motor_Init(void);

#endif


这里干了几件事:


电机控制引脚宏定义


PWM占空比改变宏定义


两个初始化函数宏定义


MOTOR.c

首先是对4个控制引脚的初始化,高速下拉推挽输出:


#include "MOTOR.h"


TIM_HandleTypeDef TIM1_Handler = {0};   //定时器1句柄 

TIM_OC_InitTypeDef TIM1_CH14Handler = {0}; //定时器1通道14句柄



void MiniBalance_Motor_Init(void) //完成4个控制引脚的初始化

{

GPIO_InitTypeDef GPIO_Initure = {0}; //声明初始化结构体

__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟


GPIO_Initure.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; //端口配置

GPIO_Initure.Pull = GPIO_NOPULL;

GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;   //推挽输出

GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH; //50M

HAL_GPIO_Init(GPIOB, &GPIO_Initure);   //根据设定参数初始化GPIOB 

}


然后是对PWM外设的初始化,这里用定时器1的1、4通道,映射到PA8和PA11两个引脚用来控制两个电机的转速:


//TIM1 PWM初始化 

//arr:自动重装值。

//psc:时钟预分频数

//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.

//Ft=定时器工作频率,单位:Mhz

void MiniBalance_PWM_Init(u16 arr,u16 psc) //完成两个PWM输出引脚的初始化

{

TIM1_Handler.Instance=TIM1; //定时器1

TIM1_Handler.Init.Prescaler=psc; //定时器分频

TIM1_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数模式

TIM1_Handler.Init.Period=arr; //自动重装载值

TIM1_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;

HAL_TIM_PWM_Init(&TIM1_Handler);   //初始化PWM

TIM1_CH14Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1

TIM1_CH14Handler.Pulse= 0; //设置比较值,初始占空比设为0

TIM1_CH14Handler.OCPolarity=TIM_OCPOLARITY_HIGH; //输出极性 高电平有效 

HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH14Handler,TIM_CHANNEL_1);//初始化TIM1,PWM通道1、4

HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH14Handler,TIM_CHANNEL_4);//初始化TIM1,PWM通道1、4

HAL_TIM_PWM_Start(&TIM1_Handler,TIM_CHANNEL_1); //开启PWM通道1、4

HAL_TIM_PWM_Start(&TIM1_Handler,TIM_CHANNEL_4); //开启PWM通道1、4

}


在HAL_TIM_PWM_Init()中会调用端口初始化MSP函数,需要用户重定义覆盖HAL库的若定义函数:


//定时器底层驱动,时钟使能,引脚配置

//此函数会被HAL_TIM_PWM_Init()调用

//htim:定时器句柄

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)

{

GPIO_InitTypeDef GPIO_Initure;

    if(htim->Instance==TIM1)

{

__HAL_RCC_TIM1_CLK_ENABLE(); //使能TIM1时钟

__HAL_AFIO_REMAP_TIM1_PARTIAL(); //TIM1通道引脚部分重映射使能

__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟

GPIO_Initure.Pin=GPIO_PIN_8|GPIO_PIN_11;            //PA8 PA11

GPIO_Initure.Mode=GPIO_MODE_AF_PP;  //复用推挽输出,用于输出PWM

GPIO_Initure.Pull=GPIO_PULLDOWN;          //下拉

GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速

HAL_GPIO_Init(GPIOA,&GPIO_Initure);

}

}


然后是中断服务函数,等等,我们设置了自动重装填,不需要中断控制,OK结束。


如何使用电机:实践

控制集成封装

这里集成了控制小车所需的代码,现在只添加电机控制这一模块


CONTROL.h

#ifndef __CONTROL_H

#define __CONTROL_H

#include "sys.h"


void Set_Pwm(int moto1,int moto2);

int myabs(int a); //绝对值函数


#endif


两个函数,核心是第一个,设置PWM的重装填阈值,相当于控制了占空比,这样就实现了调速的功能。


CONTROL.c

#include "CONTROL.h"


/**************************************************************************

函数功能:赋值给PWM寄存器

入口参数:左轮PWM、右轮PWM

返回  值:无

**************************************************************************/

void Set_Pwm(int moto1,int moto2)

{

   int siqu=500;//死区补偿,防止数值过小无法驱动

if(moto1<0) BIN2=0, BIN1=1; //正转

else           BIN2=1, BIN1=0; //反转

PWMB=myabs(moto1)+siqu;

  if(moto2<0) AIN1=0, AIN2=1; //正转

else        AIN1=1, AIN2=0; //反转

PWMA=myabs(moto2)+siqu;

}


/**************************************************************************

函数功能:绝对值函数

入口参数:int

返回  值:unsigned int

**************************************************************************/

int myabs(int a)

{    

  int temp;

if(a<0)  temp=-a;  

  else temp=a;

  return temp;

}


上面这个是实现功能的函数,Set_pwm函数是根据TB6612电机驱动芯片的真值表来计算的,通过直接访问TIM1的CCR寄存器,注意考虑两个电机的中心对称分布,所以写的时候将一个反向,实现输入两个正数,两个电机的转动都使小车向前走即可。


mian函数:

//头文件略去

int main(void)

{

HAL_Init();

Stm32_Clock_Init(RCC_CFGR_PLLMULL9);

JTAG_Set(SWD_ENABLE);

//uart_init(115200);

delay_init(72);

KEY_Init();

MiniBalance_Motor_Init();

MiniBalance_PWM_Init(7199,0);   //PWM输出,溢出值7200,不分频,10KHz频率,100um周期

while(1)

{

Set_Pwm(3000, 3000);

delay_ms(1000);

Set_Pwm(-3000, -3000);

delay_ms(1000);

}

}


这里放了一个最简单的一秒正转,一秒反转,因为还没有研究PID的原理,后面会结合MPU6050触发中断来进行数据处理,反馈给电机,来进行最基本的控制。网上找不到HAL库的历程,就搞来FW3.5标准库来研究,慢慢摸索终于把这电机弄转起来了,实现了多轮运动嘿嘿。

关键字:STM32 引用地址:STM32 TB6612驱动的直流有刷减速电机

上一篇:stm32和电机开发(开篇)
下一篇:STM32嵌入式显示器:首款搭载 STM32H7 的高清屏幕

推荐阅读最新更新时间:2024-11-12 23:54

STM32学习日志——RTC实时时钟
以前刚买手机时,有一个困惑,为什么时钟拔掉电池后时间就暂停了,而手机拔掉电池后,时间照样在走,为了证明是否是联网的原因,将网络关掉后还是一样。后来学了单片机才明白系统有一个实时时钟,由一个小纽扣电池供电。手机应该也是类似的原因。 首先RTC的时钟源由RCC_BDCR的RTCSEL位控制,一般选择LSE振荡器,接着通过RTCPRL位将其分频,假设LSE为32.768kHZ,则PRL写入32767可得到周期为1秒的信号。而RTC_DIV是一个递减的计数器,用PRL的数据装载,每次归零后重新装载,通过读取DIV的当前值,可以获得更精确的时间,比如DIV的当前值为3276,说明还有(3276/32767=0.1s)完成一个周期,说明这个周
[单片机]
STM32入门学习笔记之MPU6050传感器解析实验2
(2) 陀螺仪配置寄存器 (地址:0x1B) 7 6 5 4 3 2 1 0 XG_ST YG_ST ZG_ST FS_SEL - - - Bit 7:陀螺仪X轴自检 0:禁用 1:启用 Bit 6:陀螺仪Y轴自检 0:禁用 1:启用 Bit 5:陀螺仪Z轴自检 0:禁用 1:启用 Bit 4~Bit 3:陀螺仪满量程 0:±250°/s 1:±500°/s 2:±1000°/s 3:±2000°/s (3) 加速度传感器配置寄存器 (地址:0x1C) 7 6 5 4 3 2 1 0 XA_ST YA_ST ZA_ST AFS_SEL - - - Bit 7:加速度计X轴自检 0:禁用 1:启用 B
[单片机]
STM32步进电机源码
motor.c #include motor.h //导入led头文件 #include stm32f10x.h //导入STM32官方库 #include stm32f10x_rcc.h //导入STM32的RCC时钟库 #include delay.h //延时库 void RCC_Configuration(void) { SystemInit(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE , ENABLE); } { GPIO_InitTypeDef GPIO_In
[单片机]
几张图对比STM32各系列产品特性和外设兼容性
STM32产品系列特性比较 下面是STM32F0、F1、F2、F4、L1各产品系列的特性进行对比: 外设兼容性分析对比 对STM32进行过研究的朋友,特别是使用过寄存器开发的朋友应该很明白STM32片上外设,进行过对比的朋友,会发现,各系列MCU的片上外设很多相似之处,甚至完全一样。 下面将F1分别和F0、F2、F4、L1对比一下,大家看看有哪些差异。 1.STM32 F1 与 F0 系列外设兼容性分析对比 2.STM32 F1 与 F2 系列外设兼容性分析对比 3.STM32 F1 与 F4 系列外设兼容性分析对比 4.STM32 F1 与 L1 系列外设兼容性分析对比 Pin引脚对比 S
[单片机]
STM32串口实验中重定向c库中的printf()函数和scanf()函数
在STM 32 的串口实验中,往往需要把内容打印输出在串口调试助手中,这时就需要重定向c库中的printf()函数,重定向后可使用。 注意下面的FILE的定义在头文件stdio.h中,所以在写程序时需要包含此头文件。 例: int fputc(int ch,FILE *f) { USART_SendData(USART_TypeDef* USARTx, uint8_t Data); //发送一个字节数到串口 while(USART_GetFlagStatus(USART_TypeDef* USARTx, USART_FLAG_TC)==RESET); //等待发送完毕 return(ch);
[单片机]
关于STM32定时器触发SPI逐字收发之应用示例
我们在做SPI应用时,有时希望通过定时器来定时地触发SPI的收发,并利用DMA完成数据的传输。这里,以STM32L476芯片为例来做个演示,以供参考。 本示例的大致过程是这样的: 片内SPI1做Master,SPI2做Slave,均工作在全双工模式。 这里使用片内定时器TIM3,通过它的更新事件触发DMA请求,通过DMA将数据给到SPI1的数据寄存器并发送出去,同时也开启SPI1接收事件的DMA传输。总之,SPI2的收、发事件都启用DMA完成。 TIM3的更新事件周期控制两个SPI的收发节奏,即定时器每产生一次更新事件,SPI1/SPI2这两个主从通信模块就进行一个数据的收发。我们可以通过调整定时器的计时周期来调整
[单片机]
关于<font color='red'>STM32</font>定时器触发SPI逐字收发之应用示例
STM32硬件复位时间
两个参数,,1低电平时间 2低电平压值 1.stm32复位时间 ------ 低电平时间:1.5 至 4.5 ms 2.压值
[单片机]
<font color='red'>STM32</font>硬件复位时间
GD32单片机STM32远程下载手机程序升级固件下载局域网网页升级工具
GD32、STM32单片机,是我们最常见的一种MCU。通常我们在使用STM32单片机都会遇到程序在线升级下载的问题。 GD32/STM32单片机的在线下载通常需要以下几种方式完成: 1、使用ST/GD提供的串口下载工具,本地完成固件的升级下载。 2、自行完成系统BootLoader的编写,将系统程序分为BootLoader和APP两个部分,BootLoader完成固件升级。 3、使用STM32/GD固件服务器,完成固件的升级,固件服务器https://simplewifi.taobao.com/ 几种方式各有优缺点: 使用ST提供的方法进行固件升级,方法简单,不需要额外的开发。但是,只能本地完成STM32单片机的升级。
[单片机]
GD32单片机<font color='red'>STM32</font>远程下载手机程序升级固件下载局域网网页升级工具
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved