STM32学习16--定时器输出比较2直流电机

使用STM32定时器输出PMW信号配置TB6612 驱动芯片,是嵌入式的经典方案。

一、硬件接线与引脚功能

直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作。TB6612是一款双通道驱动芯片,控制一个电机需要3个STM32引脚(1个PWM+2个GPIO),具体如下:

1、PWM引脚(PWMA和PWMB)连接STM32的定时器通道引脚(比如TIM3_CHI1对应PA6),输入PWM信号,占空比决定电机转速。

2、方向控制引脚(AIN1-AIN2):连接STM32的普通GPIO,通过高低电平组合控制电机的正转、反转和刹车;

3、使能引脚(STBY):芯片的总开关。接3.3V和5V高电平表示使能,接GND则芯片进入待机高阻态,电机自由滑行。

4、电源引脚(VM,VCC):VM接5V,官方不超过10V。VCC接3.3V,务必保证STM32、TB6612和电源共地(GND)。

二、TB6612核心控制逻辑

STBY接3.3V,一直使能,逻辑如下:

|--------|--------|-------------|------------|
| AN1 | AN2 | PWMA(PWM信号) | 电机状态 |
| 高电平(1) | 低电平(0) | 有效PWM | 正转,占空比越大越快 |
| 低电平(0) | 高电平(1) | 有效PWM | 反转,占空比越大越快 |
| 低电平(0) | 低电平(0) | X | 停机 |
| 高电平(1) | 高电平(1) | X | 制动 |

三、代码

配置:使用TIM2,通道1→PA0,PA4接AIN1,PA5接AIN2。

1、PWM初始化及修改占空比函数

cpp 复制代码
void PWM_Init(uint16_t ARR,uint16_t PSC)
{
	TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_OCInitTypeDef OC_Config;
	//开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	//初始化GPIO,PA0复用功能
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//初始化时基单元
	TIM_BaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;
	TIM_BaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;
	TIM_BaseInitStructure.TIM_Period =ARR;//1000-1
	TIM_BaseInitStructure.TIM_Prescaler =PSC;//72-1
	TIM_TimeBaseInit(TIM2,&TIM_BaseInitStructure);
	//配置OC
	OC_Config.TIM_OCMode =TIM_OCMode_PWM1;
	OC_Config.TIM_OutputState = TIM_OutputState_Enable;
	OC_Config.TIM_OCPolarity = TIM_OCPolarity_High;
	OC_Config.TIM_Pulse = 0;
	TIM_OC1Init(TIM2,&OC_Config);
	
	TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM2,ENABLE);
	TIM_Cmd(TIM2,ENABLE);		
}
//修改CCR值,也就是修改占空比
void SetCompare(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);
}

注:PWM当成模板,只要修改ARR、PSC即可。公式:频率=72M/(ARR+1)/(PSC+1);

PSC=72-1,ARR=1000-1,TB6612用这个参数频率噪音很小,比较适合。

2、TB6612引脚初始化

cpp 复制代码
void Motor_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4 |GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	/*上电默认停机*/
	GPIO_ResetBits(GPIOA,GPIO_Pin_4);
	GPIO_ResetBits(GPIOA,GPIO_Pin_5);
}

3、电机启停函数

cpp 复制代码
void Motor_Forward()
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_5);
	GPIO_SetBits(GPIOA,GPIO_Pin_4);
}
void Motor_Reverse()
{
	GPIO_SetBits(GPIOA,GPIO_Pin_5);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}
void Motor_Stop()
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_5);
	GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}

4、main函数

cpp 复制代码
#include "stm32f10x.h"                
#include "Delay.h"
#include "Motor.h"
#include "KEY.h"
#include "PWM.h"
int main()
{
	PWM_Init(1000-1,72-1);
	Motor_Init();
	while(1)
	{
		Motor_Forward();
		SetCompare(600);
		Delay_ms(5000);
		SetCompare(1000);		
		Delay_ms(10000);
		Motor_Stop();
		Delay_ms(10000);
	}
	
}

注:PWM频率选择:TB6612支持高频,可以将PWM设置在10~20kHz之间,这个频率超出了人耳听觉范围,可以有效消除电机运行时的想"啸叫声"。

四、复习GPIO

1、输出引脚(单片机往外发信号)

分:普通输出、复用输出。

1)普通推挽Out_PP:是人写代码手动控制高低电平:点灯、TB6612的AIN1和AIN2、继电器、按键指示灯、蜂鸣器等。函数:GPIO_SetBits(),GPIO_ResetBits()等,完全由程序说了算,和片内外设无关。

2)复用推挽AF__PP(专用外设输出)

引脚交给单片机硬件模块自动控制,自己写的代码不能直接拉高拉低。

TIM_CHx(PWM)、串口TX,SPI时钟、MOSI。定时器自动产生方波,软件干预不了电平,必须开复用模式。

共同点:都是输出,单片机向外送出电平。

3)开漏输出:基本不用,只有I2C偶尔使用。

2、输入引脚(单片机读取外部的电平)

1))上拉输入IPD:外部开关、独立按键最常用;

2)浮空输入:IN_FLOATING:ADC模拟量采集;

3)复用输入AF_IPD:串口Rx、SPI_MISO、定时器捕获

外设接管引脚用来接收信号,就用复用输入;

2、判断流程:

第一步:引脚是往外输出还是外部信号??

读取→输入:按键选IPD,串口选Rx选复用AF_IPD;ADC选浮空;

往外输出→进入第二步:

第二步:是自己手动写代码控制电平吗??

自己操控→Out_PP;

定时器/串口自动发波形→AF_PP(比如PWM)

本文完!

相关推荐
Brilliantwxx几秒前
【STM32】 SPI Flash 驱动开发实战:阻塞模式驱动 W25Q64(含工程代码)
开发语言·stm32·单片机·嵌入式硬件
外收内放8 分钟前
数据分析(jupyter与pandas初体验)
python·学习
zhangrelay19 分钟前
《机器人控制器设计与编程》课程习题资料-2026
linux·笔记·学习·ubuntu
kkkkkkkkkk_Z42 分钟前
新手自学嵌入式|学习日记:从C语言到51单片机基础(GPIO、中断、定时器与PWM篇)
linux·笔记·学习·51单片机
陈年老古董1 小时前
微博情感分析项目学习笔记
笔记·python·学习·机器学习·项目
老当益壮梁奶奶1 小时前
ARM汇编学习笔记(六):【i.MX6ULL】时钟系统与定时器(EPIT & GPT)
c语言·arm开发·嵌入式硬件·学习·51单片机
明德扬1 小时前
机器人多摄像头如何做FPGA多路视频聚合?
学习·fpga开发·fpga
youcans_2 小时前
【嵌入式软件AI编程】16. Claude Code 与 VS Code 的协同开发
stm32·mcu·嵌入式·ai编程·claude code
曼巴UE52 小时前
UE5 客户端 需要的网络同步概念总结(3 )-事件同步 RPC 以及三种调用方式
网络·c++·网络协议·学习·rpc·ue5
昌原的儿子LEO2 小时前
IMX6ULL 时钟系统与 EPIT/GPT 定时器原理与配置
arm开发·学习