I am a college student and I met a problem when i was learning mc9s12p128.
The command window always warn me that there was a illegal_bp problem when i was debuging use TBDML,but when i try in full chip simulation mode ,there was nothing wrong!
i donnot know the reason,anyone knows?
#include "MC9S12P128.h"
void SetBusClock_16M() {
CPMUCLKS_PLLSEL = 1; //f(bus)=f(osc)/2 ;fosc = 4m
CPMUSYNR =0X43; //01000011
//fvco = 2*4*(1+1)/1 = 16m
//VCOFRQ[7:6] SYNDIV[5:0]
//fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1) =2*4M*(3+1)=32M
//fPLL= fVCO/(2 × POSTDIV)
//fBUS= fPLL/2
//VCOCLK Frequency Ranges VCOFRQ[7:6]
// 32MHz <= fVCO <= 48MHz 00
// 48MHz < fVCO <= 64MHz 01
// Reserved 10
// Reserved 11
CPMUREFDIV = 0X40;//0100 0000
//REFFRQ[7:6] REFDIV[5:0]
//fREF = fOSC/(REFDIV + 1)
//REFCLK Frequency Ranges REFFRQ[7:6]
// 1MHz <= fREF <= 2MHz 00
// 2MHz < fREF <= 6MHz 01
// 6MHz < fREF <= 12MHz 10
// fREF > 12MHz 11
// pllclock=2*fosc*(1+SYNDIV)/(1+REFDIV)=16MHz;
CPMUPOSTDIV = 0X00; //fPLL = fVCO/(1+POSTDIV)
CPMUOSC_OSCE = 1; //choose osc as bus clock;
while(!(CPMUFLG_UPOSC==1)) {
_asm(nop);
_asm(nop);
}
while(!(CPMUFLG_LOCK==1)) ; //WHEN PLL IS STEADY
//CPMUCLKS_PLLSEL = 1; //
}
Solved! Go to Solution.
Hi 战强 秦,
while(CPMUCLKS_PLLSEL) // PLLSEL=0 check
{
CPMUCLKS_PLLSEL = 0;
}
This is important mainly for PBE mode (when PLLSEL = 0), but it is good habit to use in all modes.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi 战强 秦,
In fact, illegal_bp problem means that debugger gets lost. Typical case is unexpected interrupt or reset of MCU.
Please check whether you didn’t enable any clock interrupt in CPMUINT register and if yes, please check whether you have correctly defined appropriate interrupt routine.
For example:
//==============================================================================
//PLL_LOCK_ISR
//==============================================================================
#pragma CODE_SEG NON_BANKED
interrupt 28 void PLL_LOCK_ISR(void)
{
lock = CPMUFLG_LOCK;
if(CPMUFLG_LOCK)
{
//..your code //LOCK
}
else
{
//..your code //UNLOCK
}
CPMUFLG = 0x10; //clear LOCKIF flag
}
#pragma CODE_SEG DEFAULT
About your routine)
I suppose that you want set CPMU module into PEE mode with 4MHz external crystal and 16MHz bus clock. I am right?
You should set CPMUSYNR to 0x03 instead 0x43. VCOCLK is 32MHz.
Since external oscillator cannot be validated without locked PLL (LOCK=1), it has no sense to wait for UPOSC bit and after that wait for LOCK bit. So, line “while(!(CPMUFLG_LOCK==1)) ; //WHEN PLL IS STEADY” could be removed.
After writing CPMUCLKS register, it is recommended to read back CPMUCLKS register to make sure that write of PLLSEL, RTIOSCSEL and COPOSCSELwas successful. For example:
while(CPMUCLKS_PLLSEL) // PLLSEL=0 check
{
CPMUCLKS_PLLSEL = 0;
}
Since BDM communication depends on bus clock, I would like to recommend run code trough PLL setting function. Transient states during stepping over code could cause unexpected communication problems.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hey ,thank you very much for you help!Before i saw your message,i read the datasheet over and over again,then i found that when i added "CPMUPROT_PROT =0; CPMUCLKS_PLLSEL = 1;"before i set the register,the problem disappeared!!i do`nt know why because according to the datasheet,it is the default value! This is my code blow,but i found i can not set register "CPMUOSC"!when i wrote to it,the value did not change when i was debugging by TBDML,so the osc won`t work.Maybe i missed something importent...unhappy...
#include "PEE_BusClock.h"
void Set_PEE(byte _synr, byte _refdiv, byte _postdiv) {
CPMUPROT_PROT =0;
CPMUCLKS_PLLSEL = 1;
while(!CPMUCLKS_PLLSEL);
CPMUSYNR = _synr;
CPMUPOSTDIV = _postdiv;
CPMUREFDIV = _refdiv;
while (!CPMUFLG_LOCK);
CPMUOSC= CPMUOSC_OSCE_MASK+CPMUOSC_OSCBW_MASK+CPMUOSC_OSCFILT1_MASK;//enable external osc OSCE
while(!CPMUFLG_UPOSC) { //if osc up?
// you can check for timeout here with error message report
}
//while(!CPMUFLG_LOCK){ //if PLL LOCKED?
// you can check for timeout here with error message report
//}
//SET CLOCK
CPMUCLKS_PLLSEL = 1; //Bus = F(PLL)/2
//CPMUCLKS_COPOSCSEL = 1; //COP IS clocked from osc
while (CPMUCLKS != 0B10000000) {
asm nop;
}
}
//OSC = 4M
void SetBusClock16M_OSC4M() {
ECLKCTL_NECLK = 0; // enable ECLK output
Set_PEE(0X03,0X40,0X00);
}
/*
void SetBusClock24M_OSC4M() {
ECLKCTL_NECLK = 0; // enable ECLK output
Set_PEE(0X01,0X80,0X70);
}
void SetBusClock25M_OSC4M() {
ECLKCTL_NECLK = 0; // enable ECLK output
Set_PEE(0X58,0X03,0X00);
}
//OSC = 8M
void SetBusClock16M_OSC8M(){
ECLKCTL_NECLK = 0; // enable ECLK output
Set_PEE(0X01,0X80,0X00);
}
void SetBusClock24M_OSC8M(){
ECLKCTL_NECLK = 0; // enable ECLK output
Set_PEE(0X02,0X80,0X00);
}void SetBusClock25M_OSC8M(){
ECLKCTL_NECLK = 0; // enable ECLK output
Set_PEE(0X58,0X07,0X00);
}
*/
Hi 战强 秦,
while(CPMUCLKS_PLLSEL) // PLLSEL=0 check
{
CPMUCLKS_PLLSEL = 0;
}
This is important mainly for PBE mode (when PLLSEL = 0), but it is good habit to use in all modes.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
thank you very much !