Previous Page
    /******************************************************************************
    * PWM.c
    *
    * Description: This source file allows the Kinetis K02 to use the on chip
    *              Flex Timers as center aligned PWM outputs.
    *
    * Controller: Kinetis MK02F12810
    *
    * Spencer Black April 7, 2015
    *******************************************************************************
    * Master Include File
    ******************************************************************************/
    #include "includes.h"
    /******************************************************************************
    * PWM Port Defines
    ******************************************************************************/
    //Flex Timer macro to define startup PWM signal
    #define FTM_MOD_VAL()      ((BUS_CLOCK/2)/OVERFLOW_FREQ)

    /******************************************************************************
    * PWM Defines
    ******************************************************************************/
    #define CLK_SOURCE      0x01      //clock source bit (system clock = 0x01)

    //Values for the Flex Time macro 'FTMx_MOD()'
    #define BUS_CLOCK      40000000   //System frequency for Flex Timers
    #define OVERFLOW_FREQ  25000

    /******************************************************************************
    * Public Function prototypes
    ******************************************************************************/
    void PWM_Init(void);
    void PWM_Set_Duty_Cycle(INT8U chan,INT8U dutycycle);
    void PWM_Disable(INT8U disftmchan);
    void PWM_Enable(INT8U enftmchan);

    /******************************************************************************
    * PWM_Init(void)
    *
    * Description: Sets up the Flex Timer channels as center aligned PWM outputs on
    *              the Kinetis K02.
    *
    * Parameters: None
    ******************************************************************************/
    void PWM_Init(void){
        //Initialize Flex Timer Clocks
        SIM_SCGC6   |= (SIM_SCGC6_FTM0_MASK | SIM_SCGC6_FTM1_MASK |
                        SIM_SCGC6_FTM2_MASK);

        PORTA_PCR4  = PORT_PCR_MUX(3); //Alt setting for FTM0_CH1
        PORTA_PCR5  = PORT_PCR_MUX(3); //Alt setting for FTM0_CH2
        PORTA_PCR12 = PORT_PCR_MUX(3); //Alt setting for FTM1_CH0
        PORTA_PCR13 = PORT_PCR_MUX(3); //Alt setting for FTM1_CH1
        PORTB_PCR18 = PORT_PCR_MUX(3); //Alt setting for FTM2_CH0
        PORTB_PCR19 = PORT_PCR_MUX(3); //Alt setting for FTM2_CH1

        //Disable write protection which enables changes to the clock source
        FTM0_MODE   |= FTM_MODE_WPDIS_MASK;
        FTM1_MODE   |= FTM_MODE_WPDIS_MASK;
        FTM2_MODE   |= FTM_MODE_WPDIS_MASK;

        //Ensure free running clock and PWM by disabling QUADEN and DECAPEN
        FTM0_MODE   &= ~(FTM_MODE_FTMEN_MASK & FTM_QDCTRL_QUADEN_MASK);
        FTM1_MODE   &= ~(FTM_MODE_FTMEN_MASK & FTM_QDCTRL_QUADEN_MASK);
        FTM2_MODE   &= ~(FTM_MODE_FTMEN_MASK & FTM_QDCTRL_QUADEN_MASK);

        //Reset CNT before MOD to avoid confusion on first TOF
        FTM0_CNT    = 0;
        FTM1_CNT    = 0;
        FTM2_CNT    = 0;

        //Sets the counter value to 800 (1/40us = 25kHz)
        FTM0_MOD    = FTM_MOD_VAL();
        FTM1_MOD    = FTM_MOD_VAL();
        FTM2_MOD    = FTM_MOD_VAL();

        //Update CNT register with starting value of 0
        FTM0_CNTIN  = 0;
        FTM1_CNTIN  = 0;
        FTM2_CNTIN  = 0;

        //edge level select, falling edge with high true pulses
        FTM0_C1SC |= FTM_CnSC_ELSB_MASK;
        FTM0_C1SC &= ~FTM_CnSC_ELSA_MASK;

        FTM0_C2SC |= FTM_CnSC_ELSB_MASK;
        FTM0_C2SC &= ~FTM_CnSC_ELSA_MASK;

        FTM1_C0SC |= FTM_CnSC_ELSB_MASK;
        FTM1_C0SC &= ~FTM_CnSC_ELSA_MASK;

        FTM1_C1SC |= FTM_CnSC_ELSB_MASK;
        FTM1_C1SC &= ~FTM_CnSC_ELSA_MASK;

        FTM2_C0SC |= FTM_CnSC_ELSB_MASK;
        FTM2_C0SC &= ~FTM_CnSC_ELSA_MASK;

        FTM2_C1SC |= FTM_CnSC_ELSB_MASK;
        FTM2_C1SC &= ~FTM_CnSC_ELSA_MASK;

        //Enables clock source 40MHz
        //Enables center aligned PWM up-down counting
        FTM0_SC   |= (FTM_SC_CLKS(CLK_SOURCE) | FTM_SC_CPWMS_MASK);
        FTM1_SC   |= (FTM_SC_CLKS(CLK_SOURCE) | FTM_SC_CPWMS_MASK);
        FTM2_SC   |= (FTM_SC_CLKS(CLK_SOURCE) | FTM_SC_CPWMS_MASK);

    }

    /******************************************************************************
    * PWM_Set_Duty_Cycle(INT8U channel,INT8U duty)
    *
    * Description: Takes in a channel to write to and a value from 0 to 100 that
    *              will set the % duty cycle for the given channel
    *
    * Parameters: 'channel' = Channel to write to
    *             'duty'    = % duty cycle (0 to 100)
    ******************************************************************************/
    void PWM_Set_Duty_Cycle(INT8U chan,INT8U dutycycle){
        INT8U channel = chan;
        INT8U duty = dutycycle;

        if(channel == 0){
            FTM0_C1V = (FTM0_MOD * duty) / 100;
        }else if(channel == 1){
            FTM0_C2V = (FTM0_MOD * duty) / 100;
        }else if(channel == 2){
            FTM1_C0V = (FTM1_MOD * duty) / 100;
        }else if(channel == 3){
            FTM1_C1V = (FTM1_MOD * duty) / 100;
        }else if(channel == 4){
            FTM2_C0V = (FTM2_MOD * duty) / 100;
        }else if(channel == 5){
            FTM2_C1V = (FTM2_MOD * duty) / 100;
        }else{
            //Do nothing
        }
    }

    /******************************************************************************
    * PWM_Enable(INT8U channel,INT8U duty)
    *
    * Description: Turns on a Flex Timer channel
    *
    * Parameters: None
    ******************************************************************************/
    void PWM_Enable(INT8U enftmchan){
        INT8U enable = enftmchan;

        if(enable == 0){
            FTM0_SC |= FTM_SC_CLKS(CLK_SOURCE);
        }else if(enable == 1){
            FTM1_SC |= FTM_SC_CLKS(CLK_SOURCE);
        }else if(enable == 2){
            FTM2_SC |= FTM_SC_CLKS(CLK_SOURCE);
        }else{
            //Do Nothing
        }
    }

    /******************************************************************************
    * PWM_Disable(INT8U disftmchan)
    *
    * Description: Turns off a Flex Timer channel
    *
    * Parameters: disftmchan is the FTM channel to disable
    ******************************************************************************/
    void PWM_Disable(INT8U disftmchan){
        INT8U disable = disftmchan;

        if(disable == 0){
            FTM0_SC &= ~FTM_SC_CLKS(CLK_SOURCE);
        }else if(disable == 1){
            FTM1_SC &= ~FTM_SC_CLKS(CLK_SOURCE);
        }else if(disable == 2){
            FTM2_SC &= ~FTM_SC_CLKS(CLK_SOURCE);
        }else{
            //Do Nothing
        }
    }
    

Previous Page