DMA方式控制PWM脉冲数量、频率、占空比,用于步进、伺服.....

2019-12-13 18:32发布

本帖最后由 爱则倾心 于 2016-3-30 18:09 编辑

关键词:STM32、CubeMX、DMA、TIM、PWM、伺服电机控制
1、关于ST的CubeMX,目前来说,让人又爱又恨,恨比爱多。一是从标准库转用Cube库比较费劲,二是ST不在更新标准库,新出的片子只能用Cube库或直接玩寄存器,三是目前来说Cbue里面到处都是地雷.....
2、项目开始前从网上查了一些精确产生PWM脉冲个数的方法,引述如下:
     1)外部再弄个IO口接到PWM脚上,用外部中断的办法,单独来计数。此办法可行,但非常不科学,并且浪费资源。   
     2)使用定时器,使用一个和PWM频率一致的定时器,使用定时器中断来计数。此方法比第一种办法好了很多,但是仍然感觉比较笨,并且单片机会频繁的进中断......
     3)利用定时器内部互联,一个定时器的给另一个定时器提供时钟,主从模式,一个PWM输出脉冲给另一个定时提供时钟,每来一个脉冲,计数器值+1,当+到指定个数后,产生一次中断,然后关闭PWM输出。此方法还是浪费资源,且多路电机控制需                     要产生多路频率不同、个数不同的脉冲时就不能满足要求了。
     4)使用DMA来控制发送的脉冲数,最大可以65535个,如果想使用不同频率和脉宽,可以设置不同的装载值,如果你发送的脉冲数超过65535个,则可以使用DMA传输完成中断中切换DMA传输的数据起始地址及发送数量,继续发送。这个方法即方便,又减轻CPU的负担,可以同时驱动多个电机工作,还可以根据电机的启动-运行-停止使用不同的频率。
3、上数第4)种方法甚好,只是没有大神们没能具体说明如何实现,根据项目需要,选定第4)种方式实现多路、不同频率、不同脉宽、数量精确可控的PWM波。项目仍在开展中,时间有限,本帖今天起开始说说第4)方式的具体实现方法。
4、硬件平台:STM32L476G-DISCO,TIM2、CH1、PA0、DMA1,软件平台:STM32CubeMX+MDK V5.15。
5、软件实现步骤及关键点说明......回家了,待续......
5.1、使用Cube MX---->new project---->选择单片机型号---->选择TIM2的时钟源、通道及模式
CUBE_GENERATOR.jpg (32.61 KB, 下载次数: 0) 下载附件 2016-3-30 18:07 上传
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
76条回答
7nian
1楼-- · 2019-12-16 12:53
 精彩回答 2  元偷偷看……
gpfrank
2楼-- · 2019-12-16 17:46
非常好,一直想用这个办法!
yefeng022
3楼-- · 2019-12-16 21:53
本帖最后由 yefeng022 于 2016-4-2 22:53 编辑

我用过之前论坛上讨论过的DMA+TIM的方式。
每一个通道的脉冲需要:用于传输周期寄存器的DMA*1  定时触发DMA传输的TIM×1  用于产生脉冲的TIM×1 用于脉冲个数计数的TIM×1
大致的原理是:用一个定时器固定周期触发DMA将算好的周期寄存器值传输给产生脉冲的TIM寄存器,再用另个TIM配置为级联模式,用于输出脉冲计数。
这种方式有坛友在STM32上实现了4通道的,受到启发我也在PIC的单片机上实现了4通道独立同时发脉冲。
这种方式有几个缺点:
1.DMA定时传输,意味着加速曲线是阶梯状的,无法做到每个相邻脉冲频率都均匀变化。(我是用的1000次DMA传输完成加速,实际上加速效果还是很好的)
2.无法预知加速脉冲个数,这样只能实现对称加减速。(用过这种方法的同学应该知道为什么)

你说的这种方式有些不同
1.加速步数可控,可以实现非对称加减速,并且每个脉冲的的寄存器值都可以连续变化,加速曲线更加平滑。
2.这个方式只能用于低细分或者低速场合,因为加速过程的脉冲数不能太多,否则存储空间够呛。固定加速模式还能放在flash,如果是动态加速模式(加速曲线每次运行可以变化)必须放在ram中就受到很大限制了。
3.非常节省定时器,一个定时器就搞定。

其实你给的这种思路非常好,就是太费内存了,我之前在matlab上计算过16细分下用0.5s加速到1000转(梯形加速)用的总脉冲数,远远超出了单片机ram的大小,直接放弃了。
另外,其实可以不用保证每个脉冲都是50%的占空比,把脉宽设置成驱动器可接受的最小脉宽就行了,这样就不用多计算和保存一个寄存器的值了,可以节约内存。
爱则倾心
4楼-- · 2019-12-17 02:16
yefeng022 发表于 2016-4-2 20:51
我用过之前论坛上讨论过的DMA+TIM的方式。
每一个通道的脉冲需要:用于传输周期寄存器的DMA*1  定时触发DMA ...

感谢大侠的指点,关于你说的“因为加速过程的脉冲数不能太多,否则存储空间够呛”,加速完成匀速阶段,可以用内存不增方式,但加速阶段确实比较难办,加速阶段需占用多少空间还没计算,看来大侠对电机控制比较熟,我现在正在做伺服电机加减速这一块,若遇到问题还望不吝赐教,大侠最后给的建议非常好,另外,你怎么删除了一条回复,你说的那个中间一段时间无脉冲输出问题,我是这样干的,电机加速、匀速、减速,定时器始终不停,在DMA传输完成中断里切换内存地址或设置为内存不增方式传输,我验证了一下,脉冲输出是连续的。
yefeng022
5楼-- · 2019-12-17 02:20
爱则倾心 发表于 2016-4-2 23:21
感谢大侠的指点,关于你说的“因为加速过程的脉冲数不能太多,否则存储空间够呛”,加速完成匀速阶段,可 ...

删掉那条是我刚开始理解错了,但是频率高的时候中断处理时可能会多发脉冲。

可能因为我是用在步进电机上的原因,整个加速过程的脉冲数比较大,尤其是某些重载的电机。我想伺服电机应该不会这么敏感吧,毕竟伺服驱动器内部还有闭环控制的,给脉冲只是给指令的一种方式罢了。
爱则倾心
6楼-- · 2019-12-17 02:43
 精彩回答 2  元偷偷看……

一周热门 更多>