I am facing a aproblem when trying to configure the PLL clock in order to set the CPU clock to 50 Mhz
I am using an external Quartz of 8 Mhz and the following setup program:
;*******************************************************
; Set PLL Speed
Set_pll_clock:
mov.b #0FFH,prcr ; Enable write to control registers
mov.b #080H,prcr2 ; Enable write to CM3 register
mov.b #0AAH,prr ; Enable write to CCR, FMCR, PBC register
bclr pm21 ; Enable clock change
mov.b #008H,cm0 ; System clock control register 0
mov.b #020H,cm1 ; System clock control register 1
mov.b #000H,cm2 ; Oscillation stop detect register
mov.b #002H,cm3 ; Low speed mode clock control register
mov.b #000H,tcspr ; Count source prescaler register
mov.b #080H,tcspr ; Count source prescaler register
mov.b #000H,cpsrf ; Clock prescaler reset register
mov.w #0A0DH,pbc ; Peripheral bus control register
; value depends on setting of CCR register
mov.b #013H,ccr ; Clock control register
mov.b #01FH,ccr ; Clock control register
mov.b #0FFH,prcr
mov.b #004H,plc0 ; PLL control register 0
mov.b #001H,plc1 ; PLL control register 1
bclr seo ; PLL mode
bclr bcs ; Base clock source is PLL
mov.b #020H,pm3 ; Peripheral clock = PLL/6
bset pm21 ; Disable clock change
mov.b #000H,prcr
rts
but can never the desired clock frequency of 100Mhz for the PLL
Thks in advance for your help
I believe this should work:
void CLK_Init(void)
{
prr = 0xAA;
pbc = 0x0504;
ccr = 0x1C;
ccr = 0x1F;
prr = 0x00;
prcr = 0x04;
plc = 0x0104;
prcr = 0x00;
prcr = 0x01;
cm0 = 0x00;
prcr = 0x02;
pm2 = 0x40;
}
I tried your example (translated in asm) as follows:
Set_pll_clock2:
mov.b #0AAH,prr ; Write enable PBC register
mov.w #0504H,pbc ; Define Peripheral Bus Control Register
mov.b #01CH,ccr ;
mov.b #01FH,ccr
mov.b #000H,prr
mov.b #004H,prcr
mov.b #04H,plc0
mov.b #001H,plc1
mov.b #001H,prcr
mov.b #00H,cm0
mov.b #002H,prcr
mov.b #040H,pm2
mov.b #0FFH,prcr ; Write register enable
bclr seo ; Enable PLL mode
mov.l #0FFFH,R2R0
clock_wait2:
dec.l R2R0 ; wait for clock stabilisation
jne clock_wait2
As I am using a 64 pins uP I do not have an external CPU pin to monitor the frequency, so I run the following routine
bset pd10_4
freq:
bnot p10_4
jmp.b freq
Interrupt are disabled and I estimated this loop should be 4 cycles therefore with a 8Mhz quartz input frequency the cpu clock
should be 50 Mhz (PLL clock 100Mhz/2) and the software clock 12,5Mhz (80ns) but when I measured it I found a 400 ns period !
If I modify the plc0 & plc1 values the clock is effectively modified
Do you have any explanation ?
Regards
JP
Any clue so far ?
write to plc register must be 16 bit width, in C:
*(unsigned short *)&plc0 = 0x0304; // 50MHz, PLL = 100MHz Q=8MHz
Thanks for your help but unfortunately this is not the solution as plc0 & plc1 registers are both 8 bits.
I guess you write the two registers in one shot within C but this does not solve my problem
You cannot use a port toggle to measure the execution time.
- Every access to sfr has an additional wait.
- Access from CPU to port is delayed because CPU bus and peripheral bus run at ifferent speed.
- Additional delays may occure if the lable freq is placed at an odd address.
If you want to measure clock speed, measure any timer output signal. A port toggle by a timer output signal has no additional delays and is a reliable indicator for clock speed.
On RX PORT TOGGLE BY SOFTWARE IS NO RELIABLE INDICATOR FOR CLOCK SPEED.
Thanks for the update it sounds relevant, I will modify the program and let you know
I have changed the program to monitor the clock through the Timer A0 and now see a 25Mhz frequency (40 ns period measured on Oscillo)
rather then 50Mhz (PLL 100Mhz/2). here is the clock setup program:
mov.b #04H,plc0 ; Set PLL clock
mov.b #001H,plc1 ; to 100Mhz
dec.l R2R0
mov.b #060H,pm3 ; Set Peripheral Clock Source Divider to 2
and here is the Timer A0 setup program:
Init_timerA_0:
mov.w #0,ta0 ; Set timer counter to 0+1
mov.b #0,ta0mr ; Timer mode freq = f1
Do you have any explanation why the TimerA0 frequency is not 50 Mhz? (PLL/2)
Thanks for your help
May be because every timer overflow only toggles TA0 output? This adds an additional divider /2.
Sorry I did not get it, could you be more detailled in your explanation ?