霍尔驱动无刷电机原理和参考网上已经有很多案例了,理工男文笔烂,这里不再重复描述了。网上也有很多源码下载,但是源码下载一堆的积分,一堆的注册,烦死。自己参考芯片厂商的案例库,简单写了个参考,留个机缘给有缘人,望道友笑纳。
先上一张管脚图
为了代码方便查看和上传,直接扔一个main文件里面了
【免费】MM32F0144HALLBLDC实例源码资源-CSDN文库
代码很简单直接上代码了
#define _MAIN_C_
/** Files includes */
#include "main.h"
#include "HAL_conf.h"
#include "HAL_device.h"
#define BLDC1_GPIO_CLK (RCC_AHBENR_GPIOA | RCC_AHBENR_GPIOB)
#define BLDC1_UH_PORT GPIOA
#define BLDC1_UH_PIN GPIO_Pin_8
#define BLDC1_VH_PORT GPIOA
#define BLDC1_VH_PIN GPIO_Pin_9
#define BLDC1_WH_PORT GPIOA
#define BLDC1_WH_PIN GPIO_Pin_10
#define BLDC1_UL_PORT GPIOA
#define BLDC1_UL_PIN GPIO_Pin_7
#define BLDC1_VL_PORT GPIOB
#define BLDC1_VL_PIN GPIO_Pin_0
#define BLDC1_WL_PORT GPIOB
#define BLDC1_WL_PIN GPIO_Pin_1
#define BLDC1_UH_PIN_SRC GPIO_PinSource8
#define BLDC1_VH_PIN_SRC GPIO_PinSource9
#define BLDC1_WH_PIN_SRC GPIO_PinSource10
#define BLDC1_UL_PIN_SRC GPIO_PinSource7
#define BLDC1_VL_PIN_SRC GPIO_PinSource0
#define BLDC1_WL_PIN_SRC GPIO_PinSource1
#define BLDC1_UH_PIN_AF GPIO_AF_2
#define BLDC1_VH_PIN_AF GPIO_AF_2
#define BLDC1_WH_PIN_AF GPIO_AF_2
#define BLDC1_UL_PIN_AF GPIO_AF_2
#define BLDC1_VL_PIN_AF GPIO_AF_2
#define BLDC1_WL_PIN_AF GPIO_AF_2
/** HALL interface */
#define HALL_GPIO_CLK (RCC_AHBENR_GPIOB|RCC_AHBENR_GPIOA)
#define HALL_GPIO_MODE GPIO_Mode_FLOATING
#define HALLU_PORT GPIOA
#define HALLV_PORT GPIOB
#define HALLW_PORT GPIOB
#define HALLU_PIN GPIO_Pin_15
#define HALLV_PIN GPIO_Pin_4
#define HALLW_PIN GPIO_Pin_3
#define HALLU_PIN_AF GPIO_AF_2
#define HALLV_PIN_AF GPIO_AF_7
#define HALLW_PIN_AF GPIO_AF_4
#define HALLU_PIN_SOURCE GPIO_PinSource15
#define HALLV_PIN_SOURCE GPIO_PinSource4
#define HALLW_PIN_SOURCE GPIO_PinSource3
#define THROTTLE_INPUT_GPIO GPIOB
#define THROTTLE_INPUT_PIN GPIO_Pin_5
#define THROTTLE_INPUT_AF GPIO_AF_1
#define THROTTLE_INPUT_PIN_SOURCE GPIO_PinSource5
/** Commutation macro definition */
#define BLDC_UH_ENABLE() TIMCC1_ENABLE()
#define BLDC_UH_DISABLE() TIMCC1_DISABLE()
#define BLDC_VH_ENABLE() TIMCC2_ENABLE()
#define BLDC_VH_DISABLE() TIMCC2_DISABLE()
#define BLDC_WH_ENABLE() TIMCC3_ENABLE()
#define BLDC_WH_DISABLE() TIMCC3_DISABLE()
#define BLDC_UL_ENABLE() TIMCC1N_ENABLE()
#define BLDC_UL_DISABLE() TIMCC1N_DISABLE()
#define BLDC_VL_ENABLE() TIMCC2N_ENABLE()
#define BLDC_VL_DISABLE() TIMCC2N_DISABLE()
#define BLDC_WL_ENABLE() TIMCC3N_ENABLE()
#define BLDC_WL_DISABLE() TIMCC3N_DISABLE()
/** Duty cycle control macro definition */
#define SET_VAL_U(Value) SET_CCR1_VAL(Value)
#define SET_VAL_V(Value) SET_CCR2_VAL(Value)
#define SET_VAL_W(Value) SET_CCR3_VAL(Value)
#define BLDC_TIM_DEADTIME (5)
#define TIMCC1_ENABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1EN << TIM_Channel_1, TIM_CCx_Enable << TIM_Channel_1) //CC1NE=1: enable OC1 output
#define TIMCC1_DISABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1EN << TIM_Channel_1, TIM_CCx_Disable << TIM_Channel_1) //CC1NE=0: disable OC1 output
#define TIMCC2_ENABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1EN << TIM_Channel_2, TIM_CCx_Enable << TIM_Channel_2) //CC2NE=1: enable OC2 output
#define TIMCC2_DISABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1EN << TIM_Channel_2, TIM_CCx_Disable << TIM_Channel_2) //CC2NE=0: disable OC2 outpu
#define TIMCC3_ENABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1EN << TIM_Channel_3, TIM_CCx_Enable << TIM_Channel_3) //CC3NE=1: enable OC3 output
#define TIMCC3_DISABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1EN << TIM_Channel_3, TIM_CCx_Disable << TIM_Channel_3) //CC3NE=0: disable OC3 output
#define TIMCC1N_ENABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1NP, TIM_OCNPolarity_Low) //CCN1P=1: OC1NPolarity Low
#define TIMCC1N_DISABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC1NP, TIM_OCNPolarity_High) //CCN1P=0: OC1NPolarity High
#define TIMCC2N_ENABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC2NP, TIM_OCNPolarity_Low<<4) //CCN2P=1: OC2NPolarity Low
#define TIMCC2N_DISABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC2NP, TIM_OCNPolarity_High<<4) //CCN2P=0: OC2NPolarity High
#define TIMCC3N_ENABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC3NP, TIM_OCNPolarity_Low<<8) //CCN3P=1: OC3NPolarity Low
#define TIMCC3N_DISABLE() MODIFY_REG(TIM1->CCER, TIM_CCER_CC3NP, TIM_OCNPolarity_High<<8) //CCN3P=0: OC3NPolarity High
#define SET_CCR1_VAL(Value) WRITE_REG(TIM1->CCR1, Value)
#define SET_CCR2_VAL(Value) WRITE_REG(TIM1->CCR2, Value)
#define SET_CCR3_VAL(Value) WRITE_REG(TIM1->CCR3, Value)
#define SET_CCR4_VAL(Value) WRITE_REG(TIM1->CCR4, Value)
#define SET_CCR5_VAL(Value) WRITE_REG(TIM1->CCR5, Value)
#define DISABLE_PWMOUT() CLEAR_BIT(TIM1->BDTR, TIM_BDTR_MOEN)
#define ENABLE_PWMOUT() SET_BIT(TIM1->BDTR, TIM_BDTR_MOEN)
#define READ_TIM1_UPDATE_FLAG() READ_BIT(TIM1->SR, TIM_IT_Update)
#define CLEAN_TIM1_UPDATE_FLAG() CLEAR_BIT(TIM1->SR, TIM_IT_Update)
#define TIM1_BREAK_ENABLE() SET_BIT(TIM1->BDTR,TIM_BDTR_BKE)
#define TIM1_BREAK_DISABLE() CLEAR_BIT(TIM1->BDTR,TIM_BDTR_BKE)
#define READ_TIM1_BREAK_FLAG() READ_BIT(TIM1->SR, TIM_IT_Break)
#define CLEAN_TIM1_BREAK_FLAG() CLEAR_BIT(TIM1->SR, TIM_IT_Break)
uint16_t RemoteInput=0;
uint16_t RemotePeriod=0;
uint8_t RemoteState=0;
uint16_t Duty;
uint16_t ARR=0;
uint32_t u32HallTime = 0;
uint8_t ReadHallValue;
uint8_t HallA;
uint8_t HallB;
uint8_t HallC;
extern uint32_t SystemCoreClock;
void Pwm_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
RCC_AHBPeriphClockCmd(BLDC1_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = BLDC1_UH_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(BLDC1_UH_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BLDC1_VH_PIN;
GPIO_Init(BLDC1_VH_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BLDC1_WH_PIN;
GPIO_Init(BLDC1_WH_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BLDC1_UL_PIN;
GPIO_Init(BLDC1_UL_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BLDC1_VL_PIN;
GPIO_Init(BLDC1_VL_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BLDC1_WL_PIN;
GPIO_Init(BLDC1_WL_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(BLDC1_UH_PORT, BLDC1_UH_PIN_SRC, BLDC1_UH_PIN_AF);
GPIO_PinAFConfig(BLDC1_VH_PORT, BLDC1_VH_PIN_SRC, BLDC1_VH_PIN_AF);
GPIO_PinAFConfig(BLDC1_WH_PORT, BLDC1_WH_PIN_SRC, BLDC1_WH_PIN_AF);
GPIO_PinAFConfig(BLDC1_UL_PORT, BLDC1_UL_PIN_SRC, BLDC1_UL_PIN_AF);
GPIO_PinAFConfig(BLDC1_VL_PORT, BLDC1_VL_PIN_SRC, BLDC1_VL_PIN_AF);
GPIO_PinAFConfig(BLDC1_WL_PORT, BLDC1_WL_PIN_SRC, BLDC1_WL_PIN_AF);
}
void Hall_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
RCC_AHBPeriphClockCmd(HALL_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = HALLU_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(HALLU_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = HALLV_PIN;
GPIO_Init(HALLV_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = HALLW_PIN;
GPIO_Init(HALLW_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(HALLU_PORT, HALLU_PIN_SOURCE, HALLU_PIN_AF);
GPIO_PinAFConfig(HALLV_PORT, HALLV_PIN_SOURCE, HALLV_PIN_AF);
GPIO_PinAFConfig(HALLW_PORT, HALLW_PIN_SOURCE, HALLW_PIN_AF);
}
void Input_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = THROTTLE_INPUT_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FLOATING;
GPIO_Init(THROTTLE_INPUT_GPIO, &GPIO_InitStructure);
GPIO_PinAFConfig(THROTTLE_INPUT_GPIO, THROTTLE_INPUT_PIN_SOURCE, THROTTLE_INPUT_AF);
}
void TIM1_Init() //PWM输出
{
/** Define the struct of THE PWM configuration */
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStruct;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_BDTRStructInit(&TIM_BDTRInitStruct);
TIM_OCStructInit(&TIM_OCInitStructure);
/** Enable the TIM1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2ENR_TIM1, ENABLE);
/**
* Sets the value of the automatic reload register Period for the next update event load activity
* Set the Prescaler value used as the divisor of the TIMx clock frequency
* Set clock split :TDTS = TIM_CKD_DIV1
* TIM center aligned mode1
*/
TIM_TimeBaseStructure.TIM_Period = ARR;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/**
* Enable state selection in running mode
* Enable state selection in idle mode
* Software error lock configuration: lock closed without protection
* DTG[7:0] dead zone generator configuration (dead zone time DT)
*/
/**
* TDTS = 125nS(8MHz)
* DTG[7: 5] = 0xx => DT = DTG[7: 0] * Tdtg, Tdtg = TDTS;
* DTG[7: 5] = 10x => DT =(64+DTG[5: 0]) * Tdtg, Tdtg = 2 * TDTS;
* DTG[7: 5] = 110 => DT =(32+DTG[4: 0]) * Tdtg, Tdtg = 8 * TDTS;
* DTG[7: 5] = 111=> DT =(32 + DTG[4: 0]) * Tdtg, Tdtg = 16 * TDTS;
*/
TIM_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Enable;
TIM_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStruct.TIM_DeadTime = BLDC_TIM_DEADTIME;
/**
* Brake configuration: Disable brake
* Brake input polarity: active in low level
* Auto output enable configuration: Enable MOE bit hardware control
*/
TIM_BDTRInitStruct.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStruct.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStruct);
/**
* Mode configuration: PWM mode 1
* Output status setting: enable output
* Complementary channel output status setting: enable output
* Sets the pulse value to be loaded into the capture comparison register
* Output polarity is high
* N Output polarity is high
*/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
/** Enable CH1, 2, and 3 to be preloaded */
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
/** Enable TIMx's preloaded register on ARR */
TIM_ARRPreloadConfig(TIM1, ENABLE);
/** Turn off CH1, 2, and 3 channel outputs */
TIM_CCxCmd(TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxCmd(TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxCmd(TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
/** Enable the TIM1 */
TIM_Cmd(TIM1, ENABLE);
/** Main Output Enable:Disable the MOE bit */
TIM_CtrlPWMOutputs(TIM1, DISABLE);
}
void TIM2_Init(void)//霍尔捕捉
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_ICStructInit(&TIM_ICInitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_DeInit(TIM2);
RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM2EN, ENABLE);
/**
* Sets the value of the automatic reload register Period for the next update event load activity
* Set the Prescaler value used as the divisor of the TIMx clock frequency
* Set clock split :TDTS = TIM_CKD_DIV1
* Up counting mode
*/
TIM_TimeBaseStructure.TIM_Period = 49999;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/**
* Initialize TIM2 input capture parameters
* CC1S=01 selects the input terminal IC1 to be mapped to TI1
* Set to double edge capture
* Map to TI1
* Configure input frequency division, no frequency division
* Configure input filter IC1F to 8
*/
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x08;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
/** Enable the Hall sensor interface of TIM2 */
TIM_SelectHallSensor(TIM2, ENABLE);
/** Input trigger source selection TI1 Edge Detector */
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);
/** Select from mode to reset mode */
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
TIM_UpdateRequestConfig(TIM2,TIM_UpdateSource_Regular);
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
/** Allow interrupts to be triggered */
TIM_ITConfig(TIM2, TIM_IT_Trigger, ENABLE);
TIM_ClearITPendingBit(TIM2, TIM_IT_Trigger);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM_Cmd(TIM2, ENABLE);
}
void TIM3_Init(void)//油门输入
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_ICInitTypeDef TIM3_ICInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM3, ENABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
TIM_TimeBaseStruct.TIM_Period = 0xFFFF;
TIM_TimeBaseStruct.TIM_Prescaler = 71;
//Setting Clock Segmentation
TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
///TIM Upward Counting Mode
TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
TIM_ICStructInit(&TIM3_ICInitStruct);
TIM3_ICInitStruct.TIM_Channel = TIM_Channel_2;
TIM3_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM3_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM3_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM3_ICInitStruct.TIM_ICFilter = 0x0;
//Configure PWM
TIM_PWMIConfig(TIM3, &TIM3_ICInitStruct);
//Select the valid input
TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);
//Configuration in master-slave reset mode
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
TIM_Cmd(TIM3, ENABLE);
/** Initialization ADC interrupt */
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
}
void ReadHall(void)
{
HallA=((HALLU_PORT->IDR & HALLU_PIN)) ? Bit_SET : Bit_RESET;
HallB=((HALLV_PORT->IDR & HALLV_PIN)) ? Bit_SET : Bit_RESET;
HallC=((HALLW_PORT->IDR & HALLW_PIN)) ? Bit_SET : Bit_RESET;
// TempHallValue = HallA*4 + HallC*2 + HallB*1; //0
// TempHallValue = HallA*4 + HallB*2 + HallC*1; //0
ReadHallValue = HallB*4 + HallC*2 + HallA*1; //
// TempHallValue = HallB*4 + HallA*2 + HallC*1;
// TempHallValue = HallC*4 + HallA*2 + HallB*1; //0
// TempHallValue = HallC*4 + HallB*2 + HallA*1;
//上面6组中选一组电流最小的才是正确的配置
}
void MotorDrive(uint8_t step)
{
switch(step) {
case 3: //A+ C-
BLDC_UL_DISABLE();
BLDC_UH_ENABLE();
BLDC_VL_DISABLE();
BLDC_VH_DISABLE();
BLDC_WH_DISABLE();
BLDC_WL_ENABLE();
break;
case 1: //B+ C-
BLDC_UL_DISABLE();
BLDC_UH_DISABLE();
BLDC_VL_DISABLE();
BLDC_VH_ENABLE();
BLDC_WH_DISABLE();
BLDC_WL_ENABLE();
break;
case 5: // B+ A-
BLDC_UH_DISABLE();
BLDC_UL_ENABLE();
BLDC_VL_DISABLE();
BLDC_VH_ENABLE();
BLDC_WL_DISABLE();
BLDC_WH_DISABLE();
break;
case 4: // C+ A-
BLDC_UH_DISABLE();
BLDC_UL_ENABLE();
BLDC_VL_DISABLE();
BLDC_VH_DISABLE();
BLDC_WL_DISABLE();
BLDC_WH_ENABLE();
break;
case 6: // C+ B-
BLDC_UH_DISABLE();
BLDC_UL_DISABLE();
BLDC_VH_DISABLE();
BLDC_VL_ENABLE();
BLDC_WL_DISABLE();
BLDC_WH_ENABLE();
break;
case 2: // A+ B-
BLDC_UL_DISABLE();
BLDC_UH_ENABLE();
BLDC_VH_DISABLE();
BLDC_VL_ENABLE();
BLDC_WH_DISABLE();
BLDC_WL_DISABLE();
break;
default:
BLDC_UH_DISABLE();
BLDC_UL_DISABLE();
BLDC_VH_DISABLE();
BLDC_VL_DISABLE();
BLDC_WH_DISABLE();
BLDC_WL_DISABLE();
break;
}
}
void TIM3_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM3,TIM_FLAG_CC2)==SET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
RemoteInput=TIM_GetCapture1(TIM3);
RemotePeriod=TIM_GetCapture2(TIM3);
RemoteState=0;
//油门信息判断
if(RemotePeriod > 28517|| RemotePeriod < 2000||RemoteInput<800 || RemoteInput >2300||(TIM_GetFlagStatus(TIM3,TIM_FLAG_CC2OF)==SET))
{
WRITE_REG(TIM3->SR, ~(TIM_SR_CC2OF));
RemoteState=1;
}
if(RemoteState==0)
{
if(RemoteInput<1050) //1050是启动点
{
Duty=0;
MotorDrive(7);
}
else if(RemoteInput>1950) //油门最大值
{
Duty=ARR+1;
}
else
{
Duty=(ARR+1)*(RemoteInput-1050)/(1950-1050);
}
SET_VAL_U(Duty);
SET_VAL_V(Duty);
SET_VAL_W(Duty);
if(Duty>0&& u32HallTime==0) //油门大于启动点并且此时停转
{
ReadHall();
MotorDrive(ReadHallValue); //启动一次
}
}
}
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Trigger) != RESET)
{
/** Clear interrupt flag */
TIM_ClearITPendingBit(TIM2, TIM_IT_Trigger);
u32HallTime = TIM_GetCapture1(TIM2); //换相时间
ReadHall();
MotorDrive(ReadHallValue);
return;
}
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //长时间未更新换相时间则认为停转了或者堵转了,换相时间清零
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
u32HallTime=0;
return;
}
}
/**
* @brief : This function is the main entry.
* @param : None
* @retval : None
*/
int main(void)
{
ARR=SystemCoreClock/16000 -1; //16k的PWM输出
Pwm_GPIO_Init(); //6边桥的管脚初始化
Hall_GPIO_Init();//3个霍尔管脚初始化
Input_GPIO_Init();//油门输入管脚初始化
TIM1_Init();//PWM驱动初始化
TIM2_Init();//霍尔中断捕获,读取霍尔,换相。如果超时了换相时间清零
TIM3_Init();//油门输入捕获 ,更新DUTY,判断是否第一次换相,或者油门小于启动点停转
ENABLE_PWMOUT();//使能PWM输出
while(1)
{
}
}