再使能相应的上下桥臂, 则能驱动电机运动;
这里采用的是将霍
1.检测霍尔传感器的值可以判断出转子的位置,
若要让电机持续转动, 则必须再次检测传感器值及使能相应的上下桥臂。
尔传感器输出的三根线相边的
传感器检测与上下桥臂切换程序,如此电机就能持续运转了。
2.上桥臂的控制采用 IO 口置高低电平来控制上桥臂的通断,下桥臂则使用单片机内部集成
的三路 PWM 波来控制, 通过控制 PWM 波的占空比, 可以实现对电机的调速了。 实际测得,
PWM 波频率为 20KHz 时,占空比增加 1% ,速度增
占空比与电机的速度成正比例关系,在
加 60rpm ,并在占空比为 53% 时达到额定转速 3000rpm (空载)。
3.速度测量则采用如下公式:
电机每转一圈, 霍尔值改变 6 次 x5 个周期 =30 次, 记录边沿触发的中断次数 N/30= 电机转
过的圈数 ,设运转时间为 t(s) 则电机转速 v=N/30/t*60 rpm 。即动转时间为 2s 时,霍尔值改
变次数即为速度值,单位 rpm 。
4.调速:给定速度,由电机驱动板自动由当前速度平滑过渡到给定速度。实际测试发现,速
度变化量很大时,电机会有突然加速或减速时的冲击;因此,
加速或减速应以小步进缓慢增加或减少占空比来让速度渐渐达到最终值。
IO 口配置成外部中断,并且为边沿触发,在中断函数中加入
调速应有一个缓冲的过程。即
#include "stm32f10x.h"
#include "driver_motor.h"
#define PWM_PERIOD_T 400
#define U_Up_On GPIOB->BSRR = GPIO_Pin_13
#define U_Up_Off GPIOB->BRR = GPIO_Pin_13
#define U_Dn_On GPIOA->BSRR = GPIO_Pin_8
#define U_Dn_Off GPIOA->BRR = GPIO_Pin_8
#define V_Up_On GPIOB->BSRR = GPIO_Pin_14
#define V_Up_Off GPIOB->BRR = GPIO_Pin_14
#define V_Dn_On GPIOA->BSRR = GPIO_Pin_9
#define V_Dn_Off GPIOA->BRR = GPIO_Pin_9
#define W_Up_On GPIOB->BSRR = GPIO_Pin_15
#define W_Up_Off GPIOB->BRR = GPIO_Pin_15
#define W_Dn_On GPIOA->BSRR = GPIO_Pin_10
#define W_Dn_Off GPIOA->BRR = GPIO_Pin_10
#define SU_HOR GPIOA->IDR & GPIO_Pin_15
#define SV_HOR GPIOA->IDR & GPIO_Pin_12
#define SW_HOR GPIOA->IDR & GPIO_Pin_11
//u8 Motor_Dir=0;
//u8 Motor_EN=0;
//u8 Hor_Value=7;
//u16 TIM2_Conter=0;
u16 Hall_Conter=0;
MotorStruct Motor={CLOCK,40,STOP};
/******************************************************************************
*
* 函数: void IO_Init(void)
* 描述: IO
* 参数:
* 返回:
* 其它:
*******************************************************************************
/
void IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStructure;
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
/* 使能 SWD 禁
用 JTAG*/
/**********************LED Light***********/
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
霍尔传感器中断 **********/
/***********************
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_15;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);//Harl
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource11);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource12);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource15);
EXTI_InitStructure.EXTI_Line = EXTI_Line11 | EXTI_Line12|EXTI_Line15;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/***************************************************************************
函数: void PWM_Init(void)
描述:配置 PWM 定时器 TIM1
参数:
返回:无
***************************************************************************/
void PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStructure;
//TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
TIM_Cmd(TIM1 , DISABLE);
TIM_CtrlPWMOutputs(TIM1, DISABLE);// 禁止 OC 输出
//IO 口设置
GPIO_SetBits(GPIOA, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10); //PWM 口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);//普通 IO 口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 定时器设置
TIM_TimeBaseInitStruct.TIM_Period = PWM_PERIOD_T;//5 极电机, 3000RPM,每个 Step
有 10 个脉冲,载波 15KHZ
TIM_TimeBaseInitStruct.TIM_Prescaler = 2;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1 , &TIM_TimeBaseInitStruct);
//TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
//TIM_ARRPreloadConfig(TIM1, ENABLE);
//TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
// 配置 PWM 输出
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
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);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
预装载寄存器 TIM_Cmd(TIM1 , ENABLE);
// 使能 TIMx 在 ARR上的
TIM_Cmd(TIM1 , ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
/******************************************************************************
***********
函数: void Motor_Init(void)
描述:
参数:
返回:
*******************************************************************************
**********/
void Motor_Init(void)
{
IO_Init();
PWM_Init();
}
/******************************************************************************
***********
函数: void Flash_Led(u8 n)
描述:
参数:
返回:
*******************************************************************************
**********/
void Flash_Led(u8 n)
{
u8 i=0;
for(i=0;iCCR1=pulse;
break;
case 2 :
TIM1->CCR2=pulse;
break;
case 3 :
TIM1->CCR3=pulse;
break;
default :
break;
}
}
/******************************************************************************
*
函数: PWM_T_Output
描述:设置相应的 PWM 梯形波输出
参数: pName 上桥臂名称, nName 下桥臂名称
返回:无
*******************************************************************************
*/
void PWM_T_Output(u8 pName , u8 nName , u8 mRate)
{
switch(pName)
{
case 1:
GPIO_SetBits(GPIOB, GPIO_Pin_15 | GPIO_Pin_14 );
GPIO_ResetBits(GPIOB , GPIO_Pin_13);
break;
case 2:
GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_15 );
GPIO_ResetBits(GPIOB , GPIO_Pin_14);
break;
case 3:
GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 );
GPIO_ResetBits(GPIOB , GPIO_Pin_15);
break;
default:
GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
}
switch(nName)
{
case 1:
TIM_SetCompare2(TIM1,0);
TIM_SetCompare3(TIM1,0);
TIM_SetCompare1(TIM1,(u16)(PWM_PERIOD_T * mRate / 100));
break;
case 2:
TIM_SetCompare3(TIM1,0);
TIM_SetCompare1(TIM1,0);
TIM_SetCompare2(TIM1,(u16)(PWM_PERIOD_T * mRate / 100));
break;
case 3:
TIM_SetCompare2(TIM1,0);
TIM_SetCompare1(TIM1,0);
TIM_SetCompare3(TIM1,(u16)(PWM_PERIOD_T * mRate / 100));
break;
default:
TIM_SetCompare1(TIM1,0);
TIM_SetCompare2(TIM1,0);
TIM_SetCompare3(TIM1,0);
}
TIM_SetAutoreload(TIM1, PWM_PERIOD_T);
}
/******************************************************************************
***********
函数: PWM_T_Calculation
描述:梯形波计算
参数: HallValue 霍尔值, mRate 调制百分比, direction 方向
返回:无
*******************************************************************************
**********/
void PWM_T_Calculation(u8 hallValue , u8 mRate , u8 direction)
{
if(direction == 1)
{
switch(hallValue)
{
case 5:
PWM_T_Output(1 , 3 , mRate);
break;
case 1:
PWM_T_Output(1 , 2 , mRate);
break;
case 3:
PWM_T_Output(3 , 2 , mRate);
break;
case 2:
PWM_T_Output(3 , 1 , mRate);
break;
case 6:
PWM_T_Output(2 , 1 , mRate);
break;
case 4:
PWM_T_Output(2 , 3 , mRate);
break;
default:
PWM_T_Output(4 , 4 , 0);
break;
}
}
else
{
switch(hallValue)
{
case 5:
PWM_T_Output(3 , 1 , mRate);
break;
case 1:
PWM_T_Output(2 , 1 , mRate);
break;
case 3:
PWM_T_Output(2 , 3 , mRate);
break;
case 2:
PWM_T_Output(1 , 3 , mRate);
break;
case 6:
PWM_T_Output(1 , 2 , mRate);
break;
case 4:
PWM_T_Output(3 , 2 , mRate);
break;
default:
PWM_T_Output(4 , 4 , 0);
break;
}
}
}
/******************************************************************************
*
函数: PWM_T_Int
描述:定时器中断程序,根据霍尔位置设置输出梯形波
参数: direction= 顺时针 / 逆时针 ,mRate 调制率
返回:无
*******************************************************************************
*/
void PWM_T_Int(u8 direction , u8 mRate)
{
u8 hallValueTemp;
u8 hallValue;
hallValueTemp
=
GPIO_ReadInputDataBit(GPIOA,
(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) << 1) +
GPIO_Pin_15) << 2);
hallValue = hallValueTemp;
PWM_T_Calculation(hallValue , mRate , direction);
GPIO_Pin_11)
+
(GPIO_ReadInputDataBit(GPIOA,