freetech

kinetis的FTM例程——联合PWM

0
阅读(4286)

在电机控制、逆变电源等应用中常会用到半桥,半桥的上、下管PWM需要相同或互补的PWM来驱动。PWM的联合模式刚好适合此类应用。下面介绍相关寄存器:

FTMx_COMBINE - 联合模式寄存器,每8位控制一组PWM,要使PWM工作在联合模式,相应的COMBINE要置1。需要说明的是当工作在联合模式时,占空比为(Cn+1V-Cn+1)/(MOD-INT)

FTMx_DEADTIME - 死区时间设置,第6~7位设置系统时钟分频,第0~5位是设置延时分频后的时钟个数。当FTMx_COMBINE中的DTEN为1时,对FTMx_DEADTIME的设置才有效。该寄存器为受保护寄存器,当FTMx_MODE中的WPDIS为1时才可以写。

FTMx_OUTMASK - 输出掩码寄存器,低8位对应8路PWM,当相应的位为1时,PWM将不输出,而输出的是FTMx_OUTINIT对应的值。

FTMx_OUTINIT - 初值寄存器,初始化过程中输出的值。当某通道被掩码时也输出该值。

FTMx_POL - 极性控制位,低8位对应8路PWM,当相应的位为0时,PWM高有效;当相应的位为1时,PWM低有效。

下面的例子在实现跑马灯基础上,实现2路联合PWM输出:

/*
* main implementation: use this 'C' sample to create your own application
*
*/

#define GPIO_PIN_MASK            0x3C000000
#define GPIO_PIN(x)                ((1<<x)&GPIO_PIN_MASK)

#include <stdio.h>
#include "derivative.h" /* include peripheral declarations */

void delay()
{
    int i =0;
    int j=0;
    for(i=0;i<3000;i++)
      for(j=0;j<1000;j++)
          asm("nop");
}
void GPIO_Init()
{
    SIM_SCGC5 = SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
    /* Set GPIOA pin26~29 as GPIO*/
    PORTA_PCR26=(PORT_PCR_MUX(1));
    PORTA_PCR27=(PORT_PCR_MUX(1));
    PORTA_PCR28=(PORT_PCR_MUX(1));
    PORTA_PCR29=(PORT_PCR_MUX(1));
    PORTA_PCR5=(PORT_PCR_MUX(3));
    PORTA_PCR6=(PORT_PCR_MUX(3));
    PORTA_PCR7=(PORT_PCR_MUX(3));
    //set GPIOA pin26~29 to be output
    GPIOA_PDDR=GPIO_PDDR_PDD(GPIO_PIN(26))
         | GPIO_PDDR_PDD(GPIO_PIN(27))
         | GPIO_PDDR_PDD(GPIO_PIN(28))
         | GPIO_PDDR_PDD(GPIO_PIN(29))
         | GPIO_PDDR_PDD(GPIO_PIN(5))
         | GPIO_PDDR_PDD(GPIO_PIN(6))
         | GPIO_PDDR_PDD(GPIO_PIN(7));
    GPIOA_PDOR = 0;//所有LED灭
}
void FTM0_Init()
{
    SIM_SCGC6 |= 0x01000000;
    FTM0_MODE = 0x05;
    FTM0_SC = 0x00;   
    FTM0_C2SC = 0x28;    //PWM模式,匹配时产生中断
    FTM0_C2V = 10000;   
    FTM0_C3SC = 0x28;    //PWM模式,不产生中断
    FTM0_C3V = 30000;

    FTM0_COMBINE = (1<<8);
        
    FTM0_CNTIN = 0;//初值值0
    FTM0_CNT = 0;//计数值0
    FTM0_MOD = 50000;//模50000
    FTM0_CONF = 31;
    FTM0_SC = 0x4A;//系统时钟,4分频
    NVICISER1 |= (uint32_t)0x40000000;//使能中断NVICISERn=m,其中n=62/32,m=62%32
}
int main(void)
{
    static int counter = 26;
    FTM0_Init();
    GPIO_Init();
    printf("Hello (Kinetis) World in 'C' from PK60X256 derivative! \n\r");
    for(;;)
    {

    }
    return 0;
}
void FTM0_Interrupt(void)
{
    unsigned int tmp;
    static int counter = 26;

    tmp = FTM0_SC;
    if( (tmp&0x80) !=0)
    {
        FTM0_SC &= ~0x80;
    }
    tmp = FTM0_C2SC;
    if( (tmp&0x80)!=0 )
    {
        FTM0_C2SC &= ~0x80;
    }
    GPIOA_PDOR = GPIO_PDOR_PDO(GPIO_PIN(counter));
    counter++;
    if(counter > 29)
    {
        counter = 26;
    }
}

效果如下图所示:

image

周期为FTM0_MOD - FTM0_CNTIN的值50000,高电平时间为FTM0_C3V - FTM0_C2V 的值20000。