logo

CH563评估板PWM的问题很让人头痛

之前曾经发过一贴,我无法正常的产生PWM,但官方一直没有回音。这个双休不死心,又折腾了折腾。结果发现问题更让我迷惑了。首先我仅仅是将之前的代码中中断配置的语句调整了一下次序,将这些代码移到了PWM配置的前面,并且将输出脚PWM2换成了PWM0,就在PB0脚上测到了正确的脉冲。但除了将输出脚配置成PWM0时以外,配置成PWM1、PWM2、PWM3都无法在相应管脚上得到脉冲。先看之前的代码:

#include "CH563SFR.H"
#include "sysfreq.h"

__irq void IRQ_Handler()
{

if(R8_INT_FLAG_0&RB_IF_TMR0)
{
UINT8 i;
i=R8_TMR0_INT_FLAG;
if(i&RB_TMR_IF_DATA_ACT)
{
     R8_TMR0_INT_FLAG |= RB_TMR_IF_DATA_ACT;                                        R8_INT_FLAG_0 |= RB_IF_TMR0; 
}

if(i&RB_TMR_IF_CYC_END)
        {
                    R8_TMR0_INT_FLAG|=RB_TMR_IF_CYC_END;  
                    R8_INT_FLAG_0 |= RB_IF_TMR0;   
                }
}


}

__irq void FIQ_Handler()
{

}

void PWM_Init()
{
R8_PB_DIR_0|=PWM2;
R32_TMR0_FIFO=100000000/2;
R32_TMR0_CNT_END=100000000;
R8_TMR0_CTRL_MOD&=~(RB_TMR_MODE_NRZI|RB_TMR_ALL_CLEAR|RB_TMR_MODE_IN);
R8_TMR0_CTRL_MOD|=(RB_TMR_OUT_EN|RB_TMR_COUNT_EN)
;
R8_TMR0_INTER_EN |=(RB_TMR_IE_CYC_END|RB_TMR_IE_DATA_ACT);

R8_INT_EN_IRQ_0|=RB_IE_IRQ_TMR0;
R8_INT_EN_IRQ_GLOB|=RB_IE_IRQ_GLOB;
}

int main()
{
PWM_Init();

while(1)
{}
}


这个代码无法在PWM2上得到正确的脉冲。但我仅仅将PWM_Init()函数里的语句次序调整了一下,同时将PWM2换成PWM0,就在PB0上得到了正确的脉冲。


void PWM_Init()


{


R8_TMR0_INTER_EN |=(RB_TMR_IE_CYC_END|RB_TMR_IE_DATA_ACT);//仅仅调整了语句次序,先配置了中断,但这与手册里的说明次序是完全相反的。

R8_INT_EN_IRQ_0|=RB_IE_IRQ_TMR0;

R8_INT_EN_IRQ_GLOB|=RB_IE_IRQ_GLOB;

  R8_TMR0_CTRL_MOD&=~(RB_TMR_MODE_NRZI|RB_TMR_ALL_CLEAR|RB_TMR_MODE_IN);


R8_TMR0_CTRL_MOD|=(RB_TMR_OUT_EN|RB_TMR_COUNT_EN) ;

R8_PB_DIR_0|=PWM0;    //在这里将原来的PWM2换成了PWM0

R32_TMR0_FIFO=100000000/2;

R32_TMR0_CNT_END=100000000;


}


上面的代码就可以正常运行了,本来我以为找到了正确的方法,可是问题又来了。当我将PWM0换成其它输出脚时,比如PWM1。程序就又没有反应了,我不能在任何管脚上测到正确的脉冲。神呀,我彻底不知所措了,官方给个准确、详细的说明吧,不然没法玩下去了。



PWM0输出对应引脚是PB0,三路PWM分别是对应的脚输出,你之前出现的问题跟顺序无关。

 

R8_PB_DIR_0|=PWM0;    //在这里将原来的PWM2换成了PWM0

这句话只是将PB0脚方向置为输出而已。

Mail: zfl@wch.cn Web: http://wch.cn Tel: +86-025-52638370 Fax: +86-025-84730778

                           

