DSP28035时钟设置讲解
2019-07-13 10:14发布
生成海报
TMS320x2803x系列(28035为例)系统时钟与TMS320x280x, 2801x, 2804x 系列时钟是不太一样的。
下面是TMS320x280x, 2801x, 2804x系列的时钟图如下:
TMS320x2803x系列(28035为例)的时钟与系统框图如下:
从上图可以看出SPI-A,SPI-B,SCI-A的时钟来自低速外设时钟LSPCLK; eCAN-A,LIN-A的时钟由SYSCLKOUT的二分频获得; 其它外设的时钟都是SYSCLKOUT。其中LSPCLK的大小由LOSPCP寄存器所设置,如下图:
TMS320x2803x系列(28035为例)的时钟源选择,如下图:
时钟源选择
2803x系列DSP有两个内部时钟源(INTOSC1和INTOSC2),可以不需要外部时钟。同时,也具有PLL时钟模块。一共有4种时钟源可供选择:
1) INTOSC1(10MHz)
内部时钟源1(INTOSC1),此时钟提供给看门狗块模块,内核和CPU定时器2 。
时钟频率默认为10MHz,可以通过INTOSCnTRIM寄存器修改频率。
2) INTOSC2(10MHz)
功能与INTOSC1是一样的。
3) 外部晶体振荡器
使用外部晶体振荡器给芯片提供时钟,晶振连接于X1/X2 脚。
4) 外部时钟源
如果不使用外部晶振作为时钟源,可以选择这种模式。时钟从外部时钟源的XCLKIN引脚输入生成。
注意:XCLKIN复用于GPIO19或GPIO38脚。可以通过XCLK寄存器的XCLKINSEL位选择是GPIO19还是GPIO38作为XCLKIN输入。
CLKCTL(XCLKINOFF)为0时,不使能此时钟。如果时钟源不使用或作为GPIO引脚时,用户应该在启动引导时禁用。
上面时钟图粗看起来很复杂,如果仔细分析,其实也很简单。从图的中间画一条分隔线,左边部分为4个输入时钟源,其中INTOSC1和INTOSC2是一模一样的,XTAL和XCLKIN是另外的两个时钟源; 右边部分三个时钟模块,从上到下分别是看门狗时钟WDCLK,系统时钟OSCCLK(此时钟到PLL),以及CPU定时器2时钟CPUTMR2CLK。
看完时钟框图后,下面是软件系统时钟的设置
在main函数的最初位置初始化DSP,即调用void InitialDSP(void)函数。
void InitialDSP(void)
{
DINT
IER = 0x0000
IFR = 0x0000
InitSysCtrl()
InitPieCtrl()
InitPieVectTable()
#ifdef RunInFlash
memcpy( &secureRamFuncs_runstart,
&secureRamFuncs_loadstart,
&secureRamFuncs_loadend - &secureRamFuncs_loadstart)
InitFlash()
#endif
InitAdc()
InitGpio()
InitSci()
InitSpi()
InitCpuTimers()
EALLOW
PieVectTable.TINT2 = &OSTickISR
PieVectTable.USER12 = &OSCtxSw
PieVectTable.SCIRXINTA = &InterComRxInterrupt
PieVectTable.SCITXINTA = &InterComTxInterrupt
EDIS
…
}
函数很多,这里主要讲解InitSysCtrl()。
void InitSysCtrl(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x0068;
EDIS;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
(*Device_cal)();
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0;
EDIS;
XtalOscSel ();
InitPll(12,1);
InitPeripheralClocks();
}
下面是XtalOscSel ()函数的分析。
void XtalOscSel (void)
{
EALLOW
SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 0
SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1
SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0
SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 1
SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 1
SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1
SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 1
EDIS
}
这个函数主要是对CLKCTL寄存器的配置,要对照上面的时钟框图来看才好理解,主要是对图中几个开关状态的设置。CLKCTL寄存器各个位的功能如下:
接下来初始化PLL,函数是InitPll(12,1);
void InitPll(Uint16 val, Uint16 divsel)
{
volatile Uint16 iVol
if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0) // 判断时钟是否丢失
{
EALLOW
SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1
EDIS
}
if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0) // PLLCR 被修改之前DIVSEL必须设置为 0
{
EALLOW
SysCtrlRegs.PLLSTS.bit.DIVSEL = 0
EDIS
}
if (SysCtrlRegs.PLLCR.bit.DIV != val) //修改PLLCR
{
EALLOW
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1
SysCtrlRegs.PLLCR.bit.DIV = val
EDIS
EALLOW
SysCtrlRegs.WDCR= 0x0068
EDIS
while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1) //当PLLCR被改写的时候,PLL会上锁。等待解锁完成。
{
}
EALLOW
SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0
EDIS
}
if((divsel == 1)||(divsel == 2))
{
EALLOW
SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel
EDIS
}
if(divsel == 3)
{
EALLOW
SysCtrlRegs.PLLSTS.bit.DIVSEL = 2
DELAY_US(50L)
SysCtrlRegs.PLLSTS.bit.DIVSEL = 3
EDIS
}
}
上面的代码都是按照手册里提供的程序流程图来写的,下面把PLLCR更改的程序流程图贴出来。
看看PLL是如何配置的,如下图,可以看到有三种配置模式,分别是不使能PLL,使能PLL,PLL旁路(当OSCCLK失效时,自动转到PLL模式)。
本例代码选择使能PLL工作模式(PLLSTS.PLLOFF = 0)。
下面是PLL的状态寄存器PLLSTS和控制寄存器PLLCR; 状态寄存器PLLSTS反映了PLL的工作状态,控制寄存器PLLCR用于设置PLL的倍频系数。
最后一步初始化外设时钟,函数是InitPeripheralClocks()
这个函数还是比较简单的,主要是启动各个外设模块的时钟,当然为了节省功耗,也可以关掉没用到的外设模块时钟,将对应的模块时钟使能位设置为0即可。
void InitPeripheralClocks(void)
{
EALLOW
SysCtrlRegs.LOSPCP.all = 0x0002
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1
SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1
SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1
SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1
SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1
SysCtrlRegs.PCLKCR1.bit.EPWM7ENCLK = 1
SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK = 1
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1
SysCtrlRegs.PCLKCR0.bit.LINAENCLK = 1
SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK = 1
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1
SysCtrlRegs.PCLKCR0.bit.SPIBENCLK = 1
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1
EDIS
}
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