打印
[技术问答]

如何提**唐硬件pwm的分辨率

[复制链接]
1819|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Harvard|  楼主 | 2016-6-7 12:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如题,  新唐的pwm一般都是16bit, 其实也可以利用预分频比来提高一些所谓的分辨率.
现在有这样一个需求. 要求脉宽在0-65535us之间连续可调, 周期,也类似.但是肯定要大于65535,连续可调(分辨率为1us),有没办法通过软计数的方法,让pwm看上去的分辨率大于16bit呢


    目前针对这个应用,我想了一个i办法, 当然首先,把预分频比和时钟分配设置成合适参数,使得硬件pwm的最小时间分辨率为1us,
    利用pwm的oneshot模式. 第一个脉冲进行实际脉宽的输出,  
    如脉宽是32768us, 周期为2*65535这样一个脉冲, 利用实际的硬件pwm无法做到.硬件的16bitpwm只能做到32768us脉宽, 65535us周期,剩下的65535us的低电平期怎么办, 我想到了先用oneshot输出一个
            |-------32768us-----|________32767us____.
的oneshot波.然后再输出一个cmr=0,cnr=32768us的波,
            |___________________________________|-|,
但是,这个波会输出一个us的脉冲.         
然后重复.如此就组合成一个实际所需要的波.,基本可以达到要求.
请教大家还有没有合适的波,???
沙发
gejigeji521| | 2016-6-7 16:49 | 只看该作者
楼主可以用定时器模拟一个嘛,那样你想怎么样就怎么样了,通过IO翻转。

使用特权

评论回复
板凳
heisexingqisi| | 2016-6-7 17:24 | 只看该作者
这个是固定的吧,没听说过提高分辨率,另外分辨率高了其实耗电大的。

使用特权

评论回复
地板
Harvard|  楼主 | 2016-6-9 08:51 | 只看该作者
我的意思是这样. 如果我设定pwm的tick为1us
那么周期最大为65535;  脉宽从1-65535可调.
现在的需求是脉宽不变; 要把周期从65535扩大,这样可以形成超低频.

|_____________________|--------D-------| 65535
|_____________________|--------D-------||___________________________________||___________________________________|
                                                            65535                                                 65535                                                           65535

不知道众看官 看懂了没有

使用特权

评论回复
5
Harvard|  楼主 | 2016-6-9 09:21 | 只看该作者
目前的实现思路是这样 .讲pmw设置到 oneshot模式 然后使能 period中断. 当pwm计数器减到0时,引发中断 ;

这里面分两种状态 ;

第一个状态是输出所需要的脉宽. 在65535的周内里 输出所需要的脉宽 .

第二个状态就是输出剩余的低电平时间,  此时将 CMR设置为0 cnr设置为所需要的数,如果不够 ,可以利用循环的形式, 无限制扩展,这样. 整个脉冲的周期就可以变得很长 ,
目前这个算法 只支持0-65535的脉宽,如果也需要扩展 ,就可以在第二个状态处理上下功夫;

使用特权

评论回复
6
zhuotuzi| | 2016-6-10 20:31 | 只看该作者
低频好做啊,弄个定时器中断来做,你想多久的周期就多久了。

使用特权

评论回复
7
Harvard|  楼主 | 2016-6-12 13:04 | 只看该作者
利用pwm来做 是为了保持一致性. 分辨率1us不变. 目前单路已经成功, 但是3路同时工作时, 会出现部分通道的计数停止 .

使用特权

评论回复
8
Harvard|  楼主 | 2016-7-18 18:47 | 只看该作者
问题已经解决了

使用特权

评论回复
9
huangcunxiake| | 2016-7-19 10:08 | 只看该作者
楼主怎么解决的,方案说出来学习一下。

使用特权

评论回复
10
lai832| | 2016-7-19 16:45 | 只看该作者
你会发现:时钟源的1uS不准,造成你N个65535uS后会差1~几个uS. 越大,误差越大,

使用特权

评论回复
11
643757107| | 2016-7-19 21:29 | 只看该作者
楼上观点 我同意,误差会被放大。

使用特权

评论回复
12
Harvard|  楼主 | 2016-7-20 18:29 | 只看该作者
huangcunxiake 发表于 2016-7-19 10:08
楼主怎么解决的,方案说出来学习一下。
/* 波形1的基波输出函数: 状态机
*  |----stage1----| _______stage2____.
*  stage1: CMR=CNR,输出高电平脉宽
*  stage2: CMR=0; ,输出低电平脉宽,
*  stage2中, 如果低电平的脉宽数大于65535,则
*/
static u16 wave1_s2_n = 0;
static u16 wave2_s2_n = 0;
static u16 wave3_s2_n = 0;

