sensor_2026/HARDWARE/MOTOR/motor_driver.c

183 lines
5.8 KiB
C
Raw Normal View History

// motor_driver.c
#include "motor_driver.h"
#include "delay.h"
// ȫ<>ֱ<EFBFBD><D6B1><EFBFBD>
static uint8_t pwm_duty = 0; // PWMռ<4D>ձ<EFBFBD> 0-100
static MotorState motor_dir = MOTOR_STOP;
// GPIO<49><4F>ʼ<EFBFBD><CABC>
void DRV8832_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// ʹ<><CAB9>GPIOEʱ<45><CAB1>
RCC_AHB1PeriphClockCmd(MOTOR_IN1_GPIO_CLK, ENABLE);
// <20><><EFBFBD><EFBFBD>IN1 (PE9) <20><> IN2 (PE13) Ϊ<><CEAA><EFBFBD><EFBFBD>
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; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(MOTOR_IN1_GPIO_PORT, &GPIO_InitStructure);
// <20><><EFBFBD><EFBFBD>FAULTN (PE4) Ϊ<><CEAA><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Pin = MOTOR_FAULT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // <20><><EFBFBD><EFBFBD>
GPIO_Init(MOTOR_FAULT_GPIO_PORT, &GPIO_InitStructure);
// <20><>ʼ״̬<D7B4><CCAC>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
GPIO_ResetBits(MOTOR_IN1_GPIO_PORT, MOTOR_IN1_GPIO_PIN);
GPIO_ResetBits(MOTOR_IN2_GPIO_PORT, MOTOR_IN2_GPIO_PIN);
}
// <20><>ʼ<EFBFBD><CABC>DRV8832
void DRV8832_Init(void) {
DRV8832_GPIO_Init();
}
//=====================================================================================
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD>
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;
}
}
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>״̬
uint8_t Motor_GetFaultStatus(void) {
// FAULTN<54><4E><EFBFBD><EFBFBD>Ϊ<EFBFBD>͵<EFBFBD>ƽʱ<C6BD><CAB1>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
if (GPIO_ReadInputDataBit(MOTOR_FAULT_GPIO_PORT, MOTOR_FAULT_GPIO_PIN) == Bit_RESET) {
return 1; // <20><><EFBFBD><EFBFBD>
}
return 0; // <20><><EFBFBD><EFBFBD>
}
// <20><>ȫ<EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Motor_SafeDirectionChange(MotorState new_direction) {
// <20><>ɲ<EFBFBD><C9B2>
Motor_Control(MOTOR_BRAKE);
delay_ms(5); // 5ms<6D>ӳ<EFBFBD>
// <20><><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>
Motor_Control(new_direction);
}
// ʹ<><CAB9>TIM2ʵ<32><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PWM
#define PWM_FREQUENCY 20000 // 20kHz PWMƵ<4D><C6B5>
#define PWM_RESOLUTION 100 // 100<30><30><EFBFBD><EFBFBD><EFBFBD>ٷֱ<D9B7><D6B1><EFBFBD>
static uint8_t pwm_counter = 0; // PWM<57><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
void PWM_Timer_Init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// ʹ<><CAB9>TIM2ʱ<32><CAB1>
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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);
// ʹ<>ܶ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// <20><><EFBFBD><EFBFBD>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);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
TIM_Cmd(TIM2, ENABLE);
}
// <20><>ʱ<EFBFBD><CAB1><EFBFBD>жϴ<D0B6><CFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}
// <20><><EFBFBD><EFBFBD>ռ<EFBFBD>ձȺͷ<C8BA><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>
if (motor_dir == MOTOR_FORWARD) {
if (pwm_counter < pwm_duty) {
// <20><>ת<EFBFBD><D7AA>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 {
// ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>
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) {
// <20><>ת<EFBFBD><D7AA>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 {
// ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>
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);
}
}
}
// <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>ٶȺͷ<C8BA><CDB7><EFBFBD>
void Motor_SetSpeed(uint8_t speed, MotorState direction) {
// <20><><EFBFBD><EFBFBD><EFBFBD>ٶȷ<D9B6>Χ
if (speed > 100) speed = 100;
// <20><><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>Ϊ0<CEAA><30>100%<25><>ֱ<EFBFBD><D6B1>ʹ<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 {
// <20><><EFBFBD><EFBFBD>PWM<57><4D><EFBFBD><EFBFBD>
motor_dir = direction;
pwm_duty = speed; // ֱ<><D6B1>ʹ<EFBFBD>ðٷֱ<D9B7>
}
}