183 lines
5.8 KiB
C
183 lines
5.8 KiB
C
// motor_driver.c
|
||
#include "motor_driver.h"
|
||
#include "delay.h"
|
||
// 全局变量
|
||
static uint8_t pwm_duty = 0; // PWM占空比 0-100
|
||
static MotorState motor_dir = MOTOR_STOP;
|
||
|
||
// GPIO初始化
|
||
void DRV8832_GPIO_Init(void) {
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
|
||
// 使能GPIOE时钟
|
||
RCC_AHB1PeriphClockCmd(MOTOR_IN1_GPIO_CLK, ENABLE);
|
||
|
||
// 配置IN1 (PE9) 和 IN2 (PE13) 为输出
|
||
GPIO_InitStructure.GPIO_Pin = MOTOR_IN1_GPIO_PIN | MOTOR_IN2_GPIO_PIN;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 推挽输出
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
|
||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||
GPIO_Init(MOTOR_IN1_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
// 配置FAULTN (PE4) 为输入
|
||
GPIO_InitStructure.GPIO_Pin = MOTOR_FAULT_GPIO_PIN;
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // 上拉
|
||
GPIO_Init(MOTOR_FAULT_GPIO_PORT, &GPIO_InitStructure);
|
||
|
||
// 初始状态:停止电机
|
||
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
}
|
||
|
||
// 初始化DRV8832
|
||
void DRV8832_Init(void) {
|
||
DRV8832_GPIO_Init();
|
||
}
|
||
|
||
//=====================================================================================
|
||
// 电机基础控制函数
|
||
void Motor_Control(MotorState state) {
|
||
switch(state) {
|
||
case MOTOR_STOP: // IN1=0, IN2=0
|
||
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
break;
|
||
|
||
case MOTOR_FORWARD: // IN1=1, IN2=0
|
||
GPIO_SetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
break;
|
||
|
||
case MOTOR_REVERSE: // IN1=0, IN2=1
|
||
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_SetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
break;
|
||
|
||
case MOTOR_BRAKE: // IN1=1, IN2=1
|
||
GPIO_SetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_SetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 获取故障状态
|
||
uint8_t Motor_GetFaultStatus(void) {
|
||
// FAULTN引脚为低电平时表示故障
|
||
if (GPIO_ReadInputDataBit(MOTOR_FAULT_GPIO_PORT, MOTOR_FAULT_GPIO_PIN) == Bit_RESET) {
|
||
return 1; // 故障
|
||
}
|
||
return 0; // 正常
|
||
}
|
||
|
||
// 安全的方向切换(避免电流冲击)
|
||
void Motor_SafeDirectionChange(MotorState new_direction) {
|
||
// 先刹车
|
||
Motor_Control(MOTOR_BRAKE);
|
||
delay_ms(5); // 5ms延迟
|
||
|
||
// 再切换到新方向
|
||
Motor_Control(new_direction);
|
||
}
|
||
|
||
|
||
// 使用TIM2实现软件PWM
|
||
#define PWM_FREQUENCY 20000 // 20kHz PWM频率
|
||
#define PWM_RESOLUTION 100 // 100级调速分辨率
|
||
|
||
static uint8_t pwm_counter = 0; // PWM计数器
|
||
|
||
// 定时器初始化
|
||
void PWM_Timer_Init(void) {
|
||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
|
||
// 使能TIM2时钟
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
||
|
||
// 定时器基础配置
|
||
TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock / (2 * PWM_FREQUENCY)) - 1; // 168MHz/2/20kHz
|
||
TIM_TimeBaseStructure.TIM_Prescaler = 0;
|
||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
|
||
|
||
// 使能定时器更新中断
|
||
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||
|
||
// 配置NVIC
|
||
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
// 启动定时器
|
||
TIM_Cmd(TIM2, ENABLE);
|
||
}
|
||
|
||
// 定时器中断处理函数
|
||
void TIM2_IRQHandler(void) {
|
||
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
|
||
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||
|
||
pwm_counter++;
|
||
if (pwm_counter >= PWM_RESOLUTION) {
|
||
pwm_counter = 0;
|
||
}
|
||
|
||
// 根据占空比和方向控制电机
|
||
if (motor_dir == MOTOR_FORWARD) {
|
||
if (pwm_counter < pwm_duty) {
|
||
// 正转:IN1=1, IN2=0
|
||
GPIO_SetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
} else {
|
||
// 停止(滑行)
|
||
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
}
|
||
}
|
||
else if (motor_dir == MOTOR_REVERSE) {
|
||
if (pwm_counter < pwm_duty) {
|
||
// 反转:IN1=0, IN2=1
|
||
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_SetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
} else {
|
||
// 停止(滑行)
|
||
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
}
|
||
}
|
||
else {
|
||
// 停止状态
|
||
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
|
||
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 设置电机速度和方向
|
||
void Motor_SetSpeed(uint8_t speed, MotorState direction) {
|
||
// 限制速度范围
|
||
if (speed > 100) speed = 100;
|
||
|
||
// 如果速度为0或100%,直接使用基础控制
|
||
if (speed == 0) {
|
||
motor_dir = MOTOR_STOP;
|
||
pwm_duty = 0;
|
||
Motor_Control(MOTOR_STOP);
|
||
}
|
||
else if (speed == 100) {
|
||
motor_dir = direction;
|
||
pwm_duty = 100;
|
||
Motor_Control(direction);
|
||
}
|
||
else {
|
||
// 设置PWM参数
|
||
motor_dir = direction;
|
||
pwm_duty = speed; // 直接使用百分比
|
||
}
|
||
}
|