定时器:霍尔传感器接口与六步算法
实现结果本文的目的是 实现下图所示。(文档这个图是错的,霍尔信号和CCR2的位置不对,先将就着)
声明由于实验室缺少电机,所以咱用另一块板子timer3模拟霍尔信号TIH1、TIH2、TIH3出来。
* 模拟霍尔信号
代码如下:
/*******************************************************************************
* @name : initTIM3
* @brief : init TIM3
* @param : u16 arr, u16 arr
* @retval : void
*******************************************************************************/
void initTIM3(u16 psc, u16 arr)
{
TIM_TimeBaseInitTypeDef TIM_StructInit;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_DeInit(TIM3);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // TIM3 CH1/2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // TIM3 CH3
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_StructInit.TIM_Prescaler = psc; // set Prescaler: psc + 1
TIM_StructInit.TIM_Period = arr; // set Period: arr + 1
TIM_StructInit.TIM_ClockDivision = TIM_CKD_DIV1; // set ClockDivision :0
TIM_StructInit.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_StructInit);
TIM_CCPreloadControl(TIM3, ENABLE); // Enable ARR preload
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // Enable update interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE);
}
配置好定时器3后,模拟信号: /*******************************************************************************
* @name : simMotorPrepareCommutation
* @brief :simulate hall Input
* @param : void
* @retval : void
*******************************************************************************/
void simMotorPrepareCommutation(void)
{
if (gSimStep == 1){
// Step 1 Configuration
CH1ON;
CH2OFF;
CH3OFF;
gSimStep++;
}
else if (gSimStep == 2){
// Step 2 Configuration
CH1ON;
CH2ON;
CH3OFF;
gSimStep++;
}
else if (gSimStep == 3){
// Step 3 Configuration
CH1ON;
CH2ON;
CH3ON;
gSimStep++;
}
else if (gSimStep == 4){
// Step 4 Configuration
CH1OFF;
CH2ON;
CH3ON;
gSimStep++;
}
else if (gSimStep == 5){
// Step 5 Configuration
CH1OFF;
CH2OFF;
CH3ON;
gSimStep++;
}
else{
// Step 6 Configuration
CH1OFF;
CH2OFF;
CH3OFF;
gSimStep = 1;
}
}
通过中断调度 /*******************************************************************************
* @name : TIM3_IRQHandler
* @brief :
* @param : void
* @retval : void
*******************************************************************************/
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
simMotorPrepareCommutation();
}
}
/*
--------------------------------------------------------------------------------
TIM2 (hall timer) | TIM3 (Simulate the hall output)
--------------------------------------------------------------------------------
PA_0: hall input channel1 | PA_6 (TIM3_CH1)
--------------------------------------------------------------------------------
PA_1: hall input channel2 | PA_7 (TIM3_CH2)
--------------------------------------------------------------------------------
PA_2: hall input channel3 | PB_0 (TIM3_CH3)
--------------------------------------------------------------------------------
NOTE: if use TIM3 simulate, In order to achieve better results, please use anot-
her board to output and the main function just only init TIM3 and its parameter.
*/
int main(void)
{
//....
initTIM3(0x0, 0xFFFF);
//.....
}
MB024引脚图
好吧,接上逻辑分析仪看看:
结果:
没问题就可以进入正文。
正文
配置霍尔输入定时器配置:
void initHallTimer2()
{
TIM_TimeBaseInitTypeDef pBase;
TIM_OCInitTypeDef pOC;
TIM_ICInitTypeDef pIC;
COMMON_EnableIpClock(emCLOCK_TIM2);
COMMON_NVIC_Configure(TIM2_IRQn, 1, 1);
GPIO_TIMER2_HALL_INPUT_Configure();
TIM_DeInit(TIM2);
TIM_TimeBaseStructInit(&pBase);
pBase.TIM_Period = 0xFFFF;
pBase.TIM_Prescaler = 0;
pBase.TIM_CounterMode = TIM_CounterMode_Up;
pBase.TIM_ClockDivision = TIM_CKD_DIV1;
pBase.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &pBase);
TIM_OCStructInit(&pOC);
pOC.TIM_Pulse = 0x1;
pOC.TIM_OCMode = TIM_OCMode_PWM2;
pOC.TIM_OutputState = TIM_OutputState_Enable;
pOC.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM2, &pOC);
TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); // Add OC2 handle to reduce delay
TIM_SelectHallSensor(TIM2, ENABLE);
pIC.TIM_Channel = TIM_Channel_1;
pIC.TIM_ICPolarity= TIM_ICPolarity_Rising;
pIC.TIM_ICSelection = TIM_ICSelection_TRC;
pIC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
pIC.TIM_ICFilter = 0x0;
TIM_ICInit(TIM2, &pIC);
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
TIM_SelectOutputTrigger(TIM2, TIM_TRIGSource_OC2Ref);
TIM_Cmd(TIM2, ENABLE);
}
调度:
/* /
|---------|--------------------------------------------------------------------|
| PA_0 | _|- - -|_ _ _|- - -| _ _ _ |
| | |
| PA_1 | _ _|- - -|_ _ _|- - -| _ _ |
| | |
| PA_2 | _ _ _|- - -|_ _ _|- - -| _ |
|---------+--------------------------------------------------------------------|
|pos value||0 1 3 7 6 4|0 1 3 7 6 4|.. |
|------------------------------------------------------------------------------|
*///
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
/* Calculate motor speed or else with CCR1 values */
HallCCR1 = TIM_GetCapture1(TIM2);
/* get step position by PA_0 / PA_1 / PA_2 */
HallPos = (GPIO_ReadInputData(GPIOA)) & 0x0007;
/* Step Motor commutation*/
BLDCMotorPrepareCommutation(HallPos, TIM_OCMode_PWM1, TIM_OCMode_PWM1);
}
}
/// @briefMain function, program entry.
/// @paramNone.
/// @retval None.
int main(void)
{
MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
initHallTimer2();
initMotorTimer1(0, 999);
while(1){
}
}
/// @briefMain function, program entry.
/// @paramNone.
/// @retval None.
int main(void)
{
MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
initHallTimer2();
initMotorTimer1(0, 999);
while(1){
}
}
/// @briefMain function, program entry.
/// @paramNone.
/// @retval None.
int main(void)
{
MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
initHallTimer2();
initMotorTimer1(0, 999);
while(1){
}
}
出来这个玩意?这肯定是前面步进值没算好。继续修改
void BLDCMotorPrepareCommutation(u8 pos, TIMOCMODE_Typedef TIM_CHxMode, TIMOCMODE_Typedef TIM_CHxNMode)
{
if (pos == 0){
/* Channel1 configuration: CH1 output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxMode);
TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Enable);
TIM_CCxNCmd (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/* Channel2 configuration: CH2N output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxNMode);
TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd (TIM1, TIM_Channel_2, TIM_CCxN_Enable);
/* Channel3 configuration: CH3 None */
TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd (TIM1, TIM_Channel_3, TIM_CCxN_Disable);
}
else if (pos == 1){
/*Channel1 configuration: CH1 output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxMode);
TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Enable);
TIM_CCxNCmd (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/*Channel2 configuration: CH2 None */
TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd (TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/*Channel3 configuration: CH3N output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxNMode);
TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd (TIM1, TIM_Channel_3, TIM_CCxN_Enable);
}
else if (pos == 3){
/* Channel1 configuration: CH1 None */
TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/* Channel2 configuration: CH2 output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxMode);
TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Enable);
TIM_CCxNCmd (TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/* Channel3 configuration: CH3N output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxNMode);
TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);
}
else if (pos == 7){
/* Channel1 configuration: CH1N output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxNMode);
TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
/* Channel2 configuration: CH2 output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxMode);
TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/* Channel3 configuration: CH3 None */
TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
}
else if (pos == 6){
/* Channel1 configuration: CH1N output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxNMode);
TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
/* Channel2 configuration: CH2 None */
TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
/* Channel3 configuration: CH3 output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxMode);
TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
}
else if (pos == 4){
/* Channel1 configuration: CH1 None */
TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
/* Channel2 configuration: CH2N output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxNMode);
TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);
/* Channel3 configuration: CH3 output: PWM */
TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxMode);
TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Enable);
TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
}
}
页:
[1]
2