STM32通过PWM驱动两个直流电机
STM32之GPIO配置举例`(六)
·
STM32F103单片机通过PWM控制直流电机
测试的时候可以通过以下方式进行电机正负端测试:
使用TIM2的通道1和2进行pwm输出,即PA0,PA1引脚,PA0控制左电机pwm,PA1控制右电机pwm。
PA11,PA12控制左轮,PA11接电机正端,PA12接电机负端
PA13,PA14控制右轮,PA13接电机正端,PA14接电机负端
实际使用的时候需要使用TB6612模块进行电压匹配:
单片机接TB6612如下:
PA0接PWMA, PA1接PWMB
PA11接AIN1,PA12接AIN2,PA13接BIN1,PA14接BIN2
TB6612的STBY引脚是使能端(给低电平6612芯片不工作,给高电平芯片正常工作),可以直接接5V或者接一直给高电平的引脚。VM引脚接12V或者24V(直流电机工作电压,即电压匹配)
TB6612接电机如下:
AO1接左电机正端,AO2接左电机负端。
BO1接右电机正端,BO2接右电机负端
代码如下
motor.h
#ifndef __MOTOR_H
#define __MOTOR_H
#include "sys.h"
#define Motor_Left_Pwm TIM2->CCR1
#define Motor_Right_Pwm TIM2->CCR2
void Motor_Init(void);
void Tim2_pwm_init(u16 arr,u16 psc);
//小车动作函数
void RUN_GO(int left,int right);//前进,左右轮速度自设
void RUN_BACK(int left,int right);//后退,左右轮速度自设
void GO(int val);//直走
void STOP(void);//停止
void BACK(int val);//后退
void TURN_LEFT(void);//左转,左轮抱死右轮动
void TURN_RIGHT(void);//右转,右轮抱死左轮动
void TURN_LEFT_ELSE(void);//左转,左轮后退右轮前进
void TURN_RIGHT_ELSE(void);//右转,右轮后退左轮前进
//轮子行为函数
void LEFT_GO(void);
void LEFT_BACK(void);
void RIGHT_GO(void);
void RIGHT_BACK(void);
#endif
motor.c
#include "motor.h"
#include "sys.h"
#include "delay.h"
void Motor_Init(void)
{
RCC->APB2ENR|=1<<2; //时钟使能GPIOA
JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG功能
GPIOA->CRH&=0XF0000FFF;
GPIOA->CRH|=0X03333000; //PA11~14推挽输出
}
void Tim2_pwm_init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<0; //时钟使能TIM2
GPIOA->CRL&=0XFFFFFF00;
GPIOA->CRL|=0X000000BB; //PA0 PA1复用功能输出
TIM2->ARR = arr; //设置计数器自动重装载值
TIM2->PSC = psc; //预分频器设计
TIM2->CCMR1 =0X6060; //CH1 PWM1 模式 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为 有效电平;
//在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。
//CH2 PWM1 模式 在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为 有效电平;
//在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。
TIM2->CCMR1|=1<<3; //CH1 预装载使能
TIM2->CCMR1|=1<<11; //CH 2 预装载使能
TIM2->CCER |=1<<0; //OC1 输出使能
TIM2->CCER |=1<<4; //oc2 输出使能
TIM2->CR1=0x0080; //ARPE 使能
TIM2->CR1|=0x01; //使能定时器2
}
//左轮为PA11 PA12引脚
void LEFT_GO(void)
{
PAout(11) = 1;
PAout(12) = 0;
}
void LEFT_BACK(void)
{
PAout(11) = 0;
PAout(12) = 1;
}
//右轮为PA13 PA14引脚
void RIGHT_GO(void)
{
PAout(13) = 1;//RIGHT
PAout(14) = 0;
}
void RIGHT_BACK(void)//右电机反转
{
PAout(13) = 0;//RIGHT
PAout(14) = 1;
}
void TURN_LEFT(void)//左转
{
STOP();
RIGHT_GO();
Motor_Left_Pwm=0;
Motor_Right_Pwm=400;
delay_ms(10);
}
void TURN_LEFT_ELSE(void)
{
STOP();
RIGHT_GO();
LEFT_BACK();
Motor_Left_Pwm=400;
Motor_Right_Pwm=400;
delay_ms(10);
}
void TURN_RIGHT(void)//右转
{
STOP();
LEFT_GO();
Motor_Left_Pwm=0;
Motor_Right_Pwm=400;
delay_ms(10);
}
void TURN_RIGHT_ELSE(void)
{
STOP();
LEFT_GO();
RIGHT_BACK();
Motor_Left_Pwm=400;
Motor_Right_Pwm=400;
delay_ms(10);
}
void RUN_GO(int left,int right)
{
STOP();
RIGHT_GO();
LEFT_GO();
Motor_Left_Pwm=left;
Motor_Right_Pwm=right;
delay_ms(10);
}
void RUN_BACK(int left,int right)
{
STOP();
RIGHT_BACK();
LEFT_BACK();
Motor_Left_Pwm=left;
Motor_Right_Pwm=right;
delay_ms(10);
}
void GO(int val)//直走
{
STOP();
RIGHT_GO();
LEFT_GO();
Motor_Left_Pwm=val;
Motor_Right_Pwm=val;
delay_ms(10);
}
void BACK(int val)//后退
{
STOP();
RIGHT_BACK();
LEFT_BACK();
Motor_Left_Pwm=val;
Motor_Right_Pwm=val;
delay_ms(10);
}
void STOP()//停
{
PBout(0) = 0;
PBout(1) = 0;
PBout(13) = 0;
PBout(14) = 0;
Motor_Left_Pwm=0;
Motor_Right_Pwm=0;
delay_ms(10);
}
main.c
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "motor.h"
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
Motor_Init();
Tim2_pwm_init(899,0);
while(1)
{
GO(300);
delay_ms(1000);
RUN_GO(500,500);
delay_ms(1000);
RUN_BACK(500,500);
delay_ms(1000);
STOP();
delay_ms(1000);
GO(400);
delay_ms(1000);
BACK(600);
delay_ms(1000);
TURN_LEFT();
delay_ms(1000);
TURN_RIGHT();
delay_ms(1000);
TURN_LEFT_ELSE();
delay_ms(1000);
TURN_RIGHT_ELSE();
delay_ms(1000);
RUN_GO(400,700);
delay_ms(1000);
}
}
更多推荐
所有评论(0)