void pwm_wave1( void )
{
    /* 状态0:输出脉冲高电平(脉宽)*/
    if(SYS_wave1_state == 0 )
    {
        /* 判断是否具有空周期,没有则一直在状态0 */
        if( SYS_wave1_s2_n >0  )
        {
            SYS_wave1_state =1;
            wave1_s2_n = SYS_wave1_s2_n;

        }
        else
        {
            SYS_wave1_state = 0;
        }
        /*根据pwm的硬件特性,输出时,cmr尽量在前面 */
        
        PWM_SET_CMR(PWMB,0,SYS_wave1_cmr_s1);
        if( SYS_wave1_cnr_s1 == 0 ) SYS_wave1_cnr_s1 = 1250;
        PWM_SET_CNR(PWMB,0,SYS_wave1_cnr_s1 );
    }
    else
    {
            SYS_UnlockReg();
            SYS->P2_MFP &= ~(SYS_MFP_P24_Msk  );
            SYS->P2_MFP |= SYS_MFP_P24_GPIO ;
            SYS_LockReg();
            WAVE1_PWM =0;
   
        /* 低电平重复次数 */
        if( wave1_s2_n >0)
        {
            wave1_s2_n --;
            /*s2 输出完毕,切换到s1*/
            if(wave1_s2_n ==0)
            {
                /* 推出低电平输出,*/
                SYS_wave1_state = 0;
                SYS_UnlockReg();
                SYS->P2_MFP &= ~(SYS_MFP_P24_Msk  );
                SYS->P2_MFP |= SYS_MFP_P24_PWM4 ;
                SYS_LockReg();
            }           
        }
        
            PWM_SET_CMR(PWMB,0,SYS_wave1_cmr_s2);
            if( SYS_wave1_cnr_s2 == 0 ) SYS_wave1_cnr_s2 = 1250;
            PWM_SET_CNR(PWMB,0,SYS_wave1_cnr_s2);  

    }
   
     
}




/**
* [url=home.php?mod=space&uid=247401]@brief[/url]       PWMA IRQ Handler,处理本项目的 PWM4-7
*
* @param       None
*
* [url=home.php?mod=space&uid=266161]@return[/url]      None
*
* [url=home.php?mod=space&uid=1543424]@Details[/url]     ISR to handle PWMB interrupt event
*/
void PWMB_IRQHandler(void)
{
    uint32_t u32PwmIntFlag;

    /* Handle PWMA Timer function */
    u32PwmIntFlag = PWMB->PIIR;

    /* PWMB channel 0 PWM timer interrupt */
    if(u32PwmIntFlag & PWM_PIIR_PWMIF0_Msk)
    {
        PWMB->PIIR   =PWM_PIIR_PWMIF0_Msk;
        pwm_wave1();
    }
     if(u32PwmIntFlag & PWM_PIIR_PWMIF2_Msk)
    {
        PWMB->PIIR  =PWM_PIIR_PWMIF2_Msk;
        pwm_wave2();
    }
    if(u32PwmIntFlag & PWM_PIIR_PWMIF1_Msk)
    {
        PWMB->PIIR  =PWM_PIIR_PWMIF1_Msk;
        pwm_wave3();
    }

    if(u32PwmIntFlag & PWM_PIIR_PWMIF3_Msk)
    {
        PWMB->PIIR  = PWM_PIIR_PWMIF3_Msk;
        pwm_wave4();
    }
   
}

使用特权

评论回复
13
capturesthe| | 2016-7-22 16:13 | 只看该作者
头一次听说PWM也有分辨率,学习知识了
这样的话是不是精度越高,可调范围越大
感觉和adc一样了

使用特权

评论回复
14
yiyigirl2014| | 2016-7-23 21:02 | 只看该作者
没有分辨率一说吧,只是占空比宽度而已。

使用特权

评论回复
15
zhuotuzi| | 2016-7-23 22:24 | 只看该作者
原来如此,多逛逛还是可以学到东西的

使用特权

评论回复
16
天灵灵地灵灵| | 2016-7-23 23:06 | 只看该作者
如果定时器是32位的就可以更大了。

使用特权

评论回复
17
Harvard|  楼主 | 2016-7-24 22:02 | 只看该作者
是的  不知道有没有更加好的方法 来扩展成32bit

使用特权

评论回复
18
gregoryw| | 2016-7-24 22:05 | 只看该作者
原来如此,多逛逛还是可以学到东西

使用特权

评论回复
19
zhuotuzi| | 2016-7-25 20:47 | 只看该作者
搞太多也没有太多意义。

使用特权

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

本版积分规则

个人签名:单片机工作者

74

主题

1729

帖子

21

粉丝