STM32 PWM输出原理和直流电机PWM驱动原理详解及例程

PWM会有很多地方用到,如控制灯的亮度,控制电机,控制舵机或者其他一些外设,有时候你的单片机所输出的PWM是作为信号去传输数据,有时候是用它来提供一个可控的超小功率的电压。

首先要知道什么是PWM信号。PWM信号是“Pulse(脉冲) Width(宽度) Modulation(调制)”的缩写,意思是 可控制宽度的脉冲信号。

那么这个信号有什么用呢?它是怎么实现控制小灯或者电机呢?

我们就用小灯作为例来说。

首先看看普通的发光二极管。
在这里插入图片描述
就这种,那种贴片的(就是你们手里开发板上发光的那个)也是同理哈。工作原理就是通电就亮,断电就灭。

因为人眼存在“余晖效应”
在这里插入图片描述

当灯熄灭了的一瞬间,其实人的眼睛还感觉他是亮着的,当灯不停的发亮再熄灭,只要中间间隔的时间极其短,人眼看上去就像是它一直在亮着一样。

那么这个时候思考一下,有两个灯A和B,供电电压相同,在一段固定的时间内,A灯在不停地闪烁,频率之快以至于人眼无法分辨,其中有50%的时间亮着,50%熄灭。而B灯一直亮着。那么这样观察上去就会明显地感觉到A灯比B灯暗很多。那么这就是一种控制小灯亮度的办法了。

当然你也可以理解为在相同的功率下,AB两个灯都是在做把电能转化为光能的工作,在一天里A灯断断续续地工作了12小时,B灯连续不停工作了24小时。那么B转化的光能更多,也就更亮。
在这里插入图片描述
这个时候只要能在极短时间内控制灯的亮与灭就可以控制亮度了。

在上图中AB两个灯的供电端电压可以看成下图这样
在这里插入图片描述
现在A灯这个电压形状就是我们要控制的PWM的形状了。

也就是说小灯变暗其实并不是变暗,它的亮度随电压不变而不变,只是它的闪烁过程中暗的时间变长了,人眼看上去灯变暗了。

那么以此类推,电机转慢了其实是它一直在转动和停顿吗?????
并不是!电机的线圈,像电感类似的结构,通直流阻交流,它具有电流的不可突变性,通电时它产生的磁场不允许电流的突变,他会将电流产生的磁场用来抑制电流的变化。
所以说用PWM控制电机的话,不讲驱动电路板原理的话,可以简化理解为这样:用芯片生成的PWM去使电机两端的电源图像变得像PWM信号一样。至于他是怎么变得我们下回分解。
意思就是说如果用PWM控制电机,那么电机两端的电压是010101这么突变的,但是电机电流却不是,即使电压为0,因线圈自感电动势的存在,电机中依旧有电流流过,电机依旧继续转动,那么我们使用PWM 为什么可以控制转速呢?
你也许会想到高中物理老师说的一个词语:等效电压。
我们通过PWM去控制等效电压。
你也可以根据能量守恒来想啊,电机转起来过后,线圈电阻恒定不变,功率恒定不变,两端电压峰值也恒定不变,那么这样情况下,电源电压图形上占空比的不同将导电机在这段时间内致消耗能量的不同,以此达到转化的机械能的不同,转速是不是也不同了。

那么现在我们怎么通过STM32来输出一个如A图电源端这样形状的信号呢?

首先是频率,这个信号的周期必须极其的短,也就是频率得快,大概得多块呢?这么说吧,至少得50Hz左右才不会有明显的闪烁感。

其次是占空比,占空比也就是一个周期内高电平占了整个周期的百分之几,像A灯这个就是百分之五十,50%的占空比。

周期和频率都是可以自己设置的。

那么为了设置频率和占空比,我们就先来了解一下STM32的TIM定时器,这个定时器就是控制上图时间坐标轴的关键了。

