代码生成部分我选用了LL库,MDK V5的工程设置输出,其它正常,点击“GENERATE CODE“按钮后,生成全部驱动代码和工程。
3. 驱动代码完成工程建立后,剩下的是我们的具体驱动代码了。这里主要包括如下几个部分:
1) 霍尔信号采集
通过GPIO状态获取的方式形成霍尔状态:
HallState =(uint8_t) ((LL_GPIO_IsInputPinSet(M_HALL_H3_GPIO_Port, M_HALL_H3_Pin ) << 2)
|(LL_GPIO_IsInputPinSet( M_HALL_H2_GPIO_Port, M_HALL_H2_Pin ) << 1)
|LL_GPIO_IsInputPinSet( M_HALL_H1_GPIO_Port, M_HALL_H1_Pin ) );
2) 驱动输出
前面已经描述了开关驱动状态与霍尔状态的关系,只要根据状态完成驱动切换就可以。我这里采用了上桥臂PWM输出,下桥臂长通输出方式。
如下为实现代码:
switch ( HallState )
{
case 2:
LL_TIM_CC_DisableChannel( TIM1,TIMxCCER_MASK_CH123 );
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH1); //u+
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH2N); //v-
LL_TIM_OC_SetCompareCH1(TIM1,Duty);
LL_TIM_OC_SetCompareCH2(TIM1,((PWM_PERIOD_CYCLES) / 2));
//TIM_SetCompare3(TIM1, Duty);
break;
case 3:
LL_TIM_CC_DisableChannel( TIM1,TIMxCCER_MASK_CH123 );
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH1); //u+
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH3N); //w-
LL_TIM_OC_SetCompareCH1(TIM1,Duty);
LL_TIM_OC_SetCompareCH3(TIM1,((PWM_PERIOD_CYCLES) / 2));
break;
case 1:
LL_TIM_CC_DisableChannel( TIM1,TIMxCCER_MASK_CH123 );
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH2); //v+
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH3N); //w-
LL_TIM_OC_SetCompareCH2(TIM1,Duty);
LL_TIM_OC_SetCompareCH3(TIM1,((PWM_PERIOD_CYCLES) / 2));
break;
case 5:
LL_TIM_CC_DisableChannel( TIM1,TIMxCCER_MASK_CH123 );
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH2); //v+
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH1N); //u-
LL_TIM_OC_SetCompareCH1(TIM1,((PWM_PERIOD_CYCLES) / 2));
LL_TIM_OC_SetCompareCH2(TIM1,Duty);
break;
case 4:
LL_TIM_CC_DisableChannel( TIM1,TIMxCCER_MASK_CH123 );
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH3); //w+
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH1N); //u-
LL_TIM_OC_SetCompareCH1(TIM1,((PWM_PERIOD_CYCLES) / 2));
LL_TIM_OC_SetCompareCH3(TIM1,Duty);
break;
case 6:
LL_TIM_CC_DisableChannel( TIM1,TIMxCCER_MASK_CH123 );
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH3); //w+
LL_TIM_CC_EnableChannel(TIM1,LL_TIM_CHANNEL_CH2N); //v-
LL_TIM_OC_SetCompareCH2(TIM1,((PWM_PERIOD_CYCLES) / 2));
LL_TIM_OC_SetCompareCH3(TIM1,Duty);
break;
default:
/* Bad hall sensor configutarion soupdate the speed reliability */
break;
}
3) 转速测量
转速测量采用TIM3的XOR方式通过霍尔传感器位置变化来测量的,为了适应低速运行测试,通过借鉴STM32motor workbench中的代码,利用TIM3溢出中断和捕获中断配合一起完成转速测量,由于霍尔传感器上有干扰,所以需要在捕获中增加滤除毛刺的部分。
voidHALL_TIMx_UP_IRQHandler(void) //溢出中断
{
hall_ov_count++;
}
voidHALL_TIMx_CC_IRQHandler(void) //捕获中断
{
speed = hall_ov_count * 65536L +LL_TIM_IC_GetCaptureCH1(TIM3);
hall_ov_count = 0;
}
4) 串口控制
为了可以实现外部控制,实现了一个简单的串口输入输出控制方式:
if(LL_USART_IsActiveFlag_RXNE(USART1))
{
rx = LL_USART_ReceiveData8(USART1);
switch(rx)
{
case 'n': //正转
targetDuty = 0;
control_dir = 0;
LL_TIM_EnableAllOutputs(TIM1);
Driver_Enable = 1;
break;
case 'r'://反转
targetDuty = 0;
control_dir = 1;
LL_TIM_EnableAllOutputs(TIM1);
Driver_Enable = 1;
break;
case 's'://stop
LL_TIM_DisableAllOutputs(TIM1);
targetDuty = 0;
Driver_Enable = 0;
break;
case 'a': //转速增加
if(targetDuty <((PWM_PERIOD_CYCLES) / 6))
targetDuty += 10;
break;
case 'm': //转速降低
if(targetDuty > 10)
targetDuty -= 10;
else
targetDuty = 0;
break;
case 'd': //转速显示输出
{
sprintf(disp_str,"%un",disp_speed);
Transmit_Str(disp_str);
}
break;
default:
break;
}
}
4. 运行效果
实践证明,高集成度STSPIN32F0601在进行BLDC驱动的时候,非常简单方便,系统设计上充分的考虑了高压驱动,同时对于有感方式速度检测也做了专门的设计。