本帖最后由 jiaduo 于 2015-1-27 13:45 编辑
看datasheet说内部的irc48mhz晶振精度在1%,但是我实际使用中,使用IRC48M做TPM0时钟源,输出PWM发现有偏差,根据偏差计算得到的实际时钟为46Mhz左右。也就是说我用46Mhz这个晶振值计算TPM0加载值比较准确。。
。。所以有疑惑。现在贴出代码。
主函数部分
int main(void)
{
kl03_SystickInit();
kl03_led_init();
kl03_tpm0_epwm_init(SystemCoreClock-(3000000-650000),847000,50);
while(1){
}
}
时钟初始化部分
void SystemInit (void)
{
SIM->COPC = 0; /* disable watchdog */
//RCM_MR = 0xff;
MCG->C1 = 0;
MCG->C2 = 0;
MCG->SC = 0; /* HIRC mode */
SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0)|SIM_CLKDIV1_OUTDIV4(1); /* core clock 1div ,bus clock 2div */
MCG_MC = (1<<7);
while((MCG->S & MCG_S_CLKST_MASK));
SystemCoreClock = __SYSTEM_CLOCK;
}
TPM0输出部分
/**
*@brief:init the TPM0 for Edge-Aligned PWM (EPWM) Mode ,CH0 output(PTB11)
* using module clock.
*@param:tpm_clock - tpm clock cycles(MCGPCLK) hz - freq(max = tpm_clock/prescale/2 min = tpm_clock/pre/65536) cycle - 0~100
*/
void kl03_tpm0_epwm_init(uint32_t tpm_clock,uint32_t hz,uint32_t duty_cycle)
{
uint32_t modulo;
uint32_t cnv;
/* clock source config & enable clock */
SIM->SOPT2 &= ~SIM_SOPT2_TPMSRC_MASK;
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); /* select MCGPCLK as clock source for the TPM counter clock */
SIM->SCGC6 |= (1<<24); /* TPM0 clock enable */
SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK;
/* gpio config */
PORTB->PCR[11] &= 0;
PORTB->PCR[11] |= PORT_PCR_MUX(2); /* TPM0_CH0 */
/* tpm0 config */
TPM0->SC &= ~TPM_SC_CPWMS_MASK; /* LPTPM counter operates in up counting mode */
TPM0->SC &= ~TPM_SC_PS_MASK;
TPM0->SC |= TPM_SC_PS(0); /* 1 prescale */
TPM0->CONF &= ~TPM_CONF_TRGSEL_MASK;
TPM0->CONF |= TPM_CONF_TRGSEL(8); /* select TPM0 overflow trigger */
TPM0->CONF |= (1<<18); /* reload on overflow */
/* channel 0 config */
TPM0->CONTROLS[0].CnSC &= ~TPM_CnSC_MSB_MASK;
TPM0->CONTROLS[0].CnSC &= ~TPM_CnSC_MSA_MASK;
TPM0->CONTROLS[0].CnSC &= ~TPM_CnSC_ELSA_MASK;
TPM0->CONTROLS[0].CnSC &= ~TPM_CnSC_ELSB_MASK;
TPM0->CONTROLS[0].CnSC |= ((1<<5)|(1<<3));/* MSB , ELSB set ,Edge-aligned PWM High-true pulses (clear Output on match, set Output on reload) */
modulo = tpm_clock/hz-1;
cnv = modulo*duty_cycle/100;
TPM0->MOD = TPM_MOD_MOD(modulo); /* modulo value ,overflow if counter match the value */
TPM0->CONTROLS[0].CnV = TPM_CnV_VAL(cnv); /* match value */
/* enable the tpm0 */
TPM0->SC &= ~TPM_SC_CMOD_MASK;
TPM0->SC |= TPM_SC_CMOD(1); /* LPTPM counter increments on every LPTPM counter clock */
}
期待你们解决 |