420 lines
12 KiB
C
420 lines
12 KiB
C
#include "Config.h"
|
|
#include "ls1x.h"
|
|
#include "foc_tim.h"
|
|
#include "test.h"
|
|
#include "ls1c103_map.h"
|
|
#include "ls1c103_tim.h"
|
|
#include "ls1x_gpio.h"
|
|
|
|
/* 定时器溢出次数 */
|
|
volatile int Foc_Encoder_Overflow_Count = 0;
|
|
motor_rotate_t motor_drive = {0}; // 定义电机驱动管理结构体
|
|
|
|
static motor_dir_t direction = MOTOR_FWD; // 记录方向
|
|
static uint32_t dutyfactor = 0; // 记录占空比
|
|
static uint32_t is_motor_en = 0; // 电机使能
|
|
static uint32_t bldcm_pulse = 0;
|
|
|
|
static void GPIO_Configuration_Foc(void)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
|
AFIO_RemapConfig(AFIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5, GPIO_FUNC_MAIN);
|
|
|
|
/* GPIOA Configuration: Channel 1, 2, 3 and 4 as alternate function push-pull */
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_4;
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
|
|
/* GPIOA Configuration: Channel 1N, 2N and 3N as alternate function push-pull */
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_5;
|
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
}
|
|
|
|
static void GPIO_Configuration_Encoder(void)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
|
AFIO_RemapConfig(AFIOA, GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9, GPIO_FUNC_MAIN);
|
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
}
|
|
|
|
static void GPIO_Configuration_EN(void)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
AFIO_PORTA &= ~((uint32_t)0x0C000000);
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
GPIO_SetBits(GPIOA, GPIO_Pin_13);
|
|
}
|
|
|
|
static void TIM_MOTOR_CONFIG(){
|
|
uint32_t tmpcr1;
|
|
uint32_t tmpccmrx;
|
|
uint32_t tmpccer;
|
|
uint32_t tmpcr2;
|
|
|
|
tmpcr1 = MOTOR_TIM->CR1;
|
|
tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
|
|
tmpcr1 |= TIM_CounterMode_Up;
|
|
tmpcr1 &= ~TIM_CR1_CKD;
|
|
tmpcr1 |= TIM_CKD_DIV1;
|
|
tmpcr1 |= TIM_CR1_ARPE;
|
|
MOTOR_TIM->CR1 = tmpcr1;
|
|
/* Set the Autoreload value */
|
|
MOTOR_TIM->ARR = (uint32_t)PWM_PERIOD_COUNT - 1;
|
|
/* Set the Prescaler value */
|
|
MOTOR_TIM->PSC = PWM_PRESCALER_COUNT - 1;
|
|
MOTOR_TIM->RCR = 0;
|
|
MOTOR_TIM->EGR = TIM_EGR_UG;
|
|
|
|
/*PWM模式配置*/
|
|
//配置为PWM模式1
|
|
// 初始化通道 1 输出 PWM
|
|
MOTOR_TIM->CCER &= ~TIM_CCER_CC1E;
|
|
/* Get the TIMx CCER register value */
|
|
tmpccer = MOTOR_TIM->CCER;
|
|
/* Get the TIMx CR2 register value */
|
|
tmpcr2 = MOTOR_TIM->CR2;
|
|
/* Get the TIMx CCMR1 register value */
|
|
tmpccmrx = MOTOR_TIM->CCMR1;
|
|
/* Reset the Output Compare Mode Bits */
|
|
tmpccmrx &= ~TIM_CCMR1_OC1M;
|
|
tmpccmrx &= ~TIM_CCMR1_CC1S;
|
|
/* Select the Output Compare Mode */
|
|
tmpccmrx |= TIM_OCMode_PWM1;
|
|
/* Reset the Output Polarity level */
|
|
tmpccer &= ~TIM_CCER_CC1P;
|
|
/* Set the Output Compare Polarity */
|
|
tmpccer |= TIM_OCPolarity_High;
|
|
/* Reset the Output N Polarity level */
|
|
tmpccer &= ~TIM_CCER_CC1NP;
|
|
/* Set the Output N Polarity */
|
|
tmpccer |= TIM_OCNPolarity_High;
|
|
/* Reset the Output N State */
|
|
tmpccer &= ~TIM_CCER_CC1NE;
|
|
/* Reset the Output Compare and Output Compare N IDLE State */
|
|
tmpcr2 &= ~TIM_CR2_OIS1;
|
|
tmpcr2 &= ~TIM_CR2_OIS1N;
|
|
/* Set the Output Idle state */
|
|
tmpcr2 |= TIM_OCIdleState_Reset;
|
|
// /* Set the Output N Idle state */
|
|
tmpcr2 |= TIM_OCNIdleState_Reset;
|
|
/* Write to TIMx CR2 */
|
|
MOTOR_TIM->CR2 = tmpcr2;
|
|
/* Write to TIMx CCMR1 */
|
|
MOTOR_TIM->CCMR1 = tmpccmrx;
|
|
/* Set the Capture Compare Register value */
|
|
MOTOR_TIM->CCR1 = 0;
|
|
/* Write to TIMx CCER */
|
|
MOTOR_TIM->CCER = tmpccer;
|
|
MOTOR_TIM->CCMR1 |= TIM_CCMR1_OC1PE;
|
|
|
|
// 初始化通道 2 输出 PWM
|
|
MOTOR_TIM->CCER &= ~TIM_CCER_CC2E;
|
|
/* Get the TIMx CCER register value */
|
|
tmpccer = MOTOR_TIM->CCER;
|
|
/* Get the TIMx CR2 register value */
|
|
tmpcr2 = MOTOR_TIM->CR2;
|
|
/* Get the TIMx CCMR1 register value */
|
|
tmpccmrx = MOTOR_TIM->CCMR1;
|
|
/* Reset the Output Compare Mode Bits */
|
|
tmpccmrx &= ~TIM_CCMR1_OC2M;
|
|
tmpccmrx &= ~TIM_CCMR1_CC2S;
|
|
/* Select the Output Compare Mode */
|
|
tmpccmrx |= (TIM_OCMode_PWM1 << 8);
|
|
/* Reset the Output Polarity level */
|
|
tmpccer &= ~TIM_CCER_CC2P;
|
|
/* Set the Output Compare Polarity */
|
|
tmpccer |= (TIM_OCPolarity_High << 4);
|
|
/* Reset the Output N Polarity level */
|
|
tmpccer &= ~TIM_CCER_CC2NP;
|
|
/* Set the Output N Polarity */
|
|
tmpccer |= (TIM_OCNPolarity_High << 4);
|
|
/* Reset the Output N State */
|
|
tmpccer &= ~TIM_CCER_CC2NE;
|
|
/* Reset the Output Compare and Output Compare N IDLE State */
|
|
tmpcr2 &= ~TIM_CR2_OIS2;
|
|
tmpcr2 &= ~TIM_CR2_OIS2N;
|
|
/* Set the Output Idle state */
|
|
tmpcr2 |= (TIM_OCIdleState_Reset << 2);
|
|
/* Set the Output N Idle state */
|
|
tmpcr2 |= (TIM_OCNIdleState_Reset << 2);
|
|
/* Write to TIMx CR2 */
|
|
MOTOR_TIM->CR2 = tmpcr2;
|
|
/* Write to TIMx CCMR1 */
|
|
MOTOR_TIM->CCMR1 = tmpccmrx;
|
|
/* Set the Capture Compare Register value */
|
|
MOTOR_TIM->CCR2 = 0;
|
|
/* Write to TIMx CCER */
|
|
MOTOR_TIM->CCER = tmpccer;
|
|
MOTOR_TIM->CCMR1 |= TIM_CCMR1_OC2PE;
|
|
|
|
// 初始化通道 3 输出 PWM
|
|
MOTOR_TIM->CCER &= ~TIM_CCER_CC3E;
|
|
/* Get the TIMx CCER register value */
|
|
tmpccer = MOTOR_TIM->CCER;
|
|
/* Get the TIMx CR2 register value */
|
|
tmpcr2 = MOTOR_TIM->CR2;
|
|
/* Get the TIMx CCMR1 register value */
|
|
tmpccmrx = MOTOR_TIM->CCMR2;
|
|
/* Reset the Output Compare Mode Bits */
|
|
tmpccmrx &= ~TIM_CCMR2_OC3M;
|
|
tmpccmrx &= ~TIM_CCMR2_CC3S;
|
|
/* Select the Output Compare Mode */
|
|
tmpccmrx |= TIM_OCMode_PWM1;
|
|
/* Reset the Output Polarity level */
|
|
tmpccer &= ~TIM_CCER_CC3P;
|
|
/* Set the Output Compare Polarity */
|
|
tmpccer |= (TIM_OCPolarity_High << 8);
|
|
/* Reset the Output N Polarity level */
|
|
tmpccer &= ~TIM_CCER_CC3NP;
|
|
/* Set the Output N Polarity */
|
|
tmpccer |= (TIM_OCNPolarity_High << 8);
|
|
/* Reset the Output N State */
|
|
tmpccer &= ~TIM_CCER_CC3NE;
|
|
/* Reset the Output Compare and Output Compare N IDLE State */
|
|
tmpcr2 &= ~TIM_CR2_OIS3;
|
|
tmpcr2 &= ~TIM_CR2_OIS3N;
|
|
/* Set the Output Idle state */
|
|
tmpcr2 |= (TIM_OCIdleState_Reset << 4);
|
|
/* Set the Output N Idle state */
|
|
tmpcr2 |= (TIM_OCNIdleState_Reset << 4);
|
|
/* Write to TIMx CR2 */
|
|
MOTOR_TIM->CR2 = tmpcr2;
|
|
/* Write to TIMx CCMR1 */
|
|
MOTOR_TIM->CCMR2 = tmpccmrx;
|
|
/* Set the Capture Compare Register value */
|
|
MOTOR_TIM->CCR3 = 0;
|
|
/* Write to TIMx CCER */
|
|
MOTOR_TIM->CCER = tmpccer;
|
|
MOTOR_TIM->CCMR2 |= TIM_CCMR2_OC3PE;
|
|
|
|
/* 配置触发源 */
|
|
MOTOR_TIM->SMCR &= ~TIM_SMCR_TS;
|
|
MOTOR_TIM->SMCR |= TIM_COM_TS_ITRx;
|
|
/* Select the Capture Compare preload feature */
|
|
//MOTOR_TIM->CR2 |= TIM_CR2_CCPC;
|
|
/* Select the Commutation event source */
|
|
MOTOR_TIM->CR2 &= ~TIM_CR2_CCUS;
|
|
// MOTOR_TIM->CR2 |= TIM_COMMUTATION_SOFTWARE;
|
|
/* Disable Commutation Interrupt */
|
|
MOTOR_TIM->DIER &= ~TIM_IT_COM;
|
|
/* Disable Commutation DMA request */
|
|
MOTOR_TIM->DIER &= ~TIM_DMA_COM;
|
|
|
|
/* 开启定时器通道1输出PWM */
|
|
/* Reset the CCxE Bit */
|
|
MOTOR_TIM->CCER &= ~(uint32_t)(TIM_CCER_CC1E);
|
|
/* Set or reset the CCxE Bit */
|
|
MOTOR_TIM->CCER |= (uint32_t)(TIM_CCER_CC1E);
|
|
|
|
/* 开启定时器通道2输出PWM */
|
|
/* Reset the CCxE Bit */
|
|
MOTOR_TIM->CCER &= ~(uint32_t)(TIM_CCER_CC2E);
|
|
/* Set or reset the CCxE Bit */
|
|
MOTOR_TIM->CCER |= (uint32_t)(TIM_CCER_CC2E);
|
|
/* 开启定时器通道3输出PWM */
|
|
/* Reset the CCxE Bit */
|
|
MOTOR_TIM->CCER &= ~(uint32_t)(TIM_CCER_CC3E);
|
|
/* Set or reset the CCxE Bit */
|
|
MOTOR_TIM->CCER |= (uint32_t)(TIM_CCER_CC3E);
|
|
|
|
MOTOR_TIM->CCER |= (uint32_t)(TIM_CCER_CC1NE);
|
|
MOTOR_TIM->CCER |= (uint32_t)(TIM_CCER_CC2NE);
|
|
MOTOR_TIM->CCER |= (uint32_t)(TIM_CCER_CC3NE);
|
|
|
|
MOTOR_TIM->SR &= ~TIM_IT_Update;
|
|
MOTOR_TIM->DIER &= ~TIM_IT_Update;
|
|
|
|
MOTOR_TIM->BDTR &= ~(TIM_BDTR_MOE);
|
|
MOTOR_TIM->CR1 &= ~TIM_CR1_CEN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 配置TIMx
|
|
* @param 无
|
|
* @retval 无
|
|
*/
|
|
static void TIM_Encoder_Init(void)
|
|
{
|
|
uint32_t tmpcr1;
|
|
uint32_t tmpsmcr;
|
|
uint32_t tmpccmr1;
|
|
uint32_t tmpccer;
|
|
|
|
ENCODER_TIM->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_ECE);
|
|
/* Configure the Time base in the Encoder Mode */
|
|
tmpcr1 = ENCODER_TIM->CR1;
|
|
tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
|
|
tmpcr1 |= TIM_CounterMode_Up;
|
|
tmpcr1 &= ~TIM_CR1_CKD;
|
|
tmpcr1 |= (uint32_t)TIM_CKD_DIV1;
|
|
ENCODER_TIM->CR1 = tmpcr1;
|
|
/* Set the Autoreload value */
|
|
ENCODER_TIM->ARR = (uint32_t)ENCODER_TIM_PERIOD - 1 ;
|
|
/* Set the Prescaler value */
|
|
ENCODER_TIM->PSC = ENCODER_TIM_PRESCALER;
|
|
ENCODER_TIM->RCR = 0;
|
|
ENCODER_TIM->EGR = TIM_EGR_UG;
|
|
|
|
/* Get the TIMx SMCR register value */
|
|
tmpsmcr = ENCODER_TIM->SMCR;
|
|
/* Get the TIMx CCMR1 register value */
|
|
tmpccmr1 = ENCODER_TIM->CCMR1;
|
|
/* Get the TIMx CCER register value */
|
|
tmpccer = ENCODER_TIM->CCER;
|
|
/* Set the encoder Mode */
|
|
tmpsmcr |= TIM_EncoderMode_TI12;
|
|
/* Select the Capture Compare 1 and the Capture Compare 2 as input */
|
|
tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S);
|
|
tmpccmr1 |= (TIM_ICSelection_DirectTI | (TIM_ICSelection_DirectTI << 8U));
|
|
/* Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */
|
|
tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC);
|
|
tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F);
|
|
tmpccmr1 |= TIM_ICPSC_DIV1 | (TIM_ICPSC_DIV1 << 8U);
|
|
tmpccmr1 |= (0 << 4U) | (0 << 12U);
|
|
/* Set the TI1 and the TI2 Polarities */
|
|
tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);
|
|
tmpccer |= TIM_ICPolarity_Rising | (TIM_ICPolarity_Rising << 4U);
|
|
/* Write to TIMx SMCR */
|
|
ENCODER_TIM->SMCR = tmpsmcr;
|
|
/* Write to TIMx CCMR1 */
|
|
ENCODER_TIM->CCMR1 = tmpccmr1;
|
|
/* Write to TIMx CCER */
|
|
ENCODER_TIM->CCER = tmpccer;
|
|
|
|
/* 清零计数器 */
|
|
ENCODER_TIM->CNT = 0;
|
|
|
|
/* 清零中断标志位 */
|
|
ENCODER_TIM->SR = ~(TIM_IT_Update);
|
|
/* 使能定时器的更新事件中断 */
|
|
ENCODER_TIM->DIER |= (TIM_IT_Update);
|
|
/* 设置更新事件请求源为:计数器溢出 */
|
|
ENCODER_TIM->CR1|= TIM_CR1_URS;
|
|
|
|
/* 使能编码器接口 */
|
|
/* Reset the CCxE Bit */
|
|
ENCODER_TIM->CCER &= ~TIM_CCER_CC1E;
|
|
/* Set or reset the CCxE Bit */
|
|
ENCODER_TIM->CCER |= TIM_CCER_CC1E; /* 0x1FU = 31 bits max shift */
|
|
/* Reset the CCxE Bit */
|
|
ENCODER_TIM->CCER &= ~TIM_CCER_CC2E;
|
|
/* Set or reset the CCxE Bit */
|
|
ENCODER_TIM->CCER |= TIM_CCER_CC2E; /* 0x1FU = 31 bits max shift */
|
|
ENCODER_TIM->CR1 &= ~(TIM_CR1_CEN);
|
|
|
|
}
|
|
|
|
static void TIM_BASIC_CONFIG(void)
|
|
{
|
|
uint32_t tmpcr1;
|
|
|
|
tmpcr1 = BASIC_TIM->CR1;
|
|
tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
|
|
tmpcr1 |= TIM_CounterMode_Up;
|
|
tmpcr1 &= ~TIM_CR1_CKD;
|
|
tmpcr1 |= (uint32_t)TIM_CKD_DIV1;
|
|
tmpcr1 |= TIM_CR1_ARPE;
|
|
BASIC_TIM->CR1 = tmpcr1;
|
|
|
|
/* Set the Autoreload value */
|
|
BASIC_TIM->ARR = (uint32_t)BASIC_PERIOD_COUNT ;
|
|
|
|
/* Set the Prescaler value */
|
|
BASIC_TIM->PSC = BASIC_PRESCALER_COUNT ;
|
|
|
|
BASIC_TIM->EGR = TIM_EGR_UG;
|
|
|
|
// 开启定时器更新中断
|
|
BASIC_TIM->SR = ~TIM_IT_Update;
|
|
//BASIC_TIM->DIER |= (TIM_IT_Update);
|
|
//BASIC_TIM->CR1|=(TIM_CR1_CEN);
|
|
// intc enable
|
|
INT_EN = 0x1;
|
|
|
|
}
|
|
|
|
|
|
void FocMotor_Init(){
|
|
GPIO_Configuration_Foc();
|
|
TIM_MOTOR_CONFIG();
|
|
GPIO_Configuration_EN();
|
|
printf("Motor config complete\n");
|
|
}
|
|
|
|
/**
|
|
* @brief HALL接口初始化
|
|
* @param 无
|
|
* @retval 无
|
|
*/
|
|
void FocEncoder_Init(void)
|
|
{
|
|
GPIO_Configuration_Encoder();
|
|
TIM_Encoder_Init();
|
|
printf("Encoder config complete\n");
|
|
}
|
|
|
|
|
|
void FocBasicTim_Init(){
|
|
TIM_BASIC_CONFIG();
|
|
printf("Basic config complete\n");
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief 停止pwm输出
|
|
* @param 无
|
|
* @retval 无
|
|
*/
|
|
|
|
void foc_stop_pwm_output(void)
|
|
{
|
|
MOTOR_TIM->BDTR &= ~(TIM_BDTR_MOE);
|
|
/* 关闭定时器通道1输出PWM */
|
|
MOTOR_TIM->CCR1 = 0;
|
|
/* 关闭定时器通道2输出PWM */
|
|
MOTOR_TIM->CCR2 = 0;
|
|
/* 关闭定时器通道3输出PWM */
|
|
MOTOR_TIM->CCR3 = 0;
|
|
}
|
|
|
|
|
|
void mc_angle_init()
|
|
{
|
|
ENCODER_TIM->CNT = 0;
|
|
Foc_Encoder_Overflow_Count = 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Description : 返回电机转子的电角度
|
|
* Return : Rotor electrical angle: 0 -> 0 degrees,
|
|
* S16_MAX-> 180 degrees,
|
|
* S16_MIN-> -180 degrees
|
|
*******************************************************************************/
|
|
int Get_Electrical_Angle(void)
|
|
{
|
|
int temp;
|
|
|
|
temp = (int)(ENCODER_TIM->CNT) * (int)(UINT32_MAX / (4*ENCODER_RESOLUTION));
|
|
temp *= POLE_PAIR_NUM;
|
|
return((int)(temp/65536)); //s16 result
|
|
}
|
|
|
|
|
|
|