freetech

HCS08单片机PWM功能非正常使用方法的研究

0
阅读(3822)

昨天一客户提出要让PWM周期结束前强制改变占空比,比如当20%占空比的波形进行到50%时,突然想将该引脚置高电平或低电平,并维持0占空比或满占空比。使用中发现状态不可控,达不到他想要的目的。我做实验进行了分析,请看下面代码:

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#define  PWM_ON    { TPM2C0SC=0x28,TPM2SC=0x16;}  //方波启动 TPM2SC=0x16 is 4uS/conter
#define  PWM_OFF   { TPM2SC=0x00,TPM2CNT=0x0,TPM2C0SC=0x00;}   //方波停止 
#define  PWM_SET(Tpulse,clyle) {TPM2C0V=Tpulse,TPM2MOD=clyle;  }
unsigned int PWMDUTY;

//=================================================================================================
//函数名:Init_tpm1_counter
//作用:初始化TPM1,内部时钟工作于自时钟模式,总线频率4M;自由计数;溢出时间间隔=8000/4000近似2ms
//=================================================================================================
void Init_tpm1_counter(void)
{
    TPM1SC=0x48;//TPM1时钟源为总线时钟;分频系数为1;溢出中断允许
    TPM1MOD = 8000 - 1;
    TPM1CNTH=0;//任意时刻对TPM1CNTH或TPM1CNTL的写操作将计数寄存器的计数值复位(清零)
}

void TPM2_init(void)   //PWM OUTPUT ,TPM2-TH0为硬件比较输出  PTF4  顺序,需要先启动后设置,否则设置无效
{
  PWM_OFF;                   //PWM-STEP1
  PWM_ON;                    //PWM-STEP2
  PWMDUTY=0x0000;            // PTF4 LOW-LEVEL TIME
}

void main(void) {

  EnableInterrupts; /* enable interrupts */
  /* include your code here */
  Init_tpm1_counter();
  PTFDD_PTFDD0 = 1;
              PTFDD_PTFDD4 = 1;
  TPM2_init();

  for(;;) {
    __RESET_WATCHDOG(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}

上面的定时器1专门用来产生翻转状态的时刻,定时器2用来产生PWM波形。采用4种状态轮流切换的方式,即“50%占空比->低电平->->高电平->50%占空比”以便观察。下面用3种方法的现象来对比其可行性,绿线(PTFD0)翻转表示状态切换,黄线(PTFD4,PWM波)是PWM波形引脚。

一、简单切换占空比,中断程序如下:

//==================计数器1溢出中断服务程序==========================
interrupt VectorNumber_Vtpm1ovf void TPM1_OVF_ISR(void)
{
  static int cnt=0;
    if((TPM1SC & 0x80)==0x80)
        {
          TPM1SC_TOF=0;
            switch(cnt)
            {             
            case 0:
            case 14:
              PWM_SET(50,100);
              PTFD_PTFD0=~PTFD_PTFD0;
              break;
          case 7:
              PWM_SET(0,100);
              PTFD_PTFD0=~PTFD_PTFD0;
              break;
          case 21:
              PWM_SET(100,100);
             PTFD_PTFD0=~PTFD_PTFD0;
               break;
          case 28:
              cnt = -1;
              break;
            }
            cnt++;
        }
}

image

上面的波形显示,各状态切换都有很大延时。这是因为新状态的生效要等前一次PWM周期结束,在最坏的情况下要延时近一个周期。 

二、设置占空比时停止定时器,之后再开启。

//==================计数器1溢出中断服务程序==========================
interrupt VectorNumber_Vtpm1ovf void TPM1_OVF_ISR(void)
{
  static int cnt=0;
    if((TPM1SC & 0x80)==0x80)
        {
          TPM1SC_TOF=0;
            switch(cnt)
            {             
            case 0:
            case 14:
              PWM_OFF;
              PWM_SET(50,100);
              PWM_ON;
              PTFD_PTFD0=~PTFD_PTFD0;
              break;
          case 7:
              PWM_OFF;
              PWM_SET(0,100);
              PWM_ON;
              PTFD_PTFD0=~PTFD_PTFD0;
              break;
          case 21:
              PWM_OFF;
              PWM_SET(100,100);
              PWM_ON;
             PTFD_PTFD0=~PTFD_PTFD0;
               break;
          case 28:
              cnt = -1;
              break;
            }
            cnt++;
        }
}

image

上面的波形仍存在2个问题:

1、从正常波形到0占空比(完全低电平)有个延时。

2、满占空比(完全高电平)时有毛刺。

三、改用IO口方式实现满占空比

//==================计数器1溢出中断服务程序==========================
interrupt VectorNumber_Vtpm1ovf void TPM1_OVF_ISR(void)
{
  static int cnt=0;
    if((TPM1SC & 0x80)==0x80)
        {
          TPM1SC_TOF=0;
            switch(cnt)
            {             
            case 0:
            case 14:
              PWM_OFF;
              PWM_SET(50,100);
              PWM_ON;
              PTFD_PTFD0=~PTFD_PTFD0;
              break;
          case 7:
              PWM_OFF;
              PTFD_PTFD4 = 0;
              PTFD_PTFD0=~PTFD_PTFD0;
              break;
          case 21:
              PWM_OFF;
              PTFD_PTFD4 = 1;
              PTFD_PTFD0=~PTFD_PTFD0;
               break;
          case 28:
              cnt = -1;
              break;
            }
            cnt++;
        }
}

image

上面的波形很正常了。