完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.检测霍尔传感器的值可以判断出转子的位置,再使能相应的上下桥臂,则能驱动电机运动;若要让电机持续转动,则必须再次检测传感器值及使能相应的上下桥臂。这里采用的是将霍尔传感器输出的三根线相边的IO口配置成外部中断,并且为边沿触发,在中断函数中加入传感器检测与上下桥臂切换程序,如此电机就能持续运转了。
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.调速:给定速度,由电机驱动板自动由当前速度平滑过渡到给定速度。实际测试发现,速度变化量很大时,电机会有突然加速或减速时的冲击;因此,调速应有一个缓冲的过程。即加速或减速应以小步进缓慢增加或减少占空比来让速度渐渐达到最终值。 #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); //使能TIMx在ARR上的预装载寄存器 TIM_Cmd(TIM1 , ENABLE); 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;i { Led_On; DelayMs(100*n); Led_Off; DelayMs(100*n); } } /***************************************************************************************** 函数:void SetPWMduty(u8 PWMChanel,u16 pulse) 描述:设置pwm波占空比 参数: 返回: *****************************************************************************************/ void SetPWMduty(u8 PWMChanel,u16 pulse) { switch(PWMChanel) { case 1 : TIM1->CCR1=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_Pin_11) + (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12) << 1) + (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) << 2); hallValue = hallValueTemp; PWM_T_Calculation(hallValue , mRate , direction); } 函数:PWM_Stop 描述:PWM控制信号使能输出,禁止TIM1中断,使能TIM1中断 参数:pwmflag=DISABLE,PWM信号使能输出,pwmflag=ENABLE,禁止 PWM输出 返回:无 void PWM_Stop(u8 pwmflag) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; if(pwmflag == ENABLE)//禁止 PWM输出 { TIM_Cmd(TIM1 , DISABLE); //TIM_Cmd(TIM2 , DISABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM16_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&NVIC_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10); //PWM口 //PWM_T_Output(4 , 4 , 0); } if(pwmflag == DISABLE)//使能PWM输出 { NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM16_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_Init(GPIOA, &GPIO_InitStructure); // TIM_Cmd(TIM2 , ENABLE); } } 函数:void Motor_Start(void) 描述:启动电机 参数: 返回: *****************************************************************************************/ void Motor_Start(void) { PWM_T_Int(Motor.Dir,Motor.Speed); } 函数:void Motor_Stop(void) 描述:停止 参数: 返回:void Motor_Stop(void) { //U_Up_On;V_Up_On;W_Up_On; //U_Dn_On;V_Dn_On;W_Dn_On; PWM_T_Output(4,4,0); } /***************************************************** 函数:void EXTI15_10_IRQHandler(u8 dir,u8 hall) 描述:霍尔传感器中断 参数: 返回:******************************************************************/ void EXTI15_10_IRQHandler(void) { Hall_Conter++; if ((EXTI_GetITStatus(EXTI_Line11) != RESET)||(EXTI_GetITStatus(EXTI_Line12) != RESET)||(EXTI_GetITStatus(EXTI_Line15) != RESET)) { if(Motor.State!=STOP) PWM_T_Int(Motor.Dir,Motor.Speed); } EXTI_ClearITPendingBit(EXTI_Line11); //清除标志 EXTI_ClearITPendingBit(EXTI_Line12); //清除标志 EXTI_ClearITPendingBit(EXTI_Line15); //清除标志 }函数:void Test_Motor(u8 dir,u8 hall) 描述:电机控制 参数: 返回:void Test_Motor(void) { while(1) { switch(Motor.State) { case STOP : Motor_Stop(); break; case RUN : Motor_Start(); Motor.State=FREE; break; default : break; } } } |
|
相关推荐
11个回答
|
|
好东西要顶起!!!
|
|
|
|
牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛牛
|
|
|
|
好东西,占一个
|
|
|
|
学习了。。。。。
|
|
|
|
不错的东西,谢谢楼主分享
|
|
|
|
十分感谢分享,谢谢啦
|
|
|
|
一篇不错的文章,谢谢分享
|
|
|
|
Mark一下~....................
|
|
|
|
思路挺清晰。不错!
|
|
|
|
思路挺清晰。不错!
|
|
|
|
多谢分享!
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2136 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1970 浏览 3 评论
4566 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2116 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2629 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 02:25 , Processed in 0.687112 second(s), Total 63, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号