详细方案四:pwm与720电机控制

电机硬件分析

什么是电机?

电机(俗称"马达")是指依据电磁感应定律实现电能转换或传递的一种电磁装置。它的主要作用是产生驱动转矩,作为用电器或各种机械的动力源。其中本四轴采用的电机是直流电机。直流电动机是将直流电能转换为机械能的电动机。因其良好的调速性能而在电力拖动中得到广泛应用。

图1 直流电机图

那么是不是直接在电机两端加上电压就可以了?

直接在直流电机加上电压,确实能够使得电机转动而且转速完全能够满足四轴飞行的动力,但是这样的四轴没法控制电机的转速,加电后四轴只会朝天上飞而且没法控制。最后有可能炸机。

那怎么控制电机的转速?

直流电动机是将直流电能转换为机械能的电动机,也就是说只要控制住电流的话,就可以控制电机的转速了。那问题就变成了如何控制电流了。

电流怎样控制电机的转速?

我们想想,有电流电机就转,没电流电机就不转。那如果、10ms内,如果6ms电机有电流,4ms没电流。电机是前6ms转,后4ms不转?实际上是10ms电机都在转。前6ms电机有电流电机转,后4ms虽然没有电流但是由于惯性的作用电机依旧在转,只不过转速在不断的减少。如果将将10ms的周期不断的循环,不断认为地控制电流的导通的时间是不是就可以控制电机的转速了。其中这周期不能太大一般为ms或者ns级别的。

图2 电流控制电机

那么问题又来到了怎么控制电流上了

根据欧姆定律,在电阻不变的情况下,电压与电流成正比。高电平就是有电流流经电机,低电平就是电路断开没有电流流经电机。这个让电流能否流进电机就好像一个门阀且该门阀的开关的速度要达到ms和ns级别,那这门阀无疑MOS管是最佳人选。外加电压在MOS管在栅源极上如果大于MOS的开启电压MOS管内部就会导通,如果外加栅源极小于MOS的开启电压MOS管处于截止区,也就是该电路断开

最后的难题是电压

有什么电压能够在周期内输入稳定的高低电平到MOS管的栅源极?那就属PWM波最好了。

图3 pwm波定义图

PWM波即是通过单片机在一个周期内,让单片机的IO口输出一段时间的高电平,一段时间的低电平。如上图所示为为一个方波的周期,其占空比为t/T。其调节高低电平过程如下图


图4 pwm波调制图

本四轴电机采用的是720空心杯电机。电机的驱动原理是通过STM32芯片IO口输出PWM波(调节高电平的占空比)然后经过NMOS管来驱动电机的转速其电路图如下:

图5 电机原理图

电路分析:

单片机IO口输出PWM波给电路,后经过R8和R10分压(防止电压直接加载到NMOS导致击穿同时也保证了栅源电压大于开启电压)

如果此时的PWM波电压处于高电平那么NMOS管导通,此时电池提供的电压和电流经过电机接地。如果此时PWM波电压处于低电平NMOS管就会截止,电路断开没法接地电机转动的速度逐渐减少,只有等到下一个高电平来临的时候电机的转速才会提升。

电路中的电容的作用是去耦的作用,由于电机在转动的时候会产生磁场导致电机的电压上下波动,该电压有滤波的左右

此外在电机一旁并联二极管是因为电机在减速产生了电磁感应会有微弱的电流,防止它内流。二极管有分流消耗的作用。

软件分析

本四轴采用的是STM32F411单片机芯片。本次采用的是PWM1模式使用的时钟是TIM3

单片机该如何产生PWM波?

图6 单片机产生pwm波定义图

  • 如上图所示,假设单片机某IO口是锯齿波。其中ARR是单片机计数器的上限。单片机首  先开启TIM3定时器从0计数到ARR后又从0重新开始计数到ARR不断的循环重复。
  • 在0到ARR的计数期间单片机内部存在一个CCRX的输入捕获比较器,里面装载着参考电压。用来比较锯齿波的电压是否大于参考电压。如果大于那么IO口输出高电平,低于参考电压则输出低电平。
  • 其中占空比就是高电平时间占据整个定时周期的时间,也就是
  • 所以要调节占空比直接调节CCRX的值就可以了。

