600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 拓展模块使用教程和心得(四):PWM脉冲宽度调制及普通有刷马达和空心杯电机(测试平台:S

拓展模块使用教程和心得(四):PWM脉冲宽度调制及普通有刷马达和空心杯电机(测试平台:S

时间:2022-09-17 02:19:52

相关推荐

拓展模块使用教程和心得(四):PWM脉冲宽度调制及普通有刷马达和空心杯电机(测试平台:S

成就更好的自己

这次内容是给未来的新专栏(控制算法)打一个小基础,而且是为了完善上一期拓展模块教程三:步进电机的内容(/qq_36098477/article/details/107293881),把常用的博主目前手里有的电机,再进一步总结一下。

目录

PWM脉冲宽度调制

STC8A8K的PWM实现

STM32F103的PWM实现

普通有刷小马达与空心杯电机

一种电机驱动的典型电路

PWM脉冲宽度调制

对于PWM最浅显的理解就是让单片机输出一个占空比可调的方波,最常用的方面就是D/A转换和电机控制。具体原理给大家举个例子,8051单片机(STC8A8K等)在5V供电下,IO口置一后的电压是将近5V,如何产生用IO口产生0~5V的任意电压值呢,以2.5V为目标的话,可以输出幅值为5V的,占空比为50%方波,这样的话有效值就是2.5V。我们也可以通过PWM控制IO电平高低的时间,来控制外围附属电路通断时间。目前大多数单片机均支持PWM的硬件(STC公司的单片机有专门的硬件PWM,STM32系列需要设置定时器为PWM模式)。

下面我就以STC8A8K和STM32F103作为测试和介绍平台,讲解一下关于硬件和模拟PWM的过程。

STC8A8K的PWM实现

STC8A8K代表了市场上普遍的8051架构系列的硬件PWM方式;STC8A8K只有一组(8路)PWM通道,工作方式为:需要定时器为这一组PWM提供计数(8路共用一个定时器),但是可以为每一路(共8路)设置自己的电平翻转的两个计数值,通过比较定时器产生的计数是否达到每一路的两个计数值,从而控制每一路的PWM波形发生,此外,还可以设置每一路的初始电平状态,用户也可以将任意两路结合起来实现互补对称输出或死区控制等应用方式。总的来说,这8路PWM通道既同根同祖,又相互独立。

简单来说,硬件PWM的设置需要以下两大部分:

总PWM组设置:

PWM不与ADC关联;

PWM15位计数器溢出中断清零;

允许PWM访问拓展RAM区的SFR;

选择给PWM提供计数时基的定时器;

PWM计数器赋值;

给定时器赋定时值;

PWM组过程中的中断设置;

PWM通道设置:

选择这个PWM通道的输出引脚;

设置上面的引脚受PWM波形发生器控制;

设置这个端口初始电平;

PWM通道中断设置;

设置高低翻转电平对应的计数值;

在这个过程中,PWM自带的计数器值决定一次PWM的周期,电平翻转的两个计数值决定在这一个周期中电平反转的时间从而决定占空比。

void PWM0_Configuration(void){PWMCFG &= 0xBF; //将ETADC位置0,即PWM与ADC不关联PWMCFG &= 0x7F; //将CBIF位置0,PWM计数器归零中断标志位,需软件清零P_SW2 |= 0x80; //将EAXSFR位置1,以访问PWM在扩展RAM区的特殊功能寄存器//对PWM0的初始化部分PWM0CR &= 0xEF; //将C0_S[1:0]位置0 1,选择PWM0的输出引脚是P1.0PWM0CR |= 0x08; //将C0_S[1:0]位置0 1,选择PWM0的输出引脚是P1.0PWM0CR |= 0x80; //将ENC0O位置1,PWM0的端口为PWM输出口,受PWM波形发生器控制PWM0CR &= 0xBF; //将C0INI位置0,设置PWM0输出端口的初始电平为低电平PWMIF &= 0xFE; //将C0IF位置0,PWM0中断标志位,需软件清零PWM0CR |= 0x04; //将EC0I位置1,使能PWM0中断PWM0CR &= 0xFD; //将EC0T2SI位置0,关闭T2翻转时中断PWM0CR &= 0xFE; //将EC0T1SI位置0,关闭T1翻转时中断//对PWM0翻转计数器赋初值PWM0T1 =1; //赋值PWM0第一次翻转计数器值PWM0T2 = 0x00FA; //赋值PWM0第二次翻转计数器值//对PWM波形发生器时钟源进行初始化PWMCKS |= 0x10; //将SELT2位置1,PWM时钟源为定时器2溢出脉冲PWMC = 0x00FA; //PWM计数器赋值(同时对PWMCH和PWMCL进行了赋值)AUXR |= 0x04; //定时器2时钟为Fosc,即1TT2L = 0xE0; //设定定时初值T2H = 0xFE;//设定定时初值AUXR |= 0x10; //启动定时器2P_SW2 &= 0x7F; //将EAXSFR位置0,恢复访问XRAM//PWM外部异常控制寄存器的操作PWMFDCR &= 0xDF; //将ENFD位置0,关闭PWM外部异常检测功能PWMFDCR &= 0xF7; //将ENDI位置0,关闭PWM异常检测中断PWMFDCR &= 0xFB; //将FDCMP位置0,比较器与PWM无关PWMFDCR &= 0xFD; //将FDIO位置0,P3.5的状态与PWM无关PWMFDCR &= 0xFE; //将FDIF位置0,PWM异常检测中断标志位,需软件清零IP2 |= 0x40; //将PPWM位置1,使能PWM中断为最高优先级中断//使能PWM波形发生器PWMCR |= 0x80; //将ENPWM位置1,使能PWM波形发生器,PWM计数器开始计数PWMCR &= 0xBF; //将ECBI位置0,禁止PWM计数器归零中断}

至于模拟PWM就很简单了,可以直接用计数器产生中断然后通过代码翻转引脚电平即可:

void Timer0Init(){AUXR |= 0x80;//定时器配置,定时时间1MS,到时间后占空比加一,以实现占空比的调节TMOD &= 0xF0;TL0 = 0x40;TH0 = 0xA2;TF0 = 0;TR0 = 1;ET0 = 1;EA = 1;}void main(){Timer0Init();while(1){if(num<DR)//循环加一的num与DR比较,判断计数值是否翻转电平moter=1;elsemoter=0;num++;//计数值加一if(num==10001)num=0;}}void TM0_Rountine() interrupt 1{DR++; //通过定时中断调节占空比if(DR==10001) DR=0;}

STM32F103的PWM实现

STM32系列以最基础的F103为代表,STM32的PWM原理几乎与STC系列的8051架构单片机一模一样,只不过是实现方式和调用的硬件不同;STM32的PWM功能只是内部几个定时器的附属功能之一,没有专门的PWM硬件,我们在此不多介绍STM32的定时器(种类繁多,功能繁多,结构复杂),只介绍如何硬件实现;在STM32的定时/计数器硬件电路介绍中有一个寄存器叫捕获/比较寄存器,定时器会根据目前的计数值与比较计数器比较,若计数值小于某通道(STM32一个定时器有四个通道)的比较寄存器值,则对应通道的输出引脚保持高电平,反之则保持为低电平,;当计数器溢出,则装入重装值,对应引脚再恢复高电平。

简单来说,硬件PWM的设置需要以下几小部分:

PWM输出引脚的初始化;

使能要用的计数器的时钟;

选择计数模式(向上就是加计数,向下就是减计数);

设置计数器重装值;

设置时钟分频系数;

配置通道为比较通道;

使能输出比较状态(比较的结果可以产生中断或选择输出到引脚上)

给比较寄存器赋值;

设置比较达到条件后引脚电平的状态;

使能这个通道;

使能预装载寄存器;

这个过程中,计数器的重装值决定一次PWM的周期,比较寄存器的值决定电平翻转的时间从而决定占空比。

void TIM3_PWM_Init(void){TIM_TimeBaseInitTypeDefTIM_TimeBaseInitStruct;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 , ENABLE);//打开外设TIM3时钟 TIM_DeInit(TIM3); //将外设TIM3寄存器重设为缺省值 //TIM2是通用定时器,需配置TIM_ClockDivision、TIM_CounterMode、TIM_Period和TIM_Prescaler,无需配置TIM_RepetitionCounterTIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1 ; //设置了时钟分割(Tck_tim) TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up ; //选择了计数器模式(TIM向上计数模式) TIM_TimeBaseInitStruct.TIM_Period = 999 ;//设定计数器自动重装值,取值范围0x0000~0xFFFF TIM_TimeBaseInitStruct.TIM_Prescaler = 7199 ;//设置用来作为TIM3时钟频率除数的预分频值为(7199+1),取值范围0x0000~0xFFFF TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct ) ; TIM_Cmd(TIM3, ENABLE); //使能TIM3外设 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //选择使能输出比较状态TIM_OCInitStructure.TIM_Pulse = 500;//设置待装入捕获比较寄存器的脉冲值,取值范围0x0000~0xFFFF TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //设置定时器输出比较极性高电平TIM_OC1Init(TIM3, &TIM_OCInitStructure); //使能TIM3通道1TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR1上的预装载寄存器TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//配置为PWM模式1TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //选择使能输出比较状态TIM_OCInitStructure.TIM_Pulse = 250;//设置通道2的电平跳变值,输出另外一个占空比的PWMTIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于250时为高电平TIM_OC2Init(TIM3, &TIM_OCInitStructure); //使能TIM3通道2TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR2上的预装载寄存器}

模拟PWM就很简单了,这里跟上面8051的原理几乎一致,而且在STM32里资源丰富一般是用不到模拟的,这里就不给代码了。

普通有刷小马达与空心杯电机

先上实物图:

第一张图是最常见的小马达了,在各种玩具中都有见,特点是转速低,扭矩一般,耗电量大,振动幅度大,总之没有一点优点,而且外界负载会很大程度影响运行稳定性和运行电流;好一点的也有这种以线圈为转子,永磁体为定子的有刷驱动方式的其他类型的电机,那种适合于做动量轮和动力电机。

第二张图是空心杯电机,博主手里的型号是720,特点是转速快,扭矩小,耗电量低,转动稳定,一般用作航模螺旋桨电机等不需要太大负载但对转速有要求的场景。下图是博主在四旋翼飞行器上的应用。

一种电机驱动的典型电路

这种电路可以作为集基础控制,功耗波动,稳定为一体的理想电路,中间的CMOS管SI2302是博主经过选型和实践后确定,是可以是直接照搬的,多用于在低电压情况下(3.3V~12V)控制上文中那两个类型的电机。

控制方面,可以通过PWM控制右端从VCC到GND整体的导通状态,从而控制电机的转动速度,对于电机工作电流有要求的朋友可以将SI2302替换成SI2300,2300内阻比较小,可以容纳大一点的电流。

那个4.7uF的电容也可以不加,也可以替换成合适的稳压二极管,但是测试后觉得电容好像更稳定一些。

单单靠这种电路和上文的两种电机是不能做成闭环控制的,需要有转速传感器或加速度传感器作为反馈才行。此外,这种电路只能实现相对的控制,不能实现精度极高的控制,那样的话需要更为严谨的控制方式和电路,就不能仅仅只靠PWM了。

拓展模块使用教程和心得(四):PWM脉冲宽度调制及普通有刷马达和空心杯电机(测试平台:STC8A8K STM32F103)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。