#include "gpio.h"
|
#include "motor.h"
|
#include "gd32e23x_exti.h"
|
#include "gd32e23x_timer.h"
|
#include "bldc_ctrl.h"
|
#include "pwm.h"
|
#include "string.h"
|
#include "SEGGER_RTT_Conf.h"
|
#include "SEGGER_RTT.h"
|
static volatile motor_rotate_t motor_drive = {0};
|
static uint32_t motor_pluse = 1500;
|
static volatile uint8_t motor_step = 0;
|
static void motor_phasechange(void);
|
static void update_speed_dir(uint8_t dir_in);
|
|
extern void Motor_Init(void)
|
{
|
motor_drive.timeout = 0;
|
motor_drive.speed = 0;
|
motor_drive.enable_flag = 0;
|
motor_pluse = 0;
|
memset(motor_drive.speed_group, 0, SPEED_FILTER_NUM);
|
|
// hall_enable();
|
};
|
/**
|
* @brief ʹÄÜ»ô¶û´«¸ÐÆ÷
|
* @param ÎÞ
|
* @retval ÎÞ
|
*/
|
void hall_enable(void)
|
{
|
/* ʹÄÜ»ô¶û´«¸ÐÆ÷½Ó¿Ú */
|
exti_interrupt_enable(HALL_A_EXTI);
|
exti_interrupt_enable(HALL_B_EXTI);
|
exti_interrupt_enable(HALL_C_EXTI);
|
StartSpeedTime(); //start speed timer
|
motor_phasechange(); // Ö´ÐÐÒ»´Î»»Ïà
|
|
motor_drive.enable_flag = 1;
|
}
|
|
/**
|
* @brief ½ûÓûô¶û´«¸ÐÆ÷
|
* @param ÎÞ
|
* @retval ÎÞ
|
*/
|
void hall_disable(void)
|
{
|
/* ½ûÓûô¶û´«¸ÐÆ÷½Ó¿Ú */
|
exti_interrupt_disable(HALL_A_EXTI);
|
exti_interrupt_disable(HALL_B_EXTI);
|
exti_interrupt_disable(HALL_C_EXTI);
|
// HAL_TIMEx_HallSensor_Stop(&htimx_hall);
|
StopSpeedTime(); //stop speed timer
|
motor_drive.enable_flag = 0;
|
motor_drive.speed = 0;
|
}
|
|
uint8_t get_hall_state(void)
|
{
|
uint8_t state = 0;
|
/* ¶ÁÈ¡»ô¶û´«¸ÐÆ÷ U µÄ״̬ */
|
if (Get_HallSensorA_State())
|
{
|
state |= (0x01U << 0);
|
}
|
|
/* ¶ÁÈ¡»ô¶û´«¸ÐÆ÷ V µÄ״̬ */
|
if (Get_HallSensorB_State())
|
{
|
state |= (0x01U << 1);
|
}
|
|
/* ¶ÁÈ¡»ô¶û´«¸ÐÆ÷ W µÄ״̬ */
|
if (Get_HallSensorC_State())
|
{
|
state |= (0x01U << 2);
|
}
|
|
return state; // ·µ»Ø´«¸ÐÆ÷״̬
|
}
|
static uint8_t count = 0;
|
static void update_motor_speed(uint8_t dir_in, uint32_t time)
|
{
|
int speed_temp = 0;
|
static int flag = 0;
|
float f = 0;
|
|
/* ¼ÆËãËÙ¶È£º
|
µç»úÿתһȦ¹²ÓÃ12¸öÂö³å£¬(1.0/(64000000.0/6400)Ϊ¼ÆÊýÆ÷µÄÖÜÆÚ£¬(1.0/(64000000.0/6400) * time)Ϊʱ¼ä³¤¡£
|
*/
|
|
if (time == 0)
|
motor_drive.speed_group[count++] = 0;
|
else
|
{
|
// f = (1.0f / (64000000.0f / SPEED_PRESCALER_COUNT) * time);
|
// f = (1.0f / 12.0f) / (f / 60.0f);
|
f = time;
|
motor_drive.speed_group[count++] = f;
|
}
|
update_speed_dir(dir_in);
|
// motor_drive.speed = motor_drive.speed_group[count-1];
|
if (count >= SPEED_FILTER_NUM)
|
{
|
flag = 1;
|
count = 0;
|
}
|
// return ;
|
speed_temp = 0;
|
|
/* ¼ÆËã½ü SPEED_FILTER_NUM ´ÎµÄËÙ¶ÈÆ½¾ùÖµ£¨Â˲¨£© */
|
if (flag)
|
{
|
for (uint8_t c = 0; c < SPEED_FILTER_NUM; c++)
|
{
|
speed_temp += motor_drive.speed_group[c];
|
}
|
|
motor_drive.speed = speed_temp / SPEED_FILTER_NUM;
|
}
|
else
|
{
|
for (uint8_t c = 0; c < count; c++)
|
{
|
speed_temp += motor_drive.speed_group[c];
|
}
|
|
motor_drive.speed = speed_temp / count;
|
}
|
}
|
|
/**
|
* @brief »ñÈ¡µç»úתËÙ
|
* @param time:»ñÈ¡µÄʱ¼ä¼ä¸ô
|
* @retval ·µ»Øµç»úתËÙ
|
*/
|
float get_motor_speed(void)
|
{
|
return motor_drive.speed;
|
}
|
|
/**
|
* @brief ¸üеç»úʵ¼ÊËÙ¶È·½Ïò
|
* @param dir_in£º»ô¶ûÖµ
|
* @retval ÎÞ
|
*/
|
static void update_speed_dir(uint8_t dir_in)
|
{
|
uint8_t step[6] = {1, 3, 2, 6, 4, 5};
|
|
static uint8_t num_old = 0;
|
uint8_t step_loc = 0; // ¼Ç¼µ±Ç°»ô¶ûλÖÃ
|
int8_t dir = 1;
|
|
for (step_loc = 0; step_loc < 6; step_loc++)
|
{
|
if (step[step_loc] == dir_in) // ÕÒµ½µ±Ç°»ô¶ûµÄλÖÃ
|
{
|
break;
|
}
|
}
|
|
/* ¶Ëµã´¦Àí */
|
if (step_loc == 0)
|
{
|
if (num_old == 1)
|
{
|
dir = 1;
|
}
|
else if (num_old == 5)
|
{
|
dir = -1;
|
}
|
}
|
/* ¶Ëµã´¦Àí */
|
else if (step_loc == 5)
|
{
|
if (num_old == 0)
|
{
|
dir = 1;
|
}
|
else if (num_old == 4)
|
{
|
dir = -1;
|
}
|
}
|
else if (step_loc > num_old)
|
{
|
dir = -1;
|
}
|
else if (step_loc < num_old)
|
{
|
dir = 1;
|
}
|
|
num_old = step_loc;
|
// motor_drive.speed *= dir;;
|
motor_drive.speed_group[count - 1] *= dir;
|
}
|
|
/**
|
* @brief »ô¶û´«¸ÐÆ÷´¥·¢»Øµ÷º¯Êý
|
* @param void
|
* @retval ÎÞ
|
*/
|
void HAL_HallExti_TriggerCallback(void)
|
{
|
uint8_t step = 0;
|
motor_step = get_hall_state();
|
// /* »ñÈ¡»ô¶û´«¸ÐÆ÷Òý½Å״̬,×÷Ϊ»»ÏàµÄÒÀ¾Ý */
|
if (exti_interrupt_flag_get(HALL_A_EXTI | HALL_B_EXTI | HALL_C_EXTI)) // ÅжÏÊÇ·ñÓÉ´¥·¢ÖжϲúÉú
|
{
|
// update_motor_speed(motor_step, 300u * GetSpeedTimerOutcnt() + timer_counter_read(TIMER2));
|
SEGGER_RTT_printf(0, "motor speed is:%d,%d!\n", GetSpeedTimerOutcnt(), timer_counter_read(TIMER2));
|
timer_counter_value_config(TIMER2, 0);
|
motor_drive.timeout = 0;
|
}
|
motor_phasechange();
|
// HAL_TIM_GenerateEvent(&htimx_bldcm, TIM_EVENTSOURCE_COM); // Èí¼þ²úÉú»»Ïàʼþ£¬´Ëʱ²Å½«ÅäÖÃдÈë
|
}
|
|
static void motor_phasechange(void)
|
{
|
uint8_t step = 0;
|
step = get_hall_state();
|
if (get_bldcm_direction() == MOTOR_FWD)
|
{
|
step = 7u - step;
|
}
|
switch (step)
|
{
|
/* next step: step 3 configuration .W-U` breakover---------------------------- */
|
case 1:
|
/* channel U configuration */
|
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_U, 0);
|
MOTOR_U_L_ENABLE;
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCXN_DISABLE);
|
|
/* channel V configuration */
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_V, 0);
|
MOTOR_V_L_DISABLE;
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_DISABLE);
|
|
/* channel W configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_W, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCX_ENABLE);
|
SetPwmDuty(MOTOR_OUT_CH_W, motor_pluse);
|
MOTOR_W_L_DISABLE;
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_ENABLE);
|
|
break;
|
|
/* next step: step 6 configuration .u-v` breakover---------------------------- */
|
case 2:
|
/* channel U configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_U, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCX_ENABLE);
|
SetPwmDuty(MOTOR_OUT_CH_U, motor_pluse);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCXN_DISABLE);
|
MOTOR_U_L_DISABLE;
|
|
/* channel V configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_V, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_V, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_DISABLE);
|
MOTOR_V_L_ENABLE;
|
|
/* channel W configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_W, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_W, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_ENABLE);
|
MOTOR_W_L_DISABLE;
|
|
break;
|
|
/* next step: step 2 configuration .W-V` breakover---------------------------- */
|
case 3:
|
/* channel U configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_U, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_U, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCXN_ENABLE);
|
MOTOR_U_L_DISABLE;
|
|
/* channel V configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_V, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_V, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_DISABLE);
|
MOTOR_V_L_ENABLE;
|
|
/* channel W configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_W, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCX_ENABLE);
|
SetPwmDuty(MOTOR_OUT_CH_W, motor_pluse);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_DISABLE);
|
MOTOR_W_L_DISABLE;
|
|
break;
|
|
/* next step: step 5 configuration .V-W` breakover---------------------------- */
|
case 4:
|
/* channel U configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_U, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCX_DISABLE);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCXN_ENABLE);
|
SetPwmDuty(MOTOR_OUT_CH_U, 0);
|
MOTOR_U_L_DISABLE;
|
|
/* channel V configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_V, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_ENABLE);
|
SetPwmDuty(MOTOR_OUT_CH_V, motor_pluse);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_DISABLE);
|
MOTOR_V_L_DISABLE;
|
|
/* channel W configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_W, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_W, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_DISABLE);
|
MOTOR_W_L_ENABLE;
|
|
break;
|
|
/* next step: step 1 configuration .V-U` breakover---------------------------- */
|
case 5:
|
/* channel U configuration */
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_U, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCXN_DISABLE);
|
MOTOR_U_L_ENABLE;
|
|
/* channel V configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_V, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_ENABLE);
|
SetPwmDuty(MOTOR_OUT_CH_V, motor_pluse);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_ENABLE);
|
MOTOR_V_L_DISABLE;
|
|
/* channel W configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_W, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_W, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_DISABLE);
|
MOTOR_W_L_DISABLE;
|
break;
|
|
/* next step: step 4 configuration .U-W` breakover---------------------------- */
|
case 6:
|
/* channel U configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_U, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCX_ENABLE);
|
SetPwmDuty(MOTOR_OUT_CH_U, motor_pluse);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_U, TIMER_CCXN_DISABLE);
|
MOTOR_U_L_DISABLE;
|
|
/* channel V configuration */
|
// timer_channel_output_mode_config(TIMER0, MOTOR_OUT_CH_V, TIMER_OC_MODE_PWM0);
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_V, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_V, TIMER_CCXN_ENABLE);
|
MOTOR_V_L_DISABLE;
|
|
/* channel W configuration */
|
// timer_channel_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCX_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_W, 0);
|
// timer_channel_complementary_output_state_config(TIMER0, MOTOR_OUT_CH_W, TIMER_CCXN_DISABLE);
|
MOTOR_W_L_ENABLE;
|
|
break;
|
}
|
}
|
|
/**
|
* @brief Í£Ö¹pwmÊä³ö
|
* @param ÎÞ
|
* @retval ÎÞ
|
*/
|
extern void stop_pwm_output(void)
|
{
|
// timer_channel_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCX_DISABLE);
|
// timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_0, TIMER_CCXN_DISABLE);
|
// timer_channel_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCX_DISABLE);
|
// timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_1, TIMER_CCXN_DISABLE);
|
// timer_channel_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCX_DISABLE);
|
// timer_channel_complementary_output_state_config(TIMER0, TIMER_CH_2, TIMER_CCXN_DISABLE);
|
SetPwmDuty(MOTOR_OUT_CH_U, 0);
|
SetPwmDuty(MOTOR_OUT_CH_V, 0);
|
SetPwmDuty(MOTOR_OUT_CH_W, 0);
|
MOTOR_W_L_DISABLE;
|
MOTOR_V_L_DISABLE;
|
MOTOR_U_L_DISABLE;
|
}
|
|
/**
|
* @brief ÉèÖÃpwmÊä³öµÄÕ¼¿Õ±È
|
* @param pulse:ÒªÉèÖõÄÕ¼¿Õ±È
|
* @retval ÎÞ
|
*/
|
void set_pwm_pulse(uint16_t pulse)
|
{
|
/* ÉèÖö¨Ê±Æ÷ͨµÀÊä³ö PWM µÄÕ¼¿Õ±È */
|
motor_pluse = pulse;
|
// SetPwmDuty(TIMER_CH_0, motor_pluse);
|
// SetPwmDuty(TIMER_CH_1, motor_pluse);
|
// SetPwmDuty(TIMER_CH_2, motor_pluse);
|
|
if (motor_drive.enable_flag)
|
{
|
motor_phasechange();
|
}
|
}
|
|
extern void BLDC_SpeedAndPID(void)
|
{
|
if (motor_drive.timeout++ > 100) // ÓÐÒ»´ÎÔÚ²úÉú¸üÐÂÖжÏǰ»ô¶û´«¸ÐÆ÷ûÓв¶»ñµ½Öµ
|
{
|
// printf("¶Âת³¬Ê±\r\n");
|
motor_drive.timeout = 0;
|
|
/* ¶Âת³¬Ê±Í£Ö¹ PWM Êä³ö */
|
hall_disable(); // ½ûÓûô¶û´«¸ÐÆ÷½Ó¿Ú
|
stop_pwm_output(); // Í£Ö¹ PWM Êä³ö
|
set_bldcm_disable();
|
motor_drive.speed = 0;
|
}
|
else
|
{
|
bldcm_pid_control();
|
}
|
}
|