单片机产生PWM波的工作过程

图7 单片机内部产生pwm结构图

  • 如上图所示,就是单片机产生pwm波的模式一,其中OCIM是控制pwm模式几的。
  • OCIM被配置为模式一计数模式是向上计数的时候,一旦TIMx CNT < CCR1时通道1为有效电平否则是无效电平。如果是向下计数模式的时候则是相反。
  • 输出的OC1ref有效电平到达CCIP寄存器前,则通过设计是否为1/0如果为1则说明有OC1ref输出是高电平有效,反之为低电平。
  • 最有CO1E是IO口中断输出使能,为1时信号能够输出,为0则禁止输出

图8 pwm波计数图

上述的PWM波产生过程图的输入的CNT与CCR1的比较究竟是怎么回事?

  • CCR1其实是CCRx寄存器中的一个值,如上图所示如果CCRx等于4且为向上计数时。0-3的为有效电平,若OCREF为1则为高电平有效,剩下的低电平有效,CCxIF则相反。
  • 此外单片机的IO口输出为PWM输出功能,并非普通IO口所以在配置的时候要设置为复用的IO口输出,期间还有到了TIM1定时器,所以还要将TIM3的定时器功能映射到IO口上。

编程前的准备

编程需要的步骤

①四个电机定义

②电机最大最小速度定义

③使能定时器和IO口时钟

④初始化IO口为复用功能输出和GPIO复用映射到TIM3

⑤初始化定时器和输出比较参数

⑥使能定时器

编程代码

#include "stm32f4xx.h"#include "motor.h"

#define Moto_PwmMax 1000int16_t MOTO1_PWM = 0;int16_t MOTO2_PWM = 0;int16_t MOTO3_PWM = 0;int16_t MOTO4_PWM = 0;

/*******************************************************************************************函  数:void TIM3_GpioConfig(void)*功  能:TIM3 PWM输出通道GPIO设置*参  数:无*返回值:无*备  注:TIM3 CH1(PWM1) -> PA6*        TIM3 CH2(PWM2) -> PA7*        TIM3 CH3(PWM3) -> PB0*        TIM3 CH4(PWM4) -> PB1*******************************************************************************************/void TIM3_GpioConfig(void){  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //TIM3 时钟使能

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB, ENABLE); //GPIOA GPIOB 时钟使能 

  //GPIOB 配置: TIM3 CH1 (PA6), TIM3 CH2 (PA7), TIM3 CH3 (PB0) and TIM3 CH4 (PB2)   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用模式  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100M  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推完输出  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉输入  //PA6 PA7 初始化   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;  GPIO_Init(GPIOA, &GPIO_InitStructure);   //PB0 PB1 初始化  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ;  GPIO_Init(GPIOB, &GPIO_InitStructure); 

  //连接 TIM3 的通道到 AF2   GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3);   GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3);  GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3); }

