|
楼主 |
发表于 2012-11-21 22:03:53
|
显示全部楼层
,你们都说简单,可我比较菜啊,谁能说说思路啊?我发现了一个飞思卡尔的单片机程序是用定时器模拟的pwm不知道怎么样,程序我贴一下不知道篇幅够不够。
#include <hidef.h> /* common defines and macros */
#include <MC9S12XEP100.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xep100"
#define ECT_OC7D_OC7D4_MASK 16 // ??? not defined in library in CW 4.7 ???
//******************************************************************************
// This software is classified as Engineering Sample Software.
//******************************************************************************
// - OSCILLATOR = 16MHz
// - BUS CLOCK = 25 MHz
// - the sample software does:
// - It generates periodic signal on the port PT4 with variable frequency and stop and start feature
//
//******************************************************************************
// DEFINITIONS
//******************************************************************************
#define UBYTE unsigned char
#define SBYTE char
#define UWORD unsigned int
#define SWORD int
#define ULONG unsigned long
#define SLONG long
//******************************************************************************
// FUNCTION PROTOTYPES
//******************************************************************************
#define BUSCLK 25000 // [kHz]
//******************************************************************************
// FUNCTION PROTOTYPES
//******************************************************************************
static void PLL_Init(UBYTE synr, UBYTE refdv, UBYTE postdiv);
void TimerSetup(void);
void startOutputSignal_on_PT4(void);
void stopOutputSignal_on_PT4(void);
void permanent_1_on_PT4(void);
void changePeriod(ULONG per_us); // input parameter = required period in us
void changeDuty(UWORD duty); // duty cycle = 0~period (period is calculated global variable)
// IOW it is value of period register TC7
//******************************************************************************
static UWORD period;
//******************************************************************************
// void main(void)
//******************************************************************************
void main(void)
{
ULONG i;
UWORD j;
//----------------------------------------
ECLKCTL_NECLK = 0; // see bus clock on PE4
//----------------------------------------
// set 25MHz bus clock from 16MHz OSCCLK // PLL_Init(SYNR;REFDV;POSTDIV)
PLL_Init(0xD8,0x07,0x01);
//----------------------------------------
// - The 1 MHz frequency is generated by means of Main Timer counter in the underflow interrupt by toggling required port.
// Generated on the port PT4.
TimerSetup();
//----------------------------------------
startOutputSignal_on_PT4();
for(;;)
{
changePeriod(10000); //10ms
changeDuty(period/2);
for(i=0;i<0x1FFFFF;i++) asm nop; // SW delay
stopOutputSignal_on_PT4();
for(i=0;i<0x1FFFFF;i++) asm nop; // SW delay
startOutputSignal_on_PT4();
for(i=0;i<0x1FFFFF;i++) asm nop; // SW delay
permanent_1_on_PT4();
for(i=0;i<0x1FFFFF;i++) asm nop; // SW delay
changePeriod(4000); //4ms
startOutputSignal_on_PT4();
for(j=0;j<=period;j++)
{
changeDuty(j);
for(i=0;i<0x3FF;i++) asm nop; // SW delay
}
for(i=0;i<0x1FFFFF;i++) asm nop; // SW delay
}
}
//******************************************************************************
// void changePeriod(ULONG period)
//******************************************************************************
// timer frequency = BUSCLK/(TC7+1)/prescaler=BUSCLK/(TC7+1)/16
// 50% duty cycle; = (TC7-1)/2
void changePeriod(ULONG per_us) //[us]; (1.28us < period < 41942.4us) for 25MHz busclk and tim prsclr=16 (see TSCR2 setup)
{ // max err in the setup is (TC7min+1)*16/busclk=(0+1)*16/25000000=640ns
ULONG per;
per = per_us*BUSCLK/1000/16-1;
ECT_TC7 = (UWORD) per;
period = (UWORD) per;
}
//******************************************************************************
// void changeDuty(UWORD duty)
//******************************************************************************
void changeDuty(UWORD duty) //[us]; (1.28us < period < 41942.4us) for 25MHz busclk and tim prsclr=16
{ // max error in the setup is (TC7min+1)*16/busclk=(0+1)*16/25000000=640ns
if(duty>period) duty=period;
ECT_TC4 = duty;
}
//******************************************************************************
// void permanent_1_on_PT4(void)
//******************************************************************************
void permanent_1_on_PT4(void)
{
ECT_TCTL1 |= ECT_TCTL1_OM4_MASK | ECT_TCTL1_OL4_MASK; // channel 4 - PT4 - set output on compare, channels 0,2,3 disconnected from output pin logic
ECT_OC7D |= ECT_OC7D_OC7D4_MASK; // set PT4 on PT7 compare
}
//******************************************************************************
// void startOutputSignal(void)
//******************************************************************************
void startOutputSignal_on_PT4(void)
{
// see description of stopOutputSignal
ECT_TCTL1 &= (~(ECT_TCTL1_OM4_MASK | ECT_TCTL1_OL4_MASK)); // clear bits of channel PT4
ECT_TCTL1 |= ECT_TCTL1_OM4_MASK; // channel 4 - PT4 - clear output on compare, channels 0,2,3 disconnected from output pin logic
ECT_OC7D |= ECT_OC7D_OC7D4_MASK; // set PT4 on PT7 compare
}
//******************************************************************************
// void stopOutputSignal(void)
//******************************************************************************
void stopOutputSignal_on_PT4(void) // log 0 on PT4
{ // do not use OMn,OLn bit combination "Disconnected from output pin logic"
// because in the case of PT7 is used as a period generator then this option does not
// work. - Not documented erratum - I discovered it 3 weeks ago. The bug is in solution.
// The solution can be done by correct signal setup. Because, on the TC7 compare bit OC7D bit n says
// "set corresponding channel n to 1 on TC7 compare" and the channel n compare action is clear on compare
// then it is enough to change OC7D bit n to 0 => clear corresponding bit of channel n on TC7 compare.
ECT_TCTL1 &= (~(ECT_TCTL1_OM4_MASK | ECT_TCTL1_OL4_MASK)); // channel 4 - PT4 - clear output on compare, channels 0,2,3 disconnected from output pin logic
ECT_OC7D &= (~ECT_OC7D_OC7D4_MASK); // clear PT4 on PT7 compare
}
//******************************************************************************
// static void TimerSetup(void)
//******************************************************************************
void TimerSetup(void)
{
//--- channel 0-7 setup -------------------
ECT_TCTL1 = 0x01; // channels 7-5 disconnected from output pin logic
ECT_TIOS = 0x90; // channel 7,4 - PT4 - output compare
ECT_OC7M = ECT_OC7M_OC7M4_MASK; // channel 4 - PT4 - is an output port for channel 7 compare
//-----------------------------------------
changePeriod(10000); // [us]; (1.28us < period < 41942.4us) for 25MHz busclk and tim prsclr=16
changeDuty(period/2); // 50% duty cycle
stopOutputSignal_on_PT4(); // channel 4 - PT4 - set PT4 on PT7 compare =>left aligned PWM
ECT_TSCR2 = 0x0C; // prescaler =16,reset tim by a output compare of channel 7
// ovf int disable
//-----------------------------------------
ECT_TSCR1 = 0xF0; // enable timer,stop in wait,stop in freeze, fast flag clear
}
//******************************************************************************
// static void PLL_Init(UBYTE syn, UBYTE refdv)
//******************************************************************************
static void PLL_Init(UBYTE synr, UBYTE refdv, UBYTE postdiv)
{
PLLCTL_PLLON = 0; // Disable the Phase Lock Loop
CLKSEL_PLLSEL = 0; // Select clock source from OSCCLK
CLKSEL_PLLWAI = 1; // PLL stops in wait mode
SYNR = synr;
REFDV = refdv;
POSTDIV = postdiv;
PLLCTL_PLLON = 1; // Enable the Phase Lock Loop
while(!CRGFLG_LOCK); // Wait till the PLL VCO is within tolerance
CLKSEL_PLLSEL = 1; // Select clock source from PLLCLK
}
//******************************************************************************
// Services performed by FREESCALE in this matter are performed AS IS and without any warranty. CUSTOMER retains
// the final decision relative to the total design and functionality of the end product. FREESCALE neither
// guarantees nor will be held liable by CUSTOMER for the success of this project.
// FREESCALE DISCLAIMS ALL WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY INCLUDING, BUT NOT LIMITED TO, IMPLIED
// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ON ANY HARDWARE, SOFTWARE ORE ADVISE SUPPLIED
// TO THE PROJECT BY FREESCALE, AND OR NAY PRODUCT RESULTING FROM FREESCALE SERVICES . IN NO EVENT SHALL FREESCALE
// BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT.
//
// CUSTOMER agrees to hold FREESCALE harmless against any and all claims demands or actions by anyone on account of
// any damage, or injury, whether commercial, contractual, or tortuous, rising directly or indirectly as a result of
// the advise or assistance supplied CUSTOMER in connection with product, services or goods supplied under this Agreement.
//******************************************************************************
|
|