📄 basic.c
字号:
/******************************************************************************
* COPYRIGHT (c) MOTOROLA 2003
* FILE NAME: basic.c
*
* PURPOSE: C32 demonstration program for PWM generation using timer module.
*
* DOCUMENTATION SOURCE: EKB Applications
*
* TARGET DEVICE: MC9S12C32
*
* COMPILER: Metrowerks VERSION: MOT_V3.0
*
* AUTHOR: G.More/M.Gallop LOCATION: EKB LAST EDIT DATE: 25/03/03
*
* UPDATE HISTORY
* REV AUTHOR DATE DESCRIPTION OF CHANGE
* --- ------ -------- ---------------------
* 1.0 G.More/M.Gallop 25/03/03 Initial Coding
*
******************************************************************************/
/*===========================================================================*/
/* Motorola reserves the right to make changes without further notice to any */
/* product herein to improve reliability, function, or design. Motorola does */
/* not assume any liability arising out of the application or use of any */
/* product, circuit, or software described herein; neither does it convey */
/* any license under its patent rights nor the rights of others. Motorola */
/* products are not designed, intended, or authorized for use as components */
/* in systems intended for surgical implant into the body, or other */
/* applications intended to support life, or for any other application in */
/* which the failure of the Motorola product could create a situation where */
/* personal injury or death may occur. Should Buyer purchase or use Motorola */
/* products for any such intended or unauthorized application, Buyer shall */
/* indemnify and hold Motorola and its officers, employees, subsidiaries, */
/* affiliates, and distributors harmless against all claims costs, damages, */
/* and expenses, and reasonable attorney fees arising out of, directly or */
/* indirectly, any claim of personal injury or death associated with such */
/* unintended or unauthorized use, even if such claim alleges that Motorola */
/* was negligent regarding the design or manufacture of the part. Motorola */
/* and the Motorola logo* are registered trademarks of Motorola Ltd. */
/*****************************************************************************/
#define BUSCLOCK 16000000L /* use care! this value is used to calibrate PWM */
#define TIMERPRESCALER 4
/* include files */
#include "basic.h"
/* global variables */
unsigned int Period[4] = 0, Mark[4] = 0, Space[4] = 0;
/******************************************************************************
Function Name : main
Engineer : G.More / M.Gallop
Date : 25/03/03
Parameters : NONE
Returns : NONE
Notes : main routine
******************************************************************************/
void
main(void)
{
SetPLL(2,2); /* configures bus clock at 16MHz using PLL */
ConfigureTimer(); /* calls timer setup routine */
ConfigureChannel(0,25,100); /* channel 0 = 100Hz PWM / 25% duty cycle */
ConfigureChannel(1,30,200); /* channel 1 = 200Hz PWM / 30% duty cycle */
ConfigureChannel(2,75,1000); /* channel 2 = 1kHz PWM / 75% duty cycle */
ConfigureChannel(3,90,10000); /* channel 3 = 10kHz PWM / 90% duty cycle */
EnableInterrupts; /* clear CCR interrupt mask */
while(1) /* forever loop */
{
}
}
/******************************************************************************
Function Name : ConfigureChannels
Engineer : G.More / M.Gallop
Date : 25/03/03
Parameters : dutyCycle (percentage), frequency (Hz), channel
Returns :
Notes : beware of frequency limitations in relation to BUSCLOCK and
TIMERPRESCALER value (may overflow 16-bit variable). In this
case the minimum frequency of PWM is 62Hz. No error checking
is implemented in this function.
******************************************************************************/
void ConfigureChannel (tU08 channel, tU08 dutyCycle, tU16 frequency)
{
Period[channel] = (tU16)((BUSCLOCK / TIMERPRESCALER) / frequency);
Mark[channel] = ((Period[channel] / 100) * dutyCycle);
Space[channel] = (Period[channel] - Mark[channel]);
}
/******************************************************************************
Function Name : SetPLL
Engineer : A.McKechan / G.More / C.Culshaw
Date : 31/5/00
Parameters : multiplier, divider
Returns : NONE
******************************************************************************/
void SetPLL(tU08 multiplier, tU08 divider)
{
Crg.clksel.bit.pllsel = 0;
if(!multiplier && !divider) /* if multiplier and divider are 0 */
{
Crg.synr.byte = 0; /* set synr (multiplier) to 0 */
Crg.refdv.byte = 0; /* set refdv (divider) to 0 */
Crg.pllctl.bit.pllon = 0; /* turn PLL off */
}
else
{
Crg.pllctl.bit.pllon = 1; /* turn on the PLL */
Crg.synr.byte = multiplier-1; /* set synr (multiplier) */
Crg.refdv.byte = divider-1; /* set refdv (divider) */
while(!Crg.crgflg.bit.lock) /* wait for PLL to lock */
{
}
Crg.clksel.bit.pllsel = 1; /* select the PLL as the bus clock */
}
}
/******************************************************************************
Function Name : ConfigureTimer
Engineer : G.More / M.Gallop
Date : 25/03/03
Parameters : NONE
Returns : NONE
Notes : sets up the timer for four channels of PWM output.
******************************************************************************/
void
ConfigureTimer(void)
{
Timer.tios.byte = (IOS0|IOS1|IOS2|IOS3); /* set four channels as output compare */
Timer.tctl2.byte = (OM0|OM1|OM2|OM3); /* set mode to follow output level bits */
Timer.tie.byte = (C0I|C1I|C2I|C3I); /* enable interrupts on four pins */
Timer.tscr2.byte = (PR1); /* set the prescaler to 4 - use care! */
Timer.tscr1.byte = (TIE|TFFCA); /* enable timer and set fast flags clear all */
}
/*****************************************************************************/
/* Start of interrupt service routines */
/* placed into non-banked memory segment as vectors are only 2 bytes */
#pragma CODE_SEG NON_BANKED
/******************************************************************************
Function Name : _TimerCompare0ISR
Engineer : G.More / M.Gallop
Date : 25/03/03
Parameters : NONE
Returns : NONE
******************************************************************************/
#pragma TRAP_PROC
void
_TimerCompare0ISR(void)
{
if (Timer.tctl2.bit.ol0 == 1) /* if channel is set to generate rising edge */
{
Timer.tc[0].word += Mark[0]; /* set up timer compare for mark time */
Timer.tctl2.bit.ol0 = 0; /* set pin action to falling edge */
}
else
{
Timer.tc[0].word += Space[0]; /* set up timer compare for space time */
Timer.tctl2.bit.ol0 = 1; /* set pin action to rising edge */
}
}
/******************************************************************************
Function Name : _TimerCompare1ISR
Engineer : G.More / M.Gallop
Date : 25/03/03
Parameters : NONE
Returns : NONE
******************************************************************************/
#pragma TRAP_PROC
void
_TimerCompare1ISR(void)
{
if (Timer.tctl2.bit.ol1 == 1) /* if channel is set to generate rising edge */
{
Timer.tc[1].word += Mark[1]; /* set up timer compare for mark time */
Timer.tctl2.bit.ol1 = 0; /* set pin action to falling edge */
}
else
{
Timer.tc[1].word += Space[1]; /* set up timer compare for space time */
Timer.tctl2.bit.ol1 = 1; /* set pin action to rising edge */
}
}
/******************************************************************************
Function Name : _TimerCompare2ISR
Engineer : G.More / M.Gallop
Date : 25/03/03
Parameters : NONE
Returns : NONE
******************************************************************************/
#pragma TRAP_PROC
void
_TimerCompare2ISR(void)
{
if (Timer.tctl2.bit.ol2 == 1) /* if channel is set to generate rising edge */
{
Timer.tc[2].word += Mark[2]; /* set up timer compare for mark time */
Timer.tctl2.bit.ol2 = 0; /* set pin action to falling edge */
}
else
{
Timer.tc[2].word += Space[2]; /* set up timer compare for space time */
Timer.tctl2.bit.ol2 = 1; /* set pin action to rising edge */
}
}
/******************************************************************************
Function Name : _TimerCompare3ISR
Engineer : G.More / M.Gallop
Date : 25/03/03
Parameters : NONE
Returns : NONE
******************************************************************************/
#pragma TRAP_PROC
void
_TimerCompare3ISR(void)
{
if (Timer.tctl2.bit.ol3 == 1) /* if channel is set to generate rising edge */
{
Timer.tc[3].word += Mark[3]; /* set up timer compare for mark time */
Timer.tctl2.bit.ol3 = 0; /* set pin action to falling edge */
}
else
{
Timer.tc[3].word += Space[3]; /* set up timer compare for space time */
Timer.tctl2.bit.ol3 = 1; /* set pin action to rising edge */
}
}
/******************************************************************************
Function Name : _dummyISR
Engineer : M.Gallop
Date : 25/07/01
Parameters : NONE
Returns : NONE
Notes : interrupt service routine for unused interrupt vectors.
******************************************************************************/
#pragma TRAP_PROC
void
_dummyISR( void )
{
while(1) /* endless loop */
{;
}
}
/* End of interrupt service routines */
/* reset code segment to default */
#pragma CODE_SEG DEFAULT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -