I've tried to trim my kinetis kl26. But I cannot see any change on MCG_C3 or MCG_C4 registers. So I think i'm wrong in some step.
First I configure kinetis to be clocked with an external 8MHz cristall.
And then I proceed with the auto trim internal 4MHz oscilator.
May be auto trim doesn't work if multilink is connectet?
All code is taken from processor expert unles the last 3 lines.
This is my trim code:
SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */
/* Disable the WDOG module */
SIM_COPC = SIM_COPC_COPT(0x00);
SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x03)); /* Set the system prescalers to safe value */
/* SIM_SCGC5: PORTA=1 */
SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */
if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) {
/* PMC_REGSC: ACKISO=1 */
PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */
}
/* SIM_CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
SIM_CLKDIV1 = (SIM_CLKDIV1_OUTDIV1(0x00) | SIM_CLKDIV1_OUTDIV4(0x00)); /* Update system prescalers */
/* SIM_SOPT2: PLLFLLSEL=1 */
SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */
/* SIM_SOPT1: OSC32KSEL=3 */
SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */
/* SIM_SOPT2: TPMSRC=0 */
SIM_SOPT2 &= (uint32_t)~(uint32_t)(SIM_SOPT2_TPMSRC(0x03)); /* Set the TPM clock */
/* PORTA_PCR18: ISF=0,MUX=0 */
PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
/* PORTA_PCR19: ISF=0,MUX=0 */
PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
/* MCG_SC: FCRDIV=0 */
MCG_SC &= (uint8_t)~(uint8_t)(MCG_SC_FCRDIV(0x07));
/* Switch to FBE Mode */
/* MCG_C2: LOCRE0=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=1 */
MCG_C2 = (uint8_t)((MCG_C2 & (uint8_t)~(uint8_t)(
MCG_C2_LOCRE0_MASK |
MCG_C2_RANGE0(0x01) |
MCG_C2_HGO0_MASK |
MCG_C2_LP_MASK
)) | (uint8_t)(
MCG_C2_RANGE0(0x02) |
MCG_C2_EREFS0_MASK |
MCG_C2_IRCS_MASK
));
/* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */
OSC0_CR = OSC_CR_ERCLKEN_MASK;
/* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */
MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK);
/* MCG_C4: DMX32=0,DRST_DRS=0 */
MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03)));
/* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */
MCG_C5 = MCG_C5_PRDIV0(0x01);
/* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */
MCG_C6 = MCG_C6_VDIV0(0x00);
while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */
}
while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
}
/* Switch to PBE Mode */
/* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */
MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00));
while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */
}
while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */
}
MCG_SC = MCG_SC_ATMS_MASK; // internal 4MHz clock
MCG_SC = MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK; // Activate Trim internal 4MHz clock
while (MCG_SC & MCG_SC_ATME_MASK && !(MCG_SC & MCG_SC_ATMF_MASK)){}
已解决! 转到解答。
I've found my mistake.
I must to write to MCG_ATCVH and MCG_ATCVL before :
MCG_SC = MCG_SC_ATMS_MASK; // internal 4MHz clock
MCG_SC = MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK; // Activate Trim internal 4MHz clock
while (MCG_SC & MCG_SC_ATME_MASK && !(MCG_SC & MCG_SC_ATMF_MASK)){}
The code is this:
register unsigned short ATCV; // << Line added at the begining
.
.
.
ATCV = 21 * 8 / 4 * 128; // Line added 8 is my reference clock, 4 is the internal Clock (both in MHz) 21 and 128 are given in the manual
MCG_ATCVH = (unsigned char)((ATCV >> 8) & 0x00FF); // Line added
MCG_ATCVL = (unsigned char)(ATCV & 0x00FF); // Line added
MCG_SC = MCG_SC_ATMS_MASK; // internal 4MHz clock
MCG_SC = MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK; // Activate Trim internal 4MHz clock
while (MCG_SC & MCG_SC_ATME_MASK && !(MCG_SC & MCG_SC_ATMF_MASK)){}
I hope it will be usefull for some one.
I've found my mistake.
I must to write to MCG_ATCVH and MCG_ATCVL before :
MCG_SC = MCG_SC_ATMS_MASK; // internal 4MHz clock
MCG_SC = MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK; // Activate Trim internal 4MHz clock
while (MCG_SC & MCG_SC_ATME_MASK && !(MCG_SC & MCG_SC_ATMF_MASK)){}
The code is this:
register unsigned short ATCV; // << Line added at the begining
.
.
.
ATCV = 21 * 8 / 4 * 128; // Line added 8 is my reference clock, 4 is the internal Clock (both in MHz) 21 and 128 are given in the manual
MCG_ATCVH = (unsigned char)((ATCV >> 8) & 0x00FF); // Line added
MCG_ATCVL = (unsigned char)(ATCV & 0x00FF); // Line added
MCG_SC = MCG_SC_ATMS_MASK; // internal 4MHz clock
MCG_SC = MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK; // Activate Trim internal 4MHz clock
while (MCG_SC & MCG_SC_ATME_MASK && !(MCG_SC & MCG_SC_ATMF_MASK)){}
I hope it will be usefull for some one.