硬件准备
一块ESP32(任意ESP32都可,本文使用ESP32-WROOM-32)/STM32F103C8T6
一块TB6612电机驱动板
一个直流电机
一块5V电池
方案实现
①ESP32驱动一个直流电机:
接线方案:
TB6612 | ESP32 |
PWMA | 32 |
AIN1 | 33 |
AIN2 | 25 |
STBY | 26 |
VCC | 3.3/5v(逻辑供电) |
GND | GND(逻辑供电) |
VM | 5V(外部供电必须5v) |
GND | GND(外部供电GND) |
TB6612 | 直流电机 |
AO1 | 直流电机+ |
AO2 | 直流电机- |
PS:直流电机不分正负极,AO1也可以接直流电机-,AO2也可以接直流电机+(不同接法只是让电机正转或反转)
接线如下所示:
ESP32驱动一个直流电机代码
const int PIN_PWMA = 32;
const int PIN_AIN1 = 33;
const int PIN_AIN2 = 25;
const int PIN_STBY = 26;
// PWM频率和分辨率设置
const int pwmFrequency = 10000; // Hz
const int bitResolution = 8; // pwm值范围: 0~255
unsigned long previousStopTime = 0;
unsigned long previousBlinkTime = 0;
int StopInterval = 3000; // 3秒的时间间隔
bool toggle = false;
void setup() {
Serial.begin(115200);
// TB6612FNG引脚设置
pinMode(PIN_STBY, OUTPUT);
pinMode(PIN_AIN1, OUTPUT);
pinMode(PIN_AIN2, OUTPUT);
pinMode(PIN_PWMA, OUTPUT);
// 电机PWM输出设置(通道、频率、位深)
ledcAttach(PIN_PWMA, pwmFrequency, bitResolution);
}
void loop() {
unsigned long currentMillis = millis(); // 获取当前时间
millisBlink(currentMillis); // 调用定时函数
// 电机A:顺时针旋转
digitalWrite(PIN_STBY, HIGH); // 使能STBY
digitalWrite(PIN_AIN1, HIGH); // AIN1
digitalWrite(PIN_AIN2, LOW); // AIN2
// 根据toggle状态设置PWM值
if (toggle) {
ledcWrite(PIN_PWMA, 0); // 关闭PWM
} else {
ledcWrite(PIN_PWMA, 80); // 50的PWM值(低速)
}
}
void millisBlink(unsigned long currentTime) {
// 检查是否到达时间间隔
if (currentTime - previousStopTime >= StopInterval) {
toggle = !toggle; // 切换状态
previousStopTime = currentTime; // 重置时间
}
// 处理millis()溢出情况
else if (currentTime - previousStopTime <= 0) {
previousStopTime = currentTime;
}
}
实验现象:电机不停地正转
②STM32驱动两个直流电机:
接线方案:
TB6612 | STM32 |
PWMA | A8 |
AIN1 | B14 |
AIN2 | B15 |
STBY | 5V |
VCC | 3.3/5v(逻辑供电) |
GND | GND(逻辑供电) |
VM | 5V(外部供电必须5v) |
GND | GND(外部供电GND) |
TB6612 | 直流电机 |
AO1 | 直流电机+ |
AO2 | 直流电机- |
PS:同样的,直流电机不分正负极,AO1也可以接直流电机-,AO2也可以接直流电机+(不同接法只是让电机正转或反转)
接线如下所示:
STM32驱动一个直流电机代码:
#include "stm32f10x.h"
void PWM_Init(u16 arr,u16 psc)
{
//定义结构体
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM1 CH1 CH4的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1
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; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1预装载使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
void Motor_Ctrol(int mode)
{
if(mode==1)
{
GPIO_SetBits(GPIOB, GPIO_Pin_14); // 高电平
GPIO_ResetBits(GPIOB, GPIO_Pin_15); // 低电平}
}
if(mode==0)
{
GPIO_SetBits(GPIOB, GPIO_Pin_15); // 高电平
GPIO_ResetBits(GPIOB, GPIO_Pin_14); // 低电平}
}
}
void GPIO1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体GPIO_InitStructure
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); // 使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14| GPIO_Pin_15; //PB14 PB15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽,增大电流输出能力
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度
GPIO_Init(GPIOB, &GPIO_InitStructure); //GBIOB初始化
}
int main(void)
{
SystemInit(); //配置系统时钟为72M
//delay_init(); //延时函数初始化
GPIO1_Init(); //初始化gpio口B pin_14/pin_15
PWM_Init(7199,0); //初始化pwm输出 72000 000 /7199+1=10000
while(1)
{
Motor_Ctrol(0); //moto=1时正转
TIM_SetCompare1(TIM1,3000); //设置TIM1通道1的占空比 3000/7200
Motor_Ctrol(1); //moto=0时反转
TIM_SetCompare1(TIM1,4000); //设置TIM1通道1的占空比 4000/7200
}
}
实验现象:点击正转三秒,反转4秒,循环往复