183 lines
5.8 KiB
C
183 lines
5.8 KiB
C
|
|
// 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>
|
|||
|
|
}
|
|||
|
|
}
|