PLL OSC简述:
S12CPMU Block Diagram:
S12CPMU Synthesizer Register(CPMUSYNR)
PLL相关主要寄存器:
CPMUPROT:时钟配置寄存器保护
Clock Configuration Registers Protection Bit — This bit protects the clock configuration registers from
accidental overwrite (see list of affected registers above):
Writing 0x26 to the CPMUPROT register clears the PROT bit, other write accesses set the PROT bit.
0 Protection of clock configuration registers is disabled.
1 Protection of clock configuration registers is enabled.
0x26:将0x26写入CPMUPROT寄存器清除PROT位,其他写入访问设置PROT位
0:关闭保护
1:使能保护
S12CPMU PLL Control Register (CPMUPLL)
0x003A
Read:Anytime
Write: Anytime if PROT=0 (CPMUPROT register) and PLLSEL=1 (CPMUCLKS register). Else write has
no effect.
CPMUPLL[5:4] FM1, FM0
0x00:关闭FM
0x10: ±1%
0x20:±2%
0x30:±3%
FM1 | FM0 | FM Amplitude/Fvco Variation |
---|---|---|
0 | 0 | FM off |
0 | 1 | ±1% |
1 | 0 | ±2% |
1 | 1 | ±3% |
CPMUSYNR:
CPMUREFDIV:REFDIV基准分频器配置
CPMUPOSTDIV:POST分配配置
PLL设置示例:
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#define D_
#define LED PORTA
#define LED_DIR DDRA
void delay(void) {
unsigned int i;
for(i=0; i<60000; i++) {
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
_asm(nop);
}
}
void pll_init(void) {
CPMUPROT = 0x26; //保护时钟配置寄存器
CPMUCLKS_PSTP = 0; //禁用PLL
CPMUCLKS_PLLSEL = 1; //选择PLL作为系统时钟源
CPMUOSC_OSCE = 1; //外部晶振使能
while(CPMUOSC_OSCPINS_EN==0); //等待外部晶振使能
/* CPMUSYNR VCOFRQ[7:6], SYNDIV[5:0] */
/* CPMUREFDIV REFFRQ[7:6], REFDIV[3:0] */
/* CPMUPOSTDIV POSTDIV [0] = 0, FPLL = FVCO */
#if 0
//fVOC= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1)
CPMUSYNR = 0x07;
CPMUREFDIV = 0x0F; // 16M
//CPMUREFDIV = 0x07; // 32M
//CPMUREFDIV = 0x03; // 64M
#endif
#if 1
//fVOC配置 fVOC = 2*fREF*(SYNDIV +1)
//CPMUSYNR = 0x45; // 48M
//CPMUSYNR = 0x44; // 40M
//CPMUSYNR = 0x43; // 32M
//CPMUSYNR = 0x42; // 24M
CPMUSYNR = 0x01; // 16M
CPMUREFDIV = 0x81;//REFDIV基准分频器配置
#endif
CPMUPOSTDIV = 0x00; // PLL CLOCK = VCO CLOCK / (POSTDIV + 1)
_asm(nop);
_asm(nop);
CPMUPLL=0x10; //锁相环调频启用,用以减少噪音
while(CPMUFLG_LOCK == 0); //等待PLL稳定 wait for VCO to stabilize
CPMUPROT = 0x00; //关闭保护时钟
CPMUCLKS_PLLSEL = 1; /* Switch clk to use PLL */
}
void led_init(void) {
LED = 0xFF;
LED_DIR = 0xFF;
}
void main(void) {
/* put your own code here */
DisableInterrupts; // 关闭总中断
pll_init();
led_init();
EnableInterrupts; // 开启总中断
for(;;) {
delay();
LED = 0x00;
delay();
LED = 0xFF;
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}