STM32控制BLDC-如何让电机转起来

2024-01-07 01:20
文章标签 stm32 控制 起来 电机 bldc

本文主要是介绍STM32控制BLDC-如何让电机转起来,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

无刷直流电机比较流行,很多电机内部加入霍尔元件,通过霍尔元件可以知道电机转子的位置,根据这个位置给电机相线供电,这样电机就转起来了。框图如下所示

霍尔元件输出与相线输入电压的关系可以让BLDC电机厂家提供,一般都提供这个对应关系表,如下图所示

有了上面这些足可以让我们设计电路编写程序让电机转起来!

 

有上面的框图可以看出,3相电机的驱动需要六个mos管,一般用的是NMOS,大功率的NMOS比较便宜。大功率MOS管有较大的结电容,控制电压也高些,无法用单片机直接驱动,所以需要驱动电路。驱动芯片组成的驱动电路比较简单,常见的有IR2110S,我这里用IR2110S设计了MOS驱动电路,如下图所示,其中C24和D5是自举电路,为了控制Q3抬高电压。

3片IR2110S驱动6个NMOS,如下图

霍尔元件供电是5V,他的输出一般也是5V,可以分压后给单片机用。

单片机用流行STM32,他有高级定时器T1,T8,可以输出3对互补的PWM波,还有刹车信号输入,这些特性对于电机的可控制非常合适。电路如下图所示

BLDC电机控制用到单片机定时器及IO中断,初始化部分如下

void TIM_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef	TIM_TimeBaseInitStruct;TIM_OCInitTypeDef  TIM_OCInitStructure;TIM_BDTRInitTypeDef TIM_BDTRInitStructure;EXTI_InitTypeDef EXTI_InitStructure;//NVIC_InitTypeDef NVIC_InitStructure;TIM_ICInitTypeDef TIM_ICInitStructure;// ¿ªÆô¶¨Ê±Æ÷ʱÖÓ,¼´ÄÚ²¿Ê±ÖÓCK_INT=72MRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_TIM1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);// Êä³ö±È½ÏͨµÀ1 GPIO ³õʼ»¯GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//»ô¶ûÊäÈëGPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);EXTI_InitStructure.EXTI_Line=EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource6);EXTI_InitStructure.EXTI_Line= EXTI_Line6; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource7);EXTI_InitStructure.EXTI_Line= EXTI_Line7; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_DeInit(TIM1);        //½«ÍâÉèTIM1¼Ä´æÆ÷ÖØÉèΪȱʡֵ  TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1 ;    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up ;  TIM_TimeBaseInitStruct.TIM_Period = 1000 ;       TIM_TimeBaseInitStruct.TIM_Prescaler = 3 ;     TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct ) ;       /* ¶¨Ê±Æ÷Êä³öͨµÀ1ģʽÅäÖà */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 = 1000;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);/* Automatic Output enable, Break, dead time and lock configuration*/TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;TIM_BDTRInitStructure.TIM_DeadTime = 1;TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);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);TIM_CtrlPWMOutputs(TIM1, ENABLE); TIM_CCxCmd(TIM1,TIM_Channel_1,TIM_CCx_Enable);TIM_CCxNCmd(TIM1,TIM_Channel_1,TIM_CCxN_Enable);TIM_CCxCmd(TIM1,TIM_Channel_2,TIM_CCx_Enable);TIM_CCxNCmd(TIM1,TIM_Channel_2,TIM_CCxN_Enable);TIM_CCxCmd(TIM1,TIM_Channel_3,TIM_CCx_Enable);TIM_CCxNCmd(TIM1,TIM_Channel_3,TIM_CCxN_Enable);
}

让电机转起来需要知道电机转子的位置,根据霍尔相位对应表驱动电机相线,程序里用中断获取霍尔电平的变化。

void EXTI0_IRQHandler(void) 
{ int i,j;if(EXTI_GetITStatus(EXTI_Line0)!=RESET){EXTI_ClearITPendingBit(EXTI_Line0);step=((GPIOA->IDR & GPIO_Pin_6)>>6)+((GPIOA->IDR & GPIO_Pin_7)>>6)+((GPIOB->IDR & GPIO_Pin_0)<<2);if(start==1){TIM1->CCER=PHASE_CHANGE[step];int_count1++;}}
}void EXTI9_5_IRQHandler(void) 
{ int i,j;if(EXTI_GetITStatus(EXTI_Line6)!=RESET){EXTI_ClearITPendingBit(EXTI_Line6);step=((GPIOA->IDR & GPIO_Pin_6)>>6)+((GPIOA->IDR & GPIO_Pin_7)>>6)+((GPIOB->IDR & GPIO_Pin_0)<<2);if(start==1){TIM1->CCER=PHASE_CHANGE[step];int_count2++;}}if(EXTI_GetITStatus(EXTI_Line7)!=RESET){EXTI_ClearITPendingBit(EXTI_Line7);step=((GPIOA->IDR & GPIO_Pin_6)>>6)+((GPIOA->IDR & GPIO_Pin_7)>>6)+((GPIOB->IDR & GPIO_Pin_0)<<2);if(start==1){TIM1->CCER=PHASE_CHANGE[step];int_count3++;}}
}

 

检测到变化后改变定时器输出,从而使电机相线得到驱动,我在程序里做好了数组,把得到了位置通过数组给定时器CCER寄存器,这样电机就转起来了

int PHASE_CHANGE[7]={0x0000,0x0104,0x0041,0x0140,0x0410,0x0014,0x0401};

这是霍尔输出与PWM输出波形的截图

这是定时器3对PWM的输出截图

这是电机和电路板

这篇关于STM32控制BLDC-如何让电机转起来的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/578275

相关文章

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

Springboot控制反转与Bean对象的方法

《Springboot控制反转与Bean对象的方法》文章介绍了SpringBoot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括... 目录1 控制反转1.1 什么是控制反转1.2 SpringBoot中的控制反转2 Ioc容器对Bea

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC

Python实现局域网远程控制电脑

《Python实现局域网远程控制电脑》这篇文章主要为大家详细介绍了如何利用Python编写一个工具,可以实现远程控制局域网电脑关机,重启,注销等功能,感兴趣的小伙伴可以参考一下... 目录1.简介2. 运行效果3. 1.0版本相关源码服务端server.py客户端client.py4. 2.0版本相关源码1