/*******************************************************************************************函  数:void MOTOR_Init(void)*功  能:输出PWM初始化*参  数:无*返回值:无*备  注:TIMx_ARR  决定方波的周期*        TIMx_CCRx 决定方波的占空比*******************************************************************************************/void MOTOR_Init(void){  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  TIM_OCInitTypeDef TIM_OCInitStructure;  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  TIM3_GpioConfig();  //更新中断时间 Tout = (ARR-1)*(PSC-1)/CK_INT  //TIM2~TIM5时钟来源于APB1*2  TIM_TimeBaseStructure.TIM_Period = 1000-1; //自动重装载值  TIM_TimeBaseStructure.TIM_Prescaler = 100-1; //预分频值  TIM_TimeBaseStructure.TIM_ClockDivision = 0;  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  //PWM1 模式配置 通道1  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  TIM_OCInitStructure.TIM_Pulse = 0;  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM3, &TIM_OCInitStructure);  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //电机1  TIM_OC2Init(TIM3, &TIM_OCInitStructure);  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //电机2  TIM_OC3Init(TIM3, &TIM_OCInitStructure);  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //电机3  TIM_OC4Init(TIM3, &TIM_OCInitStructure);  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); //电机4  //ARR 寄存器预装载  TIM_ARRPreloadConfig(TIM3, ENABLE);

  //TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);

  TIM_Cmd(TIM3,ENABLE); //使能TIM3}

/******************************************************************************函  数:void Moto_Pwm(int16_t MOTO1_PWM,int16_t MOTO2_PWM,int16_t MOTO3_PWM,int16_t MOTO4_PWM)*功  能:电机要输出数值转换成PWM波形输出*参  数:MOTO1_PWM 电机1*        MOTO2_PWM 电机2*        MOTO3_PWM 电机3*        MOTO3_PWM 电机4*返回值:无 *备  注:无*****************************************************************************/void Moto_Pwm(int16_t MOTO1_PWM,int16_t MOTO2_PWM,int16_t MOTO3_PWM,int16_t MOTO4_PWM){   if(MOTO1_PWM>Moto_PwmMax) MOTO1_PWM = Moto_PwmMax; if(MOTO2_PWM>Moto_PwmMax) MOTO2_PWM = Moto_PwmMax; if(MOTO3_PWM>Moto_PwmMax) MOTO3_PWM = Moto_PwmMax; if(MOTO4_PWM>Moto_PwmMax) MOTO4_PWM = Moto_PwmMax; if(MOTO1_PWM<0) MOTO1_PWM = 0; if(MOTO2_PWM<0) MOTO2_PWM = 0; if(MOTO3_PWM<0) MOTO3_PWM = 0; if(MOTO4_PWM<0) MOTO4_PWM = 0;

 TIM3->CCR1 = MOTO1_PWM; TIM3->CCR2 = MOTO2_PWM; TIM3->CCR3 = MOTO3_PWM; TIM3->CCR4 = MOTO4_PWM;}



pwm波如何控制电机代码_PWM波控制720电机相关推荐

  1. css控制的代码,通过CSS控制把网页上的代码美化

    博客发布文章时,如果文章里有代码块的,通过pre或者code可以让代码块更好美观:有效提升阅读感受.它就像是IDE工具里的主题一样,看着眼睛舒服: 这个问题困扰了我很久,由于时间的问题,一直没解决.今 ...

  2. pwm波如何控制电机代码_电动车电机如何选择功率匹配的电机控制器?

    一般和整车厂进行技术沟通时他们会给控制器的线束图纸及功能要求图纸.功能要求中罗列了控制器的相关功能及线束总成,技术要求一般如低电平/高电平防盗.巡航.过欠压.平均电流等. 电机控制器客户输入技术要求图 ...

  3. 开关磁阻电机控制仿真 开关磁阻电机传统控制:电流斩波控制、电压PWM控制、角度位置控制。 智能控制:12/8三相开关磁阻电机有限元分析本体建模

    开关磁阻电机控制仿真(matlab 2016b版本仿真模型 自用) 模型包涵: 开关磁阻电机传统控制:电流斩波控制.电压PWM控制.角度位置控制. 智能控制:12/8三相开关磁阻电机有限元分析本体建模 ...

  4. 开关磁阻电机控制仿真 开关磁阻电机传统控制:电流斩波控制、电压PWM控制、角度位置控制

    开关磁阻电机控制仿真(matlab 2016b版本仿真模型 自用) 模型包涵: 开关磁阻电机传统控制:电流斩波控制.电压PWM控制.角度位置控制. 智能控制:12/8三相开关磁阻电机有限元分析本体建模 ...

  5. 开关磁阻电机控制仿真 matlab 开关磁阻电机传统控制:电流斩波控制、电压PWM控制、角度位置控制

    开关磁阻电机控制仿真(matlab 2016b版本仿真模型 自用) 模型包涵: 开关磁阻电机传统控制:电流斩波控制.电压PWM控制.角度位置控制. 智能控制:12 8三相开关磁阻电机有限元分析本体建模 ...

  6. 最小拍有纹波系统仿真实验matlab代码,最小拍控制器设计.doc

    最小拍控制器设计matlab实验 [实验目的] 了解和掌握有纹波和无纹波最小拍控制器的原理和设计方法. 利用Matlab仿真,观察系统的输入输出曲线. [实验内容] 系统如图所示, G(s)?-R( ...

  7. pwm控制的基本原理_最详细的电机控制说明

    最详细的矢量控制说明 引言 有的时候,无论你是从事电机本体设计的电机研究员,还是备受煎熬电机销售,亦或是电机部门的领导,当你懂了下面知识,虽然不多,但你绝对不一样!你会具有以下特异功能: (1)如果你 ...

  8. 递归学习 斐波那契 java代码实现

    文章目录 java代码 单元测试 java代码 package csdn.dreamzuora.recursion;/*** Title: 斐波那契额* Description:*斐波那契数列:0.1 ...

  9. matlab傅里叶变换去噪代码,小波的分析在心电信号去噪中应用(内附Matlab去噪源代码).ppt...

    求职应注意的礼仪 求职时最礼貌的修饰是淡妆 面试时最关键的神情是郑重 无论站还是坐,不能摇动和抖动 对话时目光不能游弋不定 要控制小动作 不要为掩饰紧张情绪而散淡 最优雅的礼仪修养是体现自然 以一种修 ...

最新文章

  1. JVM源码分析之javaagent原理完全解读--转
  2. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
  3. 时序分析:Kalman滤波(状态空间)
  4. SAP ABAP实用技巧介绍系列之 ABAP XSLT 使用attribute增加新的属性
  5. linux查看apache配置文件路径,linux 命令行下查看apache配置文件httpd.conf位置
  6. python分布式事务_分布式事务的管理--atomikos
  7. mysql格式化日期成分_MySQL格式化日期
  8. HTML文字阴影荧光,小编,文章里的“发光”文字怎么做的?
  9. Apache Spark源码走读之22 -- 浅谈mllib中线性回归的算法实现
  10. 美团HD(7)-添加取消搜索按钮
  11. go程序设计语言-前言
  12. RS485总线应用与选型指南
  13. 手机市场的竞争,用户价值才是硬道理
  14. KGB知识图谱完善保险行业的知识应用体系
  15. Android组件化开发,组件间的Activity页面跳转。
  16. iOS开发之响应式编程RAC
  17. 种群遗传学的多态性衡量参数
  18. WebView(五)—— WebView的优化
  19. 逃计算机课检讨书600字,逃自习课检讨书
  20. 华南x99-f8黑苹果免驱网卡Wi-Fi正常蓝牙无法使用解决方法

热门文章

  1. 基于javaweb(springboot+mybatis)宠物医院预约管理系统设计和实现
  2. c++输入错误重新输入_C程序-根据时长和时薪计算工资1.3(解决输入非数字选项退出的bug)...
  3. java分隔符算法_《Java数据结构和算法》栈 分隔符分配
  4. Java中锁的使用和实现
  5. 自定义依赖注解无效_SpringValidation用注解代替代码参数校验解析
  6. python基础(15)之 继承
  7. python2.7 pyqt4创建qtapp_python-2.7 – 向TabWidget pyqt4添加加号按钮
  8. java容易掉发吗_容易被忽略的面试题—Java高并发
  9. c++ 不插入重复元素但也不排序_面试官爱问的 10 大经典排序算法,20+ 张图来搞定...
  10. mysql 导入导出大文件