mmuyu 发表于 2023-7-27 17:32:13

单定时器pwm控制L9110驱动电机

本帖最后由 mmuyu 于 2023-7-27 17:36 编辑

    我们可以发现宠物屋的电机驱动使用了两个定时器生成pwm来控制电机正反转,对于单片机来说,定时器少端口多,节省出一个定时器换用端口来控制方向显然是好处多多,不仅节省了资源,简化代码,也有利于减少因为定时器可能产生1潜在问题。
首先我们看一下l9110的是如何驱动的。

Gokit的套件上,IA连接到了PB4 IB连接到了PB5。正常情况两个定时器控制分别输入到IA IB,当IB为pwm信号,IA为低电平时风扇转动,此时转速由IBpwm占空比决定,当IB为低电平,IA为pwm波的时候风扇反转,转速则由IApwm占空比决定。那么根据上面的真值表我们可以换一种思路,使用IB固定生成pwm IA通过电平控制正反转,那么此时正转是由pwm的高电平时间控制,反转则是由低电平时间控制。理论可行,那么就来操作吧。
    首先添加数据点用于控制正反转和转速。

然后打开cubemx配置端口和定时器。这里我们把PB4设定成输出,PB5设定成定时器3通道2,勾选时钟使能,配置成pwm输出模式

这里简述一下定时器的配置,首先prescaler是预分频系数,可以令定时器生成更低的频率,counter period 就是通常我们所说的定时器重载值。
假设我们想要得到一个1000hz的pwm波要如何配置呢,首先看定时器挂载的总线的频率,我这里的定时器三挂载在apb2上,是72mhz,那么我们会尽可能使用预分频后得到一个整数值,因此我这里的预分频是72(减去1是因为从0起算,后面同理),那么此时经过预分频,我们得到了1mhz的频率,1mhz计数1000个值,需要花费0.001s 也就是说0.001s完成了一个电平跳变,我们说的pwm频率是1s除以1s内电平跳变次数,1s除以0.001s 显然可得1000 因此我们就得到了一个1000hz的pwm波。
此时我们就可以生成代码来编写驱动了。
首先我们要找到定时器的配置代码,启动pwm输出,在usercode区内启动pwm,默认比较值是0因此电机上电不会转动。

接下来,编写头文件,定义端口,pwm频率,和控制电机的级数,这里我使用了255级进行电机控制

当然尽量使用能被频率整除的级数,不然可能要进行浮点运算,单片机的浮点运算是比较弱的,应该尽量避免浮点运算。
接下来是我们的代码部分。

这里简单解释一下过程,函数被传入整形的速度和模式参数。模式用于控制正反转,当速度等于0时,pwm停止,同时pb4拉低,根据L9110真值表可得出,这种情况是停止的状态,这是正反转都不转。
当速度为最大的时候,有两种情况,正转由pwm波高电平时间决定,那么此时我们应该让pwm一直输出高,把比较值修改成与计数值一致即可。反转则是由pwm的低电平时间决定,那么此时应该相反,让pwm输出低,因此输入的是比较值0
当转速在正常值的时候,正转由app获取到的值除以分级取得占比,再与计数值相乘得到占计数值的部分,最后经过取整函数取整,这样计算就得到了255分级扩大到1000的pwm占空比需要的比较值,再根据真值表,设置pb4端口的电平,启动pwm实现正转转速控制。
反转由pwm的低电平时间控制,那么输入的数值应该被分级数值减去来换算反转需要的占空比。
最后,在事件语句内调用函数即可。

电机没法演示,不过我用手感受了,正反转和转速正常运行。最后附一张app图。

还有应尽量避免电机最大转速运行,毕竟大部分电脑的端口基本只能跑到1.9a的电流。


页: [1]
查看完整版本: 单定时器pwm控制L9110驱动电机