打印
[技术问答]

如何设置两路PWM相差四分之一周期

[复制链接]
1987|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lss1985|  楼主 | 2017-9-7 11:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lss1985 于 2017-10-9 16:03 编辑

如何设置两路频率相同的PWM相差四分之一周期呢,现在是通过延时来处理的,但实际使用总有些莫名其妙的问题FREQ是修改频率的函数,然后根据频率计算延时的时长,也即四分之一的周期,第二个函数是启动PWM,延时函数放中间,先启动0,5,再启动6,7,延时子函数是按us计算的,实际使用出现问题是第一次调用FREQ正常,第二次再调用FREQ来修改PWM周期后,延时的时间还是之前第一次PWM周期的四分之一,
void FREQ(uint32_t freq)
{
        uint32_t cnr,cmr;
       
        uint32_t zk=50;
       
        cnr=22118400/5/16/freq-1;
        cmr=zk*(cnr+1)/100-1;
       
        delaytime=250000/freq;
       
        PWMA->CNR0 =cnr;//pwm0
        PWMA->CMR0 =cmr;
        PWMB->CNR1 =cnr;//pwm5
        PWMB->CNR2 =cnr;//pwm6
        PWMB->CNR3 =cnr;//pwm7
        PWMB->CMR1 =cmr;//pwm5
        PWMB->CMR2 =cmr;//pwm6
        PWMB->CMR3 =cmr;//pwm7

}
void PWM_start(void)
{
        PWMA->PCR |=(1<<0);//START pwm0
        PWMB->PCR |=(1<<8);//START pwm5
        Delayus(delaytime);
        PWMB->PCR |=(1<<16)|(1<<24);//START pwm67
}
void Delayus(uint32_t unCnt)
{
    SysTick->LOAD = unCnt * 11;
    SysTick->VAL = 0;
    SysTick->CTRL |= 1UL << 0;
    while((SysTick->CTRL & 1UL << 16) == 0);
}




沙发
xinpian101| | 2017-9-7 19:15 | 只看该作者
应该有个互补输出的模式,你在这个版块搜那个温老师的电子书看看。

使用特权

评论回复
板凳
捉虫天师| | 2017-9-8 21:31 | 只看该作者
这个应该有个互补模式

使用特权

评论回复
地板
安娜12345| | 2017-9-12 12:57 | 只看该作者
请问,设置为互补模式之后是不是只需要设置其中一个PWM波(PWM0或PWM5)的参数?

使用特权

评论回复
5
天灵灵地灵灵| | 2017-9-13 23:11 | 只看该作者
肯定是要设置参数的,要不怎么知道频率和占空比。。

使用特权

评论回复
6
lss1985|  楼主 | 2017-10-9 12:01 | 只看该作者
相位差问题不知哪位大神有好方法

使用特权

评论回复
7
lss1985|  楼主 | 2017-10-9 21:49 | 只看该作者

使用特权

评论回复
8
zhuotuzi| | 2017-10-9 22:39 | 只看该作者
相差多少的不懂,看到过互补的例子

使用特权

评论回复
9
zhuotuzi| | 2017-10-9 22:42 | 只看该作者
预分频和死区是不是可以设置成这样

使用特权

评论回复
10
lss1985|  楼主 | 2017-10-10 08:28 | 只看该作者
zhuotuzi 发表于 2017-10-9 22:39
相差多少的不懂,看到过互补的例子

互补是可以很方便设置的,只需要设PCR里的某一位
相差好像设不了

使用特权

评论回复
11
lss1985|  楼主 | 2017-10-10 17:44 | 只看该作者
问题解决,采用延时也可以较精确的实现
问题来自于PWM模块,当改变频率时,要重新初始化PWM的设置,重新修改计数寄存器,再重新启动,这样延时的值就满足要求了

使用特权

评论回复
12
wahahaheihei| | 2017-10-10 23:28 | 只看该作者
lss1985 发表于 2017-10-10 17:44
问题解决,采用延时也可以较精确的实现
问题来自于PWM模块,当改变频率时,要重新初始化PWM的设置,重新修 ...

没做过这种,楼主分享一下代码学习学习啊。

使用特权

评论回复
13
lss1985|  楼主 | 2017-10-11 22:47 | 只看该作者
wahahaheihei 发表于 2017-10-10 23:28
没做过这种,楼主分享一下代码学习学习啊。

没什么卵用,一个问题的解决带来了另一个问题
当频率发生变化时,停掉PWM模块,再初始化赋给新的频率重新启动,这样的好处是延时可以搞定了,
带来的问题是停掉PWM模块,哪怕没有延时在电机端也会有一顿一顿的反应,真是尴尬。。。。
再研究研究

使用特权

评论回复
14
zhuotuzi| | 2017-10-13 16:27 | 只看该作者
lss1985 发表于 2017-10-11 22:47
没什么卵用,一个问题的解决带来了另一个问题
当频率发生变化时,停掉PWM模块,再初始化赋给新的频率重新 ...

我觉得如果要求频率不高,可以用定时器做。

使用特权

评论回复
15
zhuomuniao110| | 2017-10-14 19:03 | 只看该作者
任意类型的可以用两个io配合定时器模拟

使用特权

评论回复
16
heisexingqisi| | 2017-10-15 20:13 | 只看该作者
毫秒级别的应该可以使用io模拟出来,但是做这个的时候就没法干别的了。而pwm发生器是独立运行的

使用特权

评论回复
17
tongbu2015| | 2017-10-15 22:34 | 只看该作者
这个延时是靠tick时钟实现的

使用特权

评论回复
18
lss1985|  楼主 | 2017-10-16 22:25 | 只看该作者
本帖最后由 lss1985 于 2017-10-16 22:27 编辑
zhuotuzi 发表于 2017-10-13 16:27
我觉得如果要求频率不高,可以用定时器做。

应该不是延时不准确的问题。
现在的问题是这样,四路PWM分成AB两组,所有的PWM频率一样
上电第一次给频率A组给完了延时四分之一周期再启动B组,效果符合预期都是正确的。
当频率需要改变时,调用修改频率的函数,也即修改所有PWM的cmr和cnr,然后调用同样的启动函数,即先启动A,延时四分之一周期,再启动B。实际发现这样的方法,B组的PWM的输出实际上没有停止,也就是说第二次启动A的时候,B组仍在运行,这样导致延时后启动B组根本就不是理想状况,延时要比给定的要大。导致PWM波形的相位差不对了。
如果在修改频率前加一个停止所以PWM输出的函数,修改后再启动,倒是可以实现正确的延时效果。
但是对于步进电机,PWM一停就会停止,实际测试就有一顿一顿的现象。即便接受这种一顿一顿的现象,当给定的步进电机速度过高的时候,步进电机就进入堵转了。
感觉进入了死胡同。咨询了新唐的技术支持陈工,目前尚未得到回复

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

92

帖子

2

粉丝