pwm_sample.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 247 行

C
247
字号
/**********************************************************************************/
/*                                                                                */
/*    Copyright (C) 2005 Oki Electric Industry Co., LTD.                          */
/*                                                                                */
/*    System Name    :  ML674051/ML674061                                         */
/*    Module Name    :  PWM sample program                                        */
/*    File   Name    :  pwm_sample.c                                              */
/*    Revision       :  01.00                                                     */
/*    Date           :  2002/02/21 initial version                                */
/*                                                                                */
/**********************************************************************************/
#include "ML674061.h"
#include "common.h"
#include "irq.h"

#ifdef __IAR__
#include "intrinsics.h"
#endif

/*

     PWM0 (Ds=10, De=100)

 duty(%)
   |       250      500
   +--------+--------+------------>n(cycle)
   |
   |   1cycle=10ms
   |     ->||<-
 De+ - - -_--_
   |    _-    -_          _-
   |  _-        -_      _-
   |_-            -_  _-
 Ds+                --
   |
  0+--------+--------+------------>time(ms)
   0       2500     5000


     PWM1 (Ds=100, De=10)

 duty(%)
   |       250      500
   +--------+--------+------------>n(cycle)
   |
   |           1cycle=10ms
   |              ->||<-
 Ds+_              _--_
   | -_          _-    -_
   |   -_      _-        -_
   |     -_  _-            -_
 De+ - - - --
   |
  0+--------+--------+------------>time(ms)
   0       2500     5000

*/

/* constants */
#define MHz     (1000000L)
#define SYSCLK	(33)			/* SYSCLK (MHz)*/
#define PWMCYC (10)    		/* frequency of PWM (msec) */
#define VALUE_OF_FTMnR          /* reload value of timer */\
                (65536 - (PWMCYC * SYSCLK * 1000) / 16)

#define DUTY(n, Ds, De) /* duty(%) n,Ds,De:show above figure */ \
    (((((long)(De))-(Ds))*(n)+(Ds)*((CYCLE)/2-1))/((CYCLE)/2-1))

#define VALUE_OF_FTMnGR(duty)  /* value of PWR duty:duty(%) */ \
    (((65536-(VALUE_OF_FTMnR))*(duty)+(VALUE_OF_FTMnR)*100)/100)

#define CYCLE   500

/* check VALUE_OF_PWCY */
#if (VALUE_OF_FTMnR < 0 || 0x10000 <= VALUE_OF_FTMnR)
#error Invalid value : VALUE_OF_FTMnR
#endif

/* functions */
int main(void);                     /* main routine */
static void reg_irq_handler(void);  /* registration of IRQ handler */
static void set_pwm(void);          /* setup PWM */
static void pwm0_handler(void);     /* PWM0 handler */
static void pwm1_handler(void);     /* PWM1 handler */

/* global variables */
UHWORD value_of_pwr0[CYCLE];
UHWORD value_of_pwr1[CYCLE];

/****************************************************************************/
/*  Entry point                                                             */
/*  Function : main                                                         */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   0                                                   */
/****************************************************************************/
int main(void)
{
    /* initialize IRQ */
    init_irq();

    /* registration of IRQ handler */
    reg_irq_handler();

    /* light LED */
    put_value(PM3, 0x18);    /* PD4-3 output mode */
    put_value(PM5, 0x3F);    /* PF5-0 output mode */

    /* setup TIMER */
    set_pwm();

    /* enable IRQ */
#ifdef __IAR__
      __enable_interrupt();
#else
    irq_en();
#endif


    /* start pwm */
    set_hbit(FTMEN, 0x3);	/* start PWM0, PWM1 */

    /* infinite loop */
    for(;;)
        ;

//    return 0;
}

/****************************************************************************/
/*  Registration of IRQ Handler                                             */
/*  Function : reg_irq_handler                                              */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/****************************************************************************/
void reg_irq_handler(void)
{
    /* register IRQ handlers into IRQ handler table */
    IRQ_HANDLER_TABLE[INT_TIMER0] = pwm0_handler;
    IRQ_HANDLER_TABLE[INT_TIMER1] = pwm1_handler;

    /* setup interrupt level */
    set_wbit(EXILCA, ILC_ILC16 & ILC_INT_LV1); /* PWM0(nIR[16]) PWM1(nIR[17]) -> level1 */

    return;
}

/****************************************************************************/
/*  setup of PWM                                                            */
/*  Function : set_pwm                                                      */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/****************************************************************************/
void set_pwm(void)
{
    int i;

    /* PF0,PF1 secondary function */
    set_wbit(PORTSEL3, 0x50000) ;	

	/* set FTM0, FTM1 to PWM mode */
	put_hvalue(FTM0CON, 0x10) ;
	put_hvalue(FTM1CON, 0x10) ;

    /* PWM interrupt clear */
    set_hbit(FTM0ST, 0x2) ;
    set_hbit(FTM1ST, 0x2) ;

    /* stop PWM */
    set_hbit(FTMDIS, 0x3) ;

    /* calculate duty value */
    for(i=0; i<(CYCLE/2); i++){
        value_of_pwr0[i] = value_of_pwr0[(CYCLE)-1-i]
            = (UHWORD)VALUE_OF_FTMnGR(DUTY(i, 10, 100));
        value_of_pwr1[i] = value_of_pwr1[(CYCLE)-1-i]
            = (UHWORD)VALUE_OF_FTMnGR(DUTY(i, 100, 10));
    }

    /* set duty value */
    put_hvalue(FTM0GR, value_of_pwr0[0]);
    put_hvalue(FTM1GR, value_of_pwr1[0]);

    /* setup cycle */
    put_hvalue(FTM0R, (UHWORD)VALUE_OF_FTMnR);
    put_hvalue(FTM1R, (UHWORD)VALUE_OF_FTMnR);

    /* setup interrupt couse and clock */
    put_hvalue(FTM0IOLV, 0x0) ;
    put_hvalue(FTM1IOLV, 0x0) ;

   	put_hvalue(FTM0CON, ((get_hvalue(FTM0CON) | 0x7) & 0xFFFC)) ;	/* APB_CLK/16 */
   	put_hvalue(FTM1CON, ((get_hvalue(FTM1CON) | 0x7) & 0xFFFC)) ;	/* APB_CLK/16 */

	set_hbit(FTM0IER,0x2) ;
	set_hbit(FTM1IER,0x2) ;

    return;
}

/****************************************************************************/
/*  PWM0 handler                                                            */
/*  Function : pwm0_handler                                                 */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/****************************************************************************/
void pwm0_handler(void)
{
    static int index = 0;   /* index of value_of_pwr0[] */

    set_hbit(FTM0ST, 0x2); /* clear PWM0 interrupt */

    /* re-set duty value */
    put_hvalue(FTM0GR, value_of_pwr0[index]);
    index++;
    if(index >= CYCLE)
        index = 0;

    return;
}

/****************************************************************************/
/*  PWM1 handler                                                            */
/*  Function : pwm1_handler                                                 */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/****************************************************************************/
void pwm1_handler(void)
{
    static int index = 0;   /* index of value_of_pwr1[] */

    set_hbit(FTM1ST, 0x2); /* clear PWM1 interrupt */

    /* re-set duty value */
    put_hvalue(FTM1GR, value_of_pwr1[index]);
    index++;
    if(index >= CYCLE)
        index = 0;

    return;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?