关于DSP系统时钟的⼀些理解
所谓PLL电路,就是锁相环电路(Phase-Locked Loop)。电路通过⽐较复杂的原理可以将低频信号进⾏倍频与分频处理。F28335的⼯作最⾼频率为150MHz,⽽⼀般在电路设计中,⼀般采⽤的晶振频率为30MHz。之所以不直接采⽤150MHz晶振,⼀⽅⾯是价格⾼昂,另⼀⽅⾯还要对电路做EMI处理。因此,为了让DSP能够⼯作在最⾼频率,需要对晶振信号频率进⾏5倍频处理。通常采⽤的⽅案是通过PLL电路先进⾏10倍频处理,再2分频处理。
全国违章查询通常⽤PLL来产⽣倍频,倍频有2、4、6、8、10这⼏个等级,那么我们要让CPU运⾏在150MHz,通常选⽤的倍频是10,这样通过PLL 出来的VCOCLK的频率为300MHz,但是不能让300MHz直接进⼊CPU,⽽是要对其再进⾏分频,PLLSTS.DIVSEL设置为2分频,这样CLKIN就是150MHz,即系统的时钟频率为150MHz。
皇冠汽车
void InitPll(Uint16 val, Uint16 divsel)
{
// Make sure the PLL is not running in limp mode
if(SysCtrlRegs.PLLSTS.bit.MCLKSTS !=0)
{
// Missing external clock has been detected
// Replace this line with a call to an appropriate
// SystemShutdown(); function.
asm("        ESTOP0");
}
// DIVSEL MUST be 0 before PLLCR can be changed from
// 0x0000. It is set to 0 by an external reset XRSn
// This puts us in 1/4
if(SysCtrlRegs.PLLSTS.bit.DIVSEL !=0)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL =0;
EDIS;
}
// Change the PLLCR
if(SysCtrlRegs.PLLCR.bit.DIV != val)
{
// Before setting PLLCR turn off missing clock detect logic
SysCtrlRegs.PLLSTS.bit.MCLKOFF =1;
SysCtrlRegs.PLLCR.bit.DIV = val;
EDIS;
// Optional: Wait for PLL to lock.
// During this time the CPU will switch to OSCCLK/2 until
// the PLL is stable.  Once the PLL is stable the CPU will
// switch to the new PLL value.
//
// This time-to-lock is monitored by a PLL lock counter.
//
/
/ Code is not required to sit and wait for the PLL to lock.
// However, if the code does anything that is timing critical,
// and requires the correct clock be locked, then it is best to
// wait until this switching has completed.
// Wait for the PLL lock bit to be set.
// The watchdog should be disabled before this loop, or fed within
// the loop via ServiceDog().
// Uncomment to disable the watchdog
DisableDog();
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS !=1)
{
/
/ Uncomment to service the watchdog
// ServiceDog();
}
EALLOW;
SysCtrlRegs.PLLSTS.bit.MCLKOFF =0;
EDIS;
}
// If switching to 1/2
if((divsel ==1)||(divsel ==2))
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
EDIS;
}
// If switching to 1/1
// * First go to 1/2 and let the power settle
//  The time required will depend on the system, this is only an example
// * Then switch to 1/1
if(divsel ==3)
{
EALLOW;
SysCtrlRegs.PLLSTS.bit.DIVSEL =2;
DELAY_US(50L);
SysCtrlRegs.PLLSTS.bit.DIVSEL =3;
EDIS;
}
}
系统时钟是在InitSysCtrl();进⾏初始化的,进⼊这个函数,系统初始化函数默认不使⽤看门狗。
⾼速时钟和低速时钟的分频初始化设置是↓↓
即⾼速时钟默认为系统时钟的⼆分频,低速时钟默认为系统时钟的四分频。
可以发现,⾼速外设时钟频率是对系统频率进⾏2分频,即为150/2=75MHz;同理,可以求得低速外设时钟频率为150/4=37.5MHz;初始化⾼速和低速时钟之后,将外设的时钟进⾏使能,⼀般默认都是使能的。
SysCtrlRegs.HISPCP.all = 0x0001;SysCtrlRegs.LOSPCP.all = 0x0002;
void  InitPeripheralClocks (void )//初始化外设时钟
{
EALLOW ;
// HISPCP/LOSPCP prescale register settings, normally it will be set to default values
SysCtrlRegs .HISPCP .all = 0x0001;
SysCtrlRegs .LOSPCP .all = 0x0002;
// XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT
// XTIMCLK = SYSCLKOUT/2
XintfRegs .XINTCNF2.bit .XTIMCLK = 1;
// XCLKOUT = XTIMCLK/2
XintfRegs .XINTCNF2.bit .CLKMODE = 1;
// Enable XCLKOUT
XintfRegs .XINTCNF2.bit .CLKOFF = 0;
/
/ Peripheral clock enables set for the selected peripherals.
// If you are not using a peripheral leave the clock off
// to save on power.
//
// Note: not all peripherals are available on all 2833x derivates.
// Refer to the datasheet for your particular device.
//
嘉悦x8// This function is not written to be an example of efficient code.
SysCtrlRegs .PCLKCR0.bit .ADCENCLK = 1;    // ADC
// *IMPORTANT*
// The ADC_cal function, which  copies the ADC calibration values from TI reserved
/
/ OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs automatically in the
// Boot ROM. If the boot ROM code is bypassed during the debug process, the
// following function MUST be called for the ADC to function according
// to specification. The clocks to the ADC MUST be enabled before calling this
// function.
// See the device data manual and/or the ADC Reference
// Manual for more information.
ADC_cal ();
SysCtrlRegs .PCLKCR0.bit .I2CAENCLK = 1;  // I2C
SysCtrlRegs .PCLKCR0.bit .SCIAENCLK = 1;  // SCI-A
SysCtrlRegs .PCLKCR0.bit .SCIBENCLK = 1;  // SCI-B
SysCtrlRegs .PCLKCR0.bit .SCICENCLK = 1;  // SCI-C
SysCtrlRegs .PCLKCR0.bit .SPIAENCLK = 1;  // SPI-A
SysCtrlRegs .PCLKCR0.bit .MCBSPAENCLK = 1; // McBSP-A
SysCtrlRegs .PCLKCR0.bit .MCBSPBENCLK = 1; // McBSP-B
SysCtrlRegs .PCLKCR0.bit .ECANAENCLK =1;    // eCAN-A
SysCtrlRegs .PCLKCR0.bit .ECANBENCLK =1;    // eCAN-B
SysCtrlRegs .PCLKCR0.bit .TBCLKSYNC = 0;  // Disable TBCLK within the ePWM
SysCtrlRegs .PCLKCR1.bit .EPWM1ENCLK = 1;  // ePWM1
SysCtrlRegs .PCLKCR1.bit .EPWM2ENCLK = 1;  // ePWM2
SysCtrlRegs .PCLKCR1.bit .EPWM3ENCLK = 1;  // ePWM3
如果要对系统时钟频率进⾏修改,也就是InitPll函数,函数有两个参数:val和divsel,val是⽤来设置PLL的倍频系数,divsel是⽤来设置分频系数:
赛车手
所以将DSP_PLLCR传递给val,将DSP_DIVSEL传递给divsel。按住Ctrl点击DSP_PLLCR,就可以发现DSP_PLLCR的值设置的是10:  SysCtrlRegs
.PCLKCR1.bit .EPWM3ENCLK = 1;  // ePWM3
SysCtrlRegs .PCLKCR1.bit .EPWM4ENCLK
= 1;  // ePWM4
SysCtrlRegs .PCLKCR1.bit .EPWM5ENCLK = 1;  // ePWM5
SysCtrlRegs .PCLKCR1.bit .EPWM6ENCLK = 1;  // ePWM6
SysCtrlRegs .PCLKCR0.bit .TBCLKSYNC = 1;  // Enable TBCLK within the ePWM
SysCtrlRegs .PCLKCR1.bit .ECAP3ENCLK = 1;  // eCAP3
SysCtrlRegs .PCLKCR1.bit .ECAP4ENCLK = 1;  // eCAP4
SysCtrlRegs .PCLKCR1.bit .ECAP5ENCLK = 1;  // eCAP5
SysCtrlRegs .PCLKCR1.bit .ECAP6ENCLK = 1;  // eCAP6
SysCtrlRegs .PCLKCR1.bit .ECAP1ENCLK = 1;  // eCAP1
SysCtrlRegs .PCLKCR1.bit .ECAP2ENCLK = 1;  // eCAP2
SysCtrlRegs .PCLKCR1.bit .EQEP1ENCLK = 1;  // eQEP1
SysCtrlRegs .PCLKCR1.bit .EQEP2ENCLK = 1;  // eQEP2
SysCtrlRegs .PCLKCR3.bit .CPUTIMER0ENCLK = 1; // CPU Timer 0
SysCtrlRegs .PCLKCR3.bit .CPUTIMER1ENCLK = 1; // CPU Timer 1
SysCtrlRegs .PCLKCR3.bit .CPUTIMER2ENCLK = 1; // CPU Timer 2
SysCtrlRegs .PCLKCR3.bit .DMAENCLK = 1;      // DMA Clock
SysCtrlRegs .PCLKCR3.bit .XINTFENCLK = 1;    // XTIMCLK
SysCtrlRegs .PCLKCR3.bit .GPIOINENCLK = 1;    // GPIO input clock
EDIS ;
}
InitPll (DSP28_PLLCR ,DSP28_DIVSEL );
----------
void  InitPll (Uint16 val , Uint16 divsel )
#define  DSP28_PLLCR  10
/
/#define DSP28_PLLCR  9
//#define DSP28_PLLCR  8
//#define DSP28_PLLCR  7
//#define DSP28_PLLCR  6
//#define DSP28_PLLCR  5
//#define DSP28_PLLCR  4
//#define DSP28_PLLCR  3
//#define DSP28_PLLCR  2
//#define DSP28_PLLCR  1
//#define DSP28_PLLCR  0 // PLL is bypassed in this mode
按住Ctrl点击DSP_DIVSEL,就可以发现DSP_DIVSEL的值设置的是2:
即将晶振频率30MHz通过PLL倍频10倍后,再分频2倍,即系统时钟频率默认是150MHz。
所以使⽤Ti默认提供的系统初始化函数InitSysCtrl(),调⽤的c⽂件为DSP2833x_SysCtrl.c,初始化之后的频率是经过PLL10倍频后再分频2倍,得到系统时钟频率为150MHz。
修改系统时钟睿翼图片
如果要修改系统时钟,让其不再是150MHz,那么我们就需要修改DSP_PLLCR和DSP_DIVSEL的值,⽐如设置
DSP_PLLCR=3,DSP_DIVSEL=2,即:
即晶振频率为30MHz,经过3倍频,2分频,系统时钟频率此时为45MHz。⼩技巧:将代码注释快捷键:Ctrl+/外设时钟控制寄存器有三个PCLKCR0、PCLKCR1、PCLKCR3,三个寄存器控制的外设的时钟不⼀样,注意区分://#define DSP28_DIVSEL  0  // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL  1 // Disable /4 for SYSCKOUT
#define  DSP28_DIVSEL  2 // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL  3 // Enable /1 for SYSCLKOUT
//#define DSP28_PLLCR  10//#define DSP28_PLLCR  9
东莞汽车网
//#define DSP28_PLLCR  8//#define DSP28_PLLCR  7
//#define DSP28_PLLCR  6
//#define DSP28_PLLCR  5
//#define DSP28_PLLCR  4
#define  DSP28_PLLCR  3
//#define DSP28_PLLCR  2
//#define DSP28_PLLCR  1
//#define DSP28_DIVSEL  0  // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL  1 // Disable /4 for SYSCKOUT
#define  DSP28_DIVSEL  2 // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL  3 // Enable /1 for SYSCLKOUT