“STM32F1 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器 (CNT)构成。STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产 生输出波形(输出比较和 PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长 度和波形周期可以在几个微秒到几个毫秒间调整。STM32 的每个通用定时器都是完全独立的, 没有互相共享的任何资源。”

简单说就是这个定时器就是定时器,你可以理解为计时用的(废话吗这不是)。

详细讲呢就是它其实是一个计数器,就是用来数数的,结合了你的芯片工作频率和你可以自己设置的预分频数,设置后就可以作为定时器使用。

举个例子哈,我之前用的STM32F103设置的的频率是72MHz,就是72 * 10 ^ 6 Hz。而不同的定时器可能在不同的总线上面,APB1总线的频率是36MHz,APB2的频率是72MHz,假设我设置一个在APB1总线上的定时器,预分频数设置成为36,那么我的这个定时器就被设置成了36 * 10 ^ 6 / 36 Hz的这么一个 计数器 ,1s之内可以数1000000个数。

然后是“重装载值”,就是说计数值达到这个重装载值后就把计数值归零。假设我设置为1000哈,那么我们一起来看,用我设好的这个定时器数到1000需要几秒钟?结果是1000/1000000=1*10 ^-3 s,也就是0.001s,1ms哈。意思就是说我的频率和周期已经设置好了哟,周期是1ms,那么频率1000Hz。

公式就是 周期 = 重装载值 / 总线频率 / 预分频数。是不是很简单了。

然后是占空比了,设置占空比需要设定一个“比较值”,当计数器计数到这个值的时侯我们就可以做一个操作,比如输出高电平,然后在计数值没达到的时候输出低电平,或者反着来也行,都是可以通过代码实现的,那么显而易见,这个比较值必须要比重装载值要小才可以。接着看一下这个图就容易明白了。

在这里插入图片描述

就是说信号在计数值达到比较值之后电信号发生变化。

警告:在pwm作为控制信号外接其他驱动模块使用时,比较值不可大于等于重装载值!这样会使某些廉价驱动板的H桥上下桥臂同时导通。(别问我怎么知道的,我不想听。)

下面开始设置。

void TIMx_Int_Init(int arr,int psc) 
{
     GPIO_InitTypeDef GPIO_InitStructure; 
     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
     TIM_OCInitTypeDef  TIM_OCInitStructure; 

     //先定义几个初始化要用到的结构体
     
     RCC_APBxPeriphClockCmd(RCC_APBxPeriph_TIMx, ENABLE); //使能计时器的时钟
     RCC_APBxPeriphClockCmd(RCC_APBxPeriph_GPIOX);//使能GPIO的时钟
     
     //使能时钟,TIM的通道与某一个IO口对应,自己查去
     //总线是哪个也自己查去
     
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_x;      //对应的那个引脚
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出 
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
     GPIO_Init(GPIOX, &GPIO_InitStructure);                //初始化 GPIO 
     
     TIM_TimeBaseStructure.TIM_Period = arr;    //设置重装载值    
     TIM_TimeBaseStructure.TIM_Prescaler =psc;  //设置预分频数  
     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割  
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM 向上计数
     TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure); //②初始化 TIMx
     
     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;    //选择 PWM 模式 2 
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //输出极性高 
     TIM_OC2Init(TIMx, &TIM_OCInitStructure);
     TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable);  //使能预装载寄存器 
     TIM_Cmd(TIMx, ENABLE);                          //⑤使能 TIMx

 }
     

这就是初始化设置的函数了,可以在里面自己设置你想要的定时器,编辑频率,APBX,GPIOX,TIMx,Pinx都自己选自己查,对应你的硬件电路图来做出改变。

最后设置比较值就可以控制占空比,比较值设定呢用这个
TIM_SetCompare2(TIMx,你想要的比较值);

这样就可以输出一个简单的PWM波了。