PWM0输出对应引脚是PB0,三路PWM分别是对应的脚输出,你之前出现的问题跟顺序无关。

 

R8_PB_DIR_0|=PWM0;    //在这里将原来的PWM2换成了PWM0

这句话只是将PB0脚方向置为输出而已。

                       

那我要在PB4上得到脉冲怎么办?R8_PB_DIR_0|=PWM2;这个无效,写成R8_PB_DIR_0=0x10;也无效。只有PWM0有效。R8_PB_DIR_0设为除了PB0以外的管脚都无法得到输出。另外,我不知你们那和情况是什么,反正在我这,顺序就是有关,同样的代码倒个次序就无法得到脉冲。我已经试了很多次。


                           

建议直接联系025-52638371找张工

                       

象这类问题,电话不好沟通的,又看不到代码,说都说不清楚。其实很简单,给一个有效的让除了PB0以外的管脚输出PWM脉冲的例子代码就可以解决问题了。


PWM0脚(PB0)对应的是PWM0,也就是要配置定时器0;

PWM1脚(PB2)对应的是PWM1,也就是要配置定时器1;

以此类推,需要使用哪路PWM则初始化对应的寄存器,不能初始化PWM0而去看其他脚的输出。

 

Mail: zfl@wch.cn Web: http://wch.cn Tel: +86-025-52638370 Fax: +86-025-84730778

                           

PWM0脚(PB0)对应的是PWM0,也就是要配置定时器0;

PWM1脚(PB2)对应的是PWM1,也就是要配置定时器1;

以此类推,需要使用哪路PWM则初始化对应的寄存器,不能初始化PWM0而去看其他脚的输出。

 

                       

手册真的要更新呀,手册里没有任何文字提到PWM输出不能进行管脚切换,事实上很多MCU的PWM输出都是可以进行多管脚切换的,如果不能应该在手册里进行说明。

第二、手册里对PWM寄存器设置的说明要更改,能否正常运行的确与设置顺序有关。手册里的次序:

(1)、设置 PWM 总周期寄存器 R32_TMR_CNT_END,最小值为 1,该寄存器的值必须大于等于

R32_TMR_FIFO 寄存器的值;

(2)、设置数据寄存器 R32_TMR_FIFO,最小值为 0,对应占空比 0%,最大值同 R32_TMR_CNT_END,

对应占空比 100%,支持连续动态数据(DMA),可以模仿出特殊波形;

(3)、将模式设置寄存器(R8_TMRx_CTRL_MOD)中的 RB_TMR_MODE_IN 位清 0,启用 PWM 模式;同时

将 RB_TMR_ALL_CLEAR 位清 0 强制清除 FIFO 和 COUNT;如果需要设置重复次数,则根据需要设置

RB_TMR_PWM_REPEAT 域。如果当前定时器是 TIM0 或 TIM1,则需要将 RB_TMR_MODE_NRZI 位清 0,如果

当前定时器是 TIM3,则需要将 RB_TMR3_MODE_COUNT 位清 0;

(4)、将模式设置寄存器(R8_TMRx_CTRL_MOD)中的 RB_TMR_COUNT_EN 位和 RB_TMR_OUT_EN 位置 1,

开启 PWM 功能;

(5)、将 PWM 对应的的 I/O 引脚设置为输出;

(6)、如果需要启用中断则设置相应的中断使能寄存器位;

(7)、PWM 完成后,如果开启中断则产生相对应的定时器中断,同时通过读取 TMR_INT_FLAG 寄存

器了解 PWM 是否完成以及 PWM 过程中是否产生错误;

按这个次序PWM无法正常运行,步骤(1)(2)应该放在步骤(3)(4)后面PWM模块才能正常执行。我已经测试过多次,这个问题百分百可重现,建议你们做测试进行验证。

CH563的手册显得有些粗糙,用户想完全靠这个手册正常掌握芯片的用法是有困难的,论坛其实是个不错的技术交流平台,象这种简单的问题,两三句话就可以说明白的,却折腾了这么久,不知是我表达不清呢,还是问题太过简单高手不屑认真解释呢?


只有登录才能回复,可以选择微信和github账号登录