相信认真看到这里的同学已经理解了这个简单的PWM,代码看不懂不重要,那是人家的库函数,你不需要知道。重要的是你要理解你想控制的东西的工作原理和控制方法。就像怎么造车怎么造发动机你不懂,没关系,你只需要知道怎么开车就可以了。

现在我再来讲一下简单的电机驱动方法。
刚才控制小灯亮度,我们是将PWM作为电源信号,而电机的控制一般都是将其作为控制信号使用,也就是说用它控制电机两端的电源,而不是直接作为电源,因为这个电压实在太低了,芯片引脚提供的电流也是太小太小了。
首先是网上到处可以找到的直流电机驱动器,就几十块一个的那种
在这里插入图片描述

这种呢比较简单,他只是一个驱动模块,你不需要知道它的工作原理,你只用自己配置一个pwm插上去就能用,一个占空比对应一个电压,转速可以通过编码器检测自己使用PID算法来控制。

但是更多时候咱们自己或者别人设计的驱动器使用起来就没有这么简单了,尤其是无刷电机驱动。通常我们将控制芯片和驱动模块做在同一个电路板上,这样不仅可以节约成本,还可以有效减小电路板的大小,这个时候你的代码就需要结合实际的硬件来做相应的改变。

一般来讲呢直流电机的驱动大部分使用H桥驱动,什么是H桥驱动呢我会在下次闲下来的时候详细的讲。用到了H桥的话大功率一般使用MOS管来实现电压的1和0的切换,你的代码还必须根据使用的MOS驱动芯片和光耦的使用与否来做出相应的变化,还有无刷电机的三相供电也实在令人头疼。

总之呢硬件是软件开发的基础,不要求你会设计,但是咱得懂啊。下一篇我就来讲讲 “H桥驱动原理以及有刷直流电机驱动及程序”。

更新时间不定,看心情。写的不好或者不对的地方欢迎大家指正。

  • 230
    点赞
  • 912
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
### 回答1: stm32f103是一种常用的单片机芯片,通常会进行升级以提高其性能和功能。然而,若在升级过程中出现了失败,可能会导致芯片无法正常工作。此时,需要对此进行分析和解决。 在升级stm32f103时,通常需要将新的固件文件下载到芯片中。如果芯片下载的过程中出现了问题,可能会导致无法完成升级,或者升级完成后出现错误。此外,如果升级过程中出现了某些不可预测的问题,也有可能导致升级失败。 一旦升级失败,首先需要确定所使用的升级工具和升级方式是否正确。其次,需要检查是否存在硬件故障或芯片损坏等问题。如果发现芯片损坏,则需要更换芯片并重新进行升级。如果问题出现在升级工具或升级方式上,需要更换或修复工具并重新进行升级。 总之,升级stm32f103时出现失败可能会导致一些问题。为避免这种情况,需要在升级前进行充分的准备和测试,并确保升级工具、升级方式和芯片本身都处于良好的状态。此外,在升级过程中要时刻关注芯片的状态,并在出现异常情况时及时采取措施。 ### 回答2: 首先,我需要确认“升级10%后失败”指的是什么情况。如果是指在升级STM32F103芯片固件时,升级进度到达10%时出现错误,则可能出现以下几种情况: 1. 烧录工具错误:请先确认使用的烧录工具是否正确设置,如烧录地址是否正确,是否选择了正确的芯片型号等。如果烧录工具的设置有误,可能导致升级失败。 2. 芯片与固件不匹配:确认正在升级的固件文件与目标芯片型号匹配。如果固件文件与芯片不一致,可能会导致升级失败。 3. 硬件连接问题:检查硬件连接是否正确,包括电源、引脚连接等。不正确的硬件连接可能导致芯片升级失败。 4. 芯片损坏:如果芯片在升级过程中受到了电压干扰等因素,可能导致芯片损坏。在使用芯片之前,建议使用合适的工具检测芯片是否正常。 如果以上都没有解决问题,建议参考STM32F103的官方文档、论坛或咨询STMicroelectronics的技术支持来寻求更详细的帮助